diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index bdd815e6d..33edefb82 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -3,9 +3,6 @@ ## Work on `dev` Any merge request should be created from and issued to the `dev` branch. -## dist files -Keep it simple, don't commit any files in the `dist` directory, I build these files only before a release. - ## Unit tests There are very few unit tests because it's somehow difficult to setup, but please don't break them and create new ones if you can. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c0fd4b9f9..ab14ad110 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,5 +2,4 @@ - [ ] I read the [guidelines for contributing](https://github.com/mistic100/Photo-Sphere-Viewer/blob/master/.github/CONTRIBUTING.md) - [ ] I created my branch from `dev` and I am issuing the PR to `dev` -- [ ] I **didn't** commited files in the `dist` directory - [ ] Unit tests are OK diff --git a/.travis.yml b/.travis.yml index 65d40319c..cb9c05917 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ node_js: - "5" before_install: - gem install sass - - gem install scss_lint + - gem install scss_lint -v 0.49.0 - npm install -g grunt-cli - npm install -g bower before_script: diff --git a/Gruntfile.js b/Gruntfile.js index e29cbe7e2..50e30aff2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -183,6 +183,7 @@ module.exports = function(grunt) { connect: { dev: { options: { + host: '0.0.0.0', port: 9000 } } diff --git a/README.md b/README.md index fda0e12d0..f4fdfd419 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Photo Sphere Viewer [![Bower version](https://img.shields.io/bower/v/Photo-Sphere-Viewer.svg?style=flat-square)](http://photo-sphere-viewer.js.org) +[![NPM version](https://img.shields.io/npm/v/photo-sphere-viewer.svg?style=flat-square)](https://www.npmjs.com/package/photo-sphere-viewer) [![Build Status](https://img.shields.io/travis/mistic100/Photo-Sphere-Viewer/master.svg?style=flat-square)](https://travis-ci.org/mistic100/Photo-Sphere-Viewer) Photo Sphere Viewer is a JavaScript library that allows you to display 360×180 degrees panoramas on any web page. Panoramas must use the equirectangular projection and can be taken with the Google Camera, the Ricoh Theta or any 360° camera. @@ -32,8 +33,7 @@ Install Node and Bower dependencies `npm install & bower install` then run `grun ### Other commands * `grunt test` to run jshint/jscs/scsslint. - * `grunt watch` to automatically build the library when modifying the source files. - * `grunt server` to open the example page with automatic build and livereload. + * `grunt serve` to open the example page with automatic build and livereload. ## License This library is available under the MIT license. diff --git a/bower.json b/bower.json index 44ac29cfb..c5d574308 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,5 @@ { "name": "Photo-Sphere-Viewer", - "version": "3.2.1", "authors": [ { "name": "Jérémy Heleine", @@ -25,6 +24,9 @@ "uevent": "~1.0.0", "doT": "master" }, + "devDependencies": { + "three.js-examples": "master" + }, "keywords": [ "photosphere", "panorama", @@ -43,8 +45,5 @@ "tests", "package.json", "Gruntfile.js" - ], - "devDependencies": { - "threejs-examples": "master" - } + ] } diff --git a/dist/photo-sphere-viewer.css b/dist/photo-sphere-viewer.css index 7756bb15d..9b3a023fd 100644 --- a/dist/photo-sphere-viewer.css +++ b/dist/photo-sphere-viewer.css @@ -1,5 +1,5 @@ /*! - * Photo Sphere Viewer 3.2.1 + * Photo Sphere Viewer 3.2.2 * Copyright (c) 2014-2015 Jérémy Heleine * Copyright (c) 2015-2016 Damien "Mistic" Sorel * Licensed under MIT (http://opensource.org/licenses/MIT) diff --git a/dist/photo-sphere-viewer.js b/dist/photo-sphere-viewer.js index 8a3659dd5..a63bc109e 100644 --- a/dist/photo-sphere-viewer.js +++ b/dist/photo-sphere-viewer.js @@ -1,5 +1,5 @@ /*! - * Photo Sphere Viewer 3.2.1 + * Photo Sphere Viewer 3.2.2 * Copyright (c) 2014-2015 Jérémy Heleine * Copyright (c) 2015-2016 Damien "Mistic" Sorel * Licensed under MIT (http://opensource.org/licenses/MIT) @@ -45,7 +45,7 @@ function PhotoSphereViewer(options) { } if ((!PhotoSphereViewer.SYSTEM.isWebGLSupported || !this.config.webgl) && !PSVUtils.checkTHREE('CanvasRenderer', 'Projector')) { - throw new PSVError('Missing Three.js components: CanvasRenderer, Projector. Get them from threejs-examples package.'); + throw new PSVError('Missing Three.js components: CanvasRenderer, Projector. Get them from three.js-examples package.'); } if (this.config.transition && this.config.transition.blur) { @@ -54,7 +54,7 @@ function PhotoSphereViewer(options) { console.warn('PhotoSphereViewer: Using canvas rendering, blur transition disabled.'); } else if (!PSVUtils.checkTHREE('EffectComposer', 'RenderPass', 'ShaderPass', 'MaskPass', 'CopyShader')) { - throw new PSVError('Missing Three.js components: EffectComposer, RenderPass, ShaderPass, MaskPass, CopyShader. Get them from threejs-examples package.'); + throw new PSVError('Missing Three.js components: EffectComposer, RenderPass, ShaderPass, MaskPass, CopyShader. Get them from three.js-examples package.'); } } @@ -87,6 +87,11 @@ function PhotoSphereViewer(options) { console.warn('PhotoSphereViewer: max_fov cannot be lower than min_fov.'); } + if (this.config.cache_texture && (!PSVUtils.isInteger(this.config.cache_texture) || this.config.cache_texture < 0)) { + this.config.cache_texture = PhotoSphereViewer.DEFAULTS.cache_texture; + console.warn('PhotoSphreViewer: invalid valud for cache_texture'); + } + // normalize config this.config.min_fov = PSVUtils.stayBetween(this.config.min_fov, 1, 179); this.config.max_fov = PSVUtils.stayBetween(this.config.max_fov, 1, 179); @@ -165,7 +170,9 @@ function PhotoSphereViewer(options) { orientation_reqid: null, // animationRequest id of the device orientation autorotate_reqid: null, // animationRequest id of the automatic rotation animation_promise: null, // promise of the current animation (either go to position or image transition) + loading_promise: null, // promise of the setPanorama method start_timeout: null, // timeout id of the automatic rotation delay + cache: [], size: { // size of the container width: 0, height: 0 @@ -260,10 +267,11 @@ uEvent.mixin(PhotoSphereViewer); /** * Loads the XMP data with AJAX + * @param {string} panorama * @returns {promise} * @private */ -PhotoSphereViewer.prototype._loadXMP = function() { +PhotoSphereViewer.prototype._loadXMP = function(panorama) { if (!this.config.usexmpdata) { return D.resolved(null); } @@ -334,7 +342,7 @@ PhotoSphereViewer.prototype._loadXMP = function() { throw new PSVError('Cannot load image'); }; - xhr.open('GET', this.config.panorama, true); + xhr.open('GET', panorama, true); xhr.send(null); return defer.promise; @@ -342,13 +350,24 @@ PhotoSphereViewer.prototype._loadXMP = function() { /** * Loads the sphere texture + * @param {string} panorama * @returns {promise} * @private */ -PhotoSphereViewer.prototype._loadTexture = function() { +PhotoSphereViewer.prototype._loadTexture = function(panorama) { var self = this; - return this._loadXMP().then(function(pano_data) { + if (this.config.cache_texture) { + var cache = this.getPanoramaCache(panorama); + + if (cache) { + this.prop.pano_data = cache.pano_data; + + return D.resolved(cache.image); + } + } + + return this._loadXMP(panorama).then(function(pano_data) { var defer = D(); var loader = new THREE.ImageLoader(); var progress = pano_data ? 100 : 0; @@ -359,6 +378,7 @@ PhotoSphereViewer.prototype._loadTexture = function() { if (self.loader) { self.loader.setProgress(100); } + self.trigger('panorama-load-progress', panorama, 100); // Config XMP data if (!pano_data && self.config.pano_data) { @@ -405,6 +425,14 @@ PhotoSphereViewer.prototype._loadTexture = function() { texture.minFilter = THREE.LinearFilter; texture.generateMipmaps = false; + if (self.config.cache_texture) { + self._putPanoramaCache({ + panorama: panorama, + image: texture, + pano_data: pano_data + }); + } + defer.resolve(texture); }; @@ -414,6 +442,7 @@ PhotoSphereViewer.prototype._loadTexture = function() { if (new_progress > progress) { progress = new_progress; self.loader.setProgress(progress); + self.trigger('panorama-load-progress', panorama, progress); } } }; @@ -423,7 +452,7 @@ PhotoSphereViewer.prototype._loadTexture = function() { throw new PSVError('Cannot load image'); }; - loader.load(self.config.panorama, onload, onprogress, onerror); + loader.load(panorama, onload, onprogress, onerror); return defer.promise; }); @@ -433,7 +462,6 @@ PhotoSphereViewer.prototype._loadTexture = function() { * Applies the texture to the scene * Creates the scene if needed * @param {THREE.Texture} texture - The sphere texture - * @returns {promise} * @private */ PhotoSphereViewer.prototype._setTexture = function(texture) { @@ -450,8 +478,6 @@ PhotoSphereViewer.prototype._setTexture = function(texture) { this.trigger('panorama-loaded'); this.render(); - - return D.resolved(); }; /** @@ -481,6 +507,7 @@ PhotoSphereViewer.prototype._createScene = function() { var material = new THREE.MeshBasicMaterial(); material.side = THREE.DoubleSide; + material.overdraw = PhotoSphereViewer.SYSTEM.isWebGLSupported && this.config.webgl ? 0 : 0.5; this.mesh = new THREE.Mesh(geometry, material); this.mesh.scale.x = -1; @@ -535,10 +562,11 @@ PhotoSphereViewer.prototype._transition = function(texture, position) { var self = this; // create a new sphere with the new texture - var geometry = new THREE.SphereGeometry(150, 32, 32, -PSVUtils.HalfPI); + var geometry = new THREE.SphereGeometry(PhotoSphereViewer.SPHERE_RADIUS * 1.5, this.config.sphere_segments, this.config.sphere_segments, -PSVUtils.HalfPI); var material = new THREE.MeshBasicMaterial(); material.side = THREE.DoubleSide; + material.overdraw = PhotoSphereViewer.SYSTEM.isWebGLSupported && this.config.webgl ? 0 : 0.5; material.map = texture; material.transparent = true; material.opacity = 0; @@ -580,15 +608,15 @@ PhotoSphereViewer.prototype._transition = function(texture, position) { // 1st half animation return PSVUtils.animation({ - properties: { - density: { start: 0.0, end: 1.5 }, - opacity: { start: 0.0, end: 0.5 }, - zoom: { start: original_zoom_lvl, end: 100 } - }, - duration: self.config.transition.duration / (self.config.transition.blur ? 4 / 3 : 2), - easing: self.config.transition.blur ? 'outCubic' : 'linear', - onTick: onTick - }) + properties: { + density: { start: 0.0, end: 1.5 }, + opacity: { start: 0.0, end: 0.5 }, + zoom: { start: original_zoom_lvl, end: 100 } + }, + duration: self.config.transition.duration / (self.config.transition.blur ? 4 / 3 : 2), + easing: self.config.transition.blur ? 'outCubic' : 'linear', + onTick: onTick + }) .then(function() { // 2nd half animation return PSVUtils.animation({ @@ -649,15 +677,15 @@ PhotoSphereViewer.prototype._reverseAutorotate = function() { this.config.longitude_range = null; PSVUtils.animation({ - properties: { - speed: { start: this.config.anim_speed, end: 0 } - }, - duration: 300, - easing: 'inSine', - onTick: function(properties) { - self.config.anim_speed = properties.speed; - } - }) + properties: { + speed: { start: this.config.anim_speed, end: 0 } + }, + duration: 300, + easing: 'inSine', + onTick: function(properties) { + self.config.anim_speed = properties.speed; + } + }) .then(function() { return PSVUtils.animation({ properties: { @@ -676,6 +704,33 @@ PhotoSphereViewer.prototype._reverseAutorotate = function() { }); }; +/** + * Adds a panorama to the cache + * @param {object} cache + * - panorama + * - image + * - pano_data + * @private + */ +PhotoSphereViewer.prototype._putPanoramaCache = function(cache) { + if (!this.config.cache_texture) { + throw new PSVError('Cannot add panorama to cache, cache_texture is disabled'); + } + + var existingCache = this.getPanoramaCache(cache.panorama); + + if (existingCache) { + existingCache.image = cache.image; + existingCache.pano_data = cache.pano_data; + } + else { + this.prop.cache = this.prop.cache.slice(0, this.config.cache_texture - 1); // remove most ancient elements + this.prop.cache.unshift(cache); + } + + this.trigger('panorama-cached', cache.panorama); +}; + /** * Number of pixels bellow which a mouse move will be considered as a click @@ -794,6 +849,7 @@ PhotoSphereViewer.DEFAULTS = { loading_img: null, loading_txt: 'Loading...', size: null, + cache_texture: 5, templates: {}, markers: [] }; @@ -1014,6 +1070,11 @@ PhotoSphereViewer.prototype._onTouchEnd = function(evt) { * @private */ PhotoSphereViewer.prototype._stopMove = function(evt) { + if (this.isGyroscopeEnabled()) { + this._click(evt); + return; + } + if (this.prop.moving) { // move threshold to trigger a click if (Math.abs(evt.clientX - this.prop.start_mouse_x) < PhotoSphereViewer.MOVE_THRESHOLD && Math.abs(evt.clientY - this.prop.start_mouse_y) < PhotoSphereViewer.MOVE_THRESHOLD) { @@ -1301,7 +1362,7 @@ PhotoSphereViewer.prototype.isGyroscopeEnabled = function() { * @returns {boolean} */ PhotoSphereViewer.prototype.isFullscreenEnabled = function() { - return PSVUtils.isFullscreenEnabled(this.container); + return PSVUtils.isFullscreenEnabled(this.parent); }; /** @@ -1412,6 +1473,7 @@ PhotoSphereViewer.prototype.destroy = function() { delete this.raycaster; delete this.passes; delete this.config; + this.prop.cache.length = 0; }; /** @@ -1424,6 +1486,10 @@ PhotoSphereViewer.prototype.destroy = function() { * @returns {promise} */ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { + if (this.prop.loading_promise !== null) { + throw new PSVError('Loading already in progress'); + } + if (typeof position == 'boolean') { transition = position; position = undefined; @@ -1442,20 +1508,21 @@ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { if (!transition || !this.config.transition || !this.scene) { this.loader = new PSVLoader(this); - return this._loadTexture() - .then(this._setTexture.bind(this)) - .then(function() { + this.prop.loading_promise = this._loadTexture(this.config.panorama) + .ensure(function() { if (self.loader) { self.loader.destroy(); self.loader = null; } + self.prop.loading_promise = null; + }) + .then(function(texture) { + self._setTexture(texture); + if (position) { self.rotate(position); } - else { - self.render(); - } }) .rethrow(); } @@ -1464,7 +1531,7 @@ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { this.loader = new PSVLoader(this); } - return this._loadTexture() + this.prop.loading_promise = this._loadTexture(this.config.panorama) .then(function(texture) { if (self.loader) { self.loader.destroy(); @@ -1473,8 +1540,18 @@ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { return self._transition(texture, position); }) + .ensure(function() { + if (self.loader) { + self.loader.destroy(); + self.loader = null; + } + + self.prop.loading_promise = null; + }) .rethrow(); } + + return this.prop.loading_promise; }; /** @@ -1656,6 +1733,8 @@ PhotoSphereViewer.prototype.animate = function(position, duration) { easing: 'inOutSine', onTick: this.rotate.bind(this) }); + + return this.prop.animation_promise; }; /** @@ -1708,7 +1787,7 @@ PhotoSphereViewer.prototype.zoomOut = function() { */ PhotoSphereViewer.prototype.toggleFullscreen = function() { if (!this.isFullscreenEnabled()) { - PSVUtils.requestFullscreen(this.container); + PSVUtils.requestFullscreen(this.parent); } else { PSVUtils.exitFullscreen(); @@ -1729,6 +1808,56 @@ PhotoSphereViewer.prototype.stopKeyboardControl = function() { window.removeEventListener('keydown', this); }; +/** + * Preload a panorama file without displaying it + * @param {string} panorama + * @returns {promise} + */ +PhotoSphereViewer.prototype.preloadPanorama = function(panorama) { + if (!this.config.cache_texture) { + throw new PSVError('Cannot preload panorama, cache_texture is disabled'); + } + + return this._loadTexture(panorama); +}; + +/** + * Removes a specific panorama from the cache or clear the entire cache + * @param {string} [panorama] + */ +PhotoSphereViewer.prototype.clearPanoramaCache = function(panorama) { + if (!this.config.cache_texture) { + throw new PSVError('Cannot clear cache, cache_texture is disabled'); + } + + if (panorama) { + for (var i = 0, l = this.prop.cache.length; i < l; i++) { + if (this.prop.cache[i].panorama === panorama) { + this.prop.cache.splice(i, 1); + break; + } + } + } + else { + this.prop.cache.length = 0; + } +}; + +/** + * Retrieve teh cache for a panorama + * @param {string} panorama + * @returns {object} + */ +PhotoSphereViewer.prototype.getPanoramaCache = function(panorama) { + if (!this.config.cache_texture) { + throw new PSVError('Cannot query cache, cache_texture is disabled'); + } + + return this.prop.cache.filter(function(cache) { + return cache.panorama === panorama; + }).shift(); +}; + /** * Init the global SYSTEM var with information generic support information @@ -1744,7 +1873,12 @@ PhotoSphereViewer.loadSystem = function() { S.fullscreenEvent = PSVUtils.fullscreenEvent(); S.deviceOrientationSupported = D(); - window.addEventListener('deviceorientation', PhotoSphereViewer.deviceOrientationListener, false); + if ('DeviceOrientationEvent' in window) { + window.addEventListener('deviceorientation', PhotoSphereViewer.deviceOrientationListener, false); + } + else { + S.deviceOrientationSupported.reject(); + } }; /** @@ -1934,8 +2068,8 @@ PhotoSphereViewer.prototype.applyRanges = function(position) { range = PSVUtils.clone(this.config.latitude_range); offset = this.prop.vFov / 180 * Math.PI / 2; - range[0] = PSVUtils.parseAngle(range[0] + offset, -Math.PI); - range[1] = PSVUtils.parseAngle(range[1] - offset, -Math.PI); + range[0] = PSVUtils.parseAngle(Math.min(range[0] + offset, range[1]), -Math.PI); + range[1] = PSVUtils.parseAngle(Math.max(range[1] - offset, range[0]), -Math.PI); if (position.latitude < range[0]) { position.latitude = range[0]; @@ -3787,7 +3921,8 @@ PSVNavBarButton.prototype.setIcon = function(icon, container) { } if (icon) { container.innerHTML = PhotoSphereViewer.ICONS[icon]; - container.querySelector('svg').classList.add('psv-button-svg'); + // classList not supported on IE11, className is read-only !!!! + container.querySelector('svg').setAttribute('class', 'psv-button-svg'); } else { container.innerHTML = ''; @@ -4144,7 +4279,7 @@ PSVNavBarGyroscopeButton.prototype._onAvailabilityChange = function(available) { this.show(); } else { - throw new PSVError('Missing Three.js components: DeviceOrientationControls. Get them from threejs-examples package.'); + throw new PSVError('Missing Three.js components: DeviceOrientationControls. Get them from three.js-examples package.'); } } }; @@ -4784,6 +4919,15 @@ PSVUtils.stayBetween = function(x, min, max) { return Math.max(min, Math.min(max, x)); }; +/** + * Checks if a value is an integer + * @param {*} value + * @returns {boolean} + */ +PSVUtils.isInteger = Number.isInteger || function(value) { + return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; + }; + /** * Returns the value of a given attribute in the panorama metadata * @param {string} data diff --git a/dist/photo-sphere-viewer.min.css b/dist/photo-sphere-viewer.min.css index 5751fc3d7..ea24a83df 100644 --- a/dist/photo-sphere-viewer.min.css +++ b/dist/photo-sphere-viewer.min.css @@ -1,5 +1,5 @@ /*! - * Photo Sphere Viewer 3.2.1 + * Photo Sphere Viewer 3.2.2 * Copyright (c) 2014-2015 Jérémy Heleine * Copyright (c) 2015-2016 Damien "Mistic" Sorel * Licensed under MIT (http://opensource.org/licenses/MIT) diff --git a/dist/photo-sphere-viewer.min.js b/dist/photo-sphere-viewer.min.js index 0e8408822..de765a0e9 100644 --- a/dist/photo-sphere-viewer.min.js +++ b/dist/photo-sphere-viewer.min.js @@ -1,10 +1,10 @@ /*! - * Photo Sphere Viewer 3.2.1 + * Photo Sphere Viewer 3.2.2 * Copyright (c) 2014-2015 Jérémy Heleine * Copyright (c) 2015-2016 Damien "Mistic" Sorel * Licensed under MIT (http://opensource.org/licenses/MIT) */ -!function(a,b){"function"==typeof define&&define.amd?define(["three","D.js","uevent","doT"],b):"object"==typeof module&&module.exports?module.exports=b(require("three"),require("d.js"),require("uevent"),require("dot")):a.PhotoSphereViewer=b(a.THREE,a.D,a.uEvent,a.doT)}(this,function(a,b,c,d){"use strict";function e(a){if(!(this instanceof e))return new e(a);if(e.SYSTEM.loaded||e.loadSystem(),this.config=x.clone(e.DEFAULTS),x.deepmerge(this.config,a),!a.container)throw new w("No value given for container.");if(!e.SYSTEM.isCanvasSupported)throw new w("Canvas is not supported.");if(!(e.SYSTEM.isWebGLSupported&&this.config.webgl||x.checkTHREE("CanvasRenderer","Projector")))throw new w("Missing Three.js components: CanvasRenderer, Projector. Get them from threejs-examples package.");if(this.config.transition&&this.config.transition.blur)if(e.SYSTEM.isWebGLSupported&&this.config.webgl){if(!x.checkTHREE("EffectComposer","RenderPass","ShaderPass","MaskPass","CopyShader"))throw new w("Missing Three.js components: EffectComposer, RenderPass, ShaderPass, MaskPass, CopyShader. Get them from threejs-examples package.")}else this.config.transition.blur=!1,console.warn("PhotoSphereViewer: Using canvas rendering, blur transition disabled.");this.config.longitude_range&&2!==this.config.longitude_range.length&&(this.config.longitude_range=null,console.warn("PhotoSphereViewer: longitude_range must have exactly two elements.")),this.config.latitude_range?2!==this.config.latitude_range.length?(this.config.latitude_range=null,console.warn("PhotoSphereViewer: latitude_range must have exactly two elements.")):this.config.latitude_range[0]>this.config.latitude_range[1]&&(this.config.latitude_range=[this.config.latitude_range[1],this.config.latitude_range[0]],console.warn("PhotoSphereViewer: latitude_range values must be ordered.")):void 0===this.config.tilt_up_max&&void 0===this.config.tilt_down_max||(this.config.latitude_range=[void 0!==this.config.tilt_down_max?this.config.tilt_down_max-Math.PI/4:-x.HalfPI,void 0!==this.config.tilt_up_max?this.config.tilt_up_max+Math.PI/4:x.HalfPI],console.warn("PhotoSphereViewer: tilt_up_max and tilt_down_max are deprecated, use latitude_range instead.")),this.config.max_fov"),h=b.substring(f,g);if(f===-1||g===-1||h.indexOf("GPano:")===-1)a.resolve(null);else{var i={full_width:parseInt(x.getXMPValue(h,"FullPanoWidthPixels")),full_height:parseInt(x.getXMPValue(h,"FullPanoHeightPixels")),cropped_width:parseInt(x.getXMPValue(h,"CroppedAreaImageWidthPixels")),cropped_height:parseInt(x.getXMPValue(h,"CroppedAreaImageHeightPixels")),cropped_x:parseInt(x.getXMPValue(h,"CroppedAreaLeftPixels")),cropped_y:parseInt(x.getXMPValue(h,"CroppedAreaTopPixels"))};i.full_width&&i.full_height&&i.cropped_width&&i.cropped_height?a.resolve(i):(console.warn("PhotoSphereViewer: invalid XMP data"),a.resolve(null))}}else 3===c.readyState&&d.loader&&d.loader.setProgress(e+=10)},c.onprogress=function(a){if(a.lengthComputable&&d.loader){var b=parseInt(a.loaded/a.total*100);b>e&&(e=b,d.loader.setProgress(e))}},c.onerror=function(){throw d.container.textContent="Cannot load image",new w("Cannot load image")},c.open("GET",this.config.panorama,!0),c.send(null),a.promise},e.prototype._loadTexture=function(){var c=this;return this._loadXMP().then(function(d){var f=b(),g=new a.ImageLoader,h=d?100:0;g.setCrossOrigin("anonymous");var i=function(b){c.loader&&c.loader.setProgress(100),!d&&c.config.pano_data&&(d=x.clone(c.config.pano_data)),d||(d={full_width:b.width,full_height:b.height,cropped_width:b.width,cropped_height:b.height,cropped_x:0,cropped_y:0}),c.prop.pano_data=d;var g=Math.min(d.full_width,e.SYSTEM.maxTextureWidth)/d.full_width,h=x.clone(d);h.full_width*=g,h.full_height*=g,h.cropped_width*=g,h.cropped_height*=g,h.cropped_x*=g,h.cropped_y*=g,b.width=h.cropped_width,b.height=h.cropped_height;var i=document.createElement("canvas");i.width=h.full_width,i.height=h.full_height;var j=i.getContext("2d");j.drawImage(b,h.cropped_x,h.cropped_y,h.cropped_width,h.cropped_height);var k=new a.Texture(i);k.needsUpdate=!0,k.minFilter=a.LinearFilter,k.generateMipmaps=!1,f.resolve(k)},j=function(a){if(a.lengthComputable&&c.loader){var b=parseInt(a.loaded/a.total*100);b>h&&(h=b,c.loader.setProgress(h))}},k=function(){throw c.container.textContent="Cannot load image",new w("Cannot load image")};return g.load(c.config.panorama,i,j,k),f.promise})},e.prototype._setTexture=function(a){return this.scene||this._createScene(),this.mesh.material.map&&this.mesh.material.map.dispose(),this.mesh.material.map=a,this.trigger("panorama-loaded"),this.render(),b.resolved()},e.prototype._createScene=function(){this.raycaster=new a.Raycaster,this.renderer=e.SYSTEM.isWebGLSupported&&this.config.webgl?new a.WebGLRenderer:new a.CanvasRenderer,this.renderer.setSize(this.prop.size.width,this.prop.size.height),this.renderer.setPixelRatio(e.SYSTEM.pixelRatio),this.camera=new a.PerspectiveCamera(this.config.default_fov,this.prop.size.width/this.prop.size.height,1,2*e.SPHERE_RADIUS),this.camera.position.set(0,0,0),this.config.gyroscope&&x.checkTHREE("DeviceOrientationControls")&&(this.doControls=new a.DeviceOrientationControls(this.camera)),this.scene=new a.Scene,this.scene.add(this.camera);var b=new a.SphereGeometry(e.SPHERE_RADIUS,this.config.sphere_segments,this.config.sphere_segments,(-x.HalfPI)),c=new a.MeshBasicMaterial;c.side=a.DoubleSide,this.mesh=new a.Mesh(b,c),this.mesh.scale.x=-1,this.scene.add(this.mesh),this.canvas_container=document.createElement("div"),this.canvas_container.className="psv-canvas-container",this.renderer.domElement.className="psv-canvas",this.container.appendChild(this.canvas_container),this.canvas_container.appendChild(this.renderer.domElement),this.config.time_anim!==!1&&(this.prop.start_timeout=window.setTimeout(this.startAutorotate.bind(this),this.config.time_anim)),this.config.transition&&this.config.transition.blur&&(this.composer=new a.EffectComposer(this.renderer),this.passes.render=new a.RenderPass(this.scene,this.camera),this.passes.copy=new a.ShaderPass(a.CopyShader),this.passes.copy.renderToScreen=!0,this.passes.blur=new a.ShaderPass(a.GodraysShader),this.passes.blur.enabled=!1,this.passes.blur.renderToScreen=!0,this.passes.blur.uniforms.fDensity.value=0,this.passes.blur.uniforms.fWeight.value=.5,this.passes.blur.uniforms.fDecay.value=.5,this.passes.blur.uniforms.fExposure.value=1,this.composer.addPass(this.passes.render),this.composer.addPass(this.passes.copy),this.composer.addPass(this.passes.blur))},e.prototype._transition=function(b,c){var d=this,e=new a.SphereGeometry(150,32,32,(-x.HalfPI)),f=new a.MeshBasicMaterial;f.side=a.DoubleSide,f.map=b,f.transparent=!0,f.opacity=0;var g=new a.Mesh(e,f);if(g.scale.x=-1,c){g.rotateY(c.longitude-this.prop.longitude);var h=new a.Vector3(0,1,0).cross(this.camera.getWorldDirection()).normalize(),i=(new a.Quaternion).setFromAxisAngle(h,c.latitude-this.prop.latitude);g.quaternion.multiplyQuaternions(i,g.quaternion)}this.scene.add(g),this.render();var j=this.prop.zoom_lvl;this.config.transition.blur&&(this.passes.copy.enabled=!1,this.passes.blur.enabled=!0);var k=function(a){f.opacity=a.opacity,d.config.transition.blur&&(d.passes.blur.uniforms.fDensity.value=a.density,d.zoom(a.zoom,!1)),d.render()};return x.animation({properties:{density:{start:0,end:1.5},opacity:{start:0,end:.5},zoom:{start:j,end:100}},duration:d.config.transition.duration/(d.config.transition.blur?4/3:2),easing:d.config.transition.blur?"outCubic":"linear",onTick:k}).then(function(){return x.animation({properties:{density:{start:1.5,end:0},opacity:{start:.5,end:1},zoom:{start:100,end:j}},duration:d.config.transition.duration/(d.config.transition.blur?4:2),easing:d.config.transition.blur?"inCubic":"linear",onTick:k})}).then(function(){d.config.transition.blur&&(d.passes.copy.enabled=!0,d.passes.blur.enabled=!1,d.zoom(j,!1)),d.mesh.material.map.dispose(),d.mesh.material.map=b,d.scene.remove(g),g.geometry.dispose(),g.geometry=null,g.material.dispose(),g.material=null,c?((d.config.latitude_range||d.config.longitude_range)&&(d.config.longitude_range=d.config.latitude_range=null,console.warn("PhotoSphereViewer: trying to perform transition with longitude_range and/or latitude_range, ranges cleared.")),d.rotate(c)):d.render()})},e.prototype._reverseAutorotate=function(){var a=this,b=-this.config.anim_speed,c=this.config.longitude_range;this.config.longitude_range=null,x.animation({properties:{speed:{start:this.config.anim_speed,end:0}},duration:300,easing:"inSine",onTick:function(b){a.config.anim_speed=b.speed}}).then(function(){return x.animation({properties:{speed:{start:0,end:b}},duration:300,easing:"outSine",onTick:function(b){a.config.anim_speed=b.speed}})}).then(function(){a.config.longitude_range=c,a.config.anim_speed=b})},e.MOVE_THRESHOLD=4,e.INERTIA_WINDOW=300,e.SPHERE_RADIUS=100,e.KEYMAP={33:"PageUp",34:"PageDown",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",107:"+",109:"-"},e.ICONS={},e.SYSTEM={loaded:!1,pixelRatio:1,isWebGLSupported:!1,isCanvasSupported:!1,deviceOrientationSupported:null,maxTextureWidth:0,mouseWheelEvent:null,fullscreenEvent:null},e.DEFAULTS={panorama:null,container:null,caption:null,autoload:!0,usexmpdata:!0,pano_data:null,webgl:!0,sphere_segments:64,min_fov:30,max_fov:90,default_fov:null,default_long:0,default_lat:0,longitude_range:null,latitude_range:null,move_speed:1,time_anim:2e3,anim_speed:"2rpm",anim_lat:null,fisheye:!1,navbar:["autorotate","zoom","download","markers","caption","gyroscope","fullscreen"],tooltip:{offset:5,arrow_size:7,delay:100},lang:{autorotate:"Automatic rotation",zoom:"Zoom",zoomOut:"Zoom out",zoomIn:"Zoom in",download:"Download",fullscreen:"Fullscreen",markers:"Markers",gyroscope:"Gyroscope"},mousewheel:!0,mousemove:!0,keyboard:!0,gyroscope:!1,move_inertia:!0,click_event_on_marker:!1,transition:{duration:1500,loader:!0,blur:!1},loading_img:null,loading_txt:"Loading...",size:null,templates:{},markers:[]},e.TEMPLATES={markersList:'

{{= it.config.lang.markers }}

'},e.prototype._bindEvents=function(){window.addEventListener("resize",this),document.addEventListener(e.SYSTEM.fullscreenEvent,this),this.config.mousemove&&(this.hud.container.style.cursor="move",this.hud.container.addEventListener("mousedown",this),this.hud.container.addEventListener("touchstart",this),window.addEventListener("mouseup",this),window.addEventListener("touchend",this),this.hud.container.addEventListener("mousemove",this),this.hud.container.addEventListener("touchmove",this)),this.config.mousewheel&&this.hud.container.addEventListener(e.SYSTEM.mouseWheelEvent,this),this.on("_side-reached",function(a){this.isAutorotateEnabled()&&("left"!==a&&"right"!==a||this._reverseAutorotate())})},e.prototype.handleEvent=function(a){switch(a.type){case"resize":x.throttle(this._onResize(),50);break;case"keydown":this._onKeyDown(a);break;case"mousedown":this._onMouseDown(a);break;case"touchstart":this._onTouchStart(a);break;case"mouseup":this._onMouseUp(a);break;case"touchend":this._onTouchEnd(a);break;case"mousemove":this._onMouseMove(a);break;case"touchmove":this._onTouchMove(a);break;case e.SYSTEM.fullscreenEvent:this._fullscreenToggled();break;case e.SYSTEM.mouseWheelEvent:this._onMouseWheel(a)}},e.prototype._onResize=function(){this.container.clientWidth==this.prop.size.width&&this.container.clientHeight==this.prop.size.height||(this.prop.size.width=parseInt(this.container.clientWidth),this.prop.size.height=parseInt(this.container.clientHeight),this.prop.aspect=this.prop.size.width/this.prop.size.height,this.renderer&&(this.renderer.setSize(this.prop.size.width,this.prop.size.height),this.composer&&this.composer.reset(new a.WebGLRenderTarget(this.prop.size.width,this.prop.size.height)),this.render()),this.trigger("size-updated",this.getSize()))},e.prototype._onKeyDown=function(a){var b=0,c=0,d=0,f=a.key||e.KEYMAP[a.keyCode||a.which];switch(f){case"ArrowUp":c=.01;break;case"ArrowDown":c=-.01;break;case"ArrowRight":b=.01;break;case"ArrowLeft":b=-.01;break;case"PageUp":case"+":d=1;break;case"PageDown":case"-":d=-1}0!==d?this.zoom(this.prop.zoom_lvl+d):0===c&&0===b||this.rotate({longitude:this.prop.longitude+b*this.prop.move_speed*this.prop.hFov,latitude:this.prop.latitude+c*this.prop.move_speed*this.prop.vFov})},e.prototype._onMouseDown=function(a){this._startMove(a)},e.prototype._onTouchStart=function(a){1===a.touches.length?this._startMove(a.touches[0]):2===a.touches.length&&this._startZoom(a)},e.prototype._startMove=function(a){this.isGyroscopeEnabled()||(this.stopAll(),this.prop.mouse_x=this.prop.start_mouse_x=parseInt(a.clientX),this.prop.mouse_y=this.prop.start_mouse_y=parseInt(a.clientY),this.prop.moving=!0,this.prop.zooming=!1,this.prop.mouse_history.length=0,this._logMouseMove(a))},e.prototype._startZoom=function(a){var b=[{x:parseInt(a.touches[0].clientX),y:parseInt(a.touches[0].clientY)},{x:parseInt(a.touches[1].clientX),y:parseInt(a.touches[1].clientY)}];this.prop.pinch_dist=Math.sqrt(Math.pow(b[0].x-b[1].x,2)+Math.pow(b[0].y-b[1].y,2)),this.prop.moving=!1,this.prop.zooming=!0},e.prototype._onMouseUp=function(a){this._stopMove(a)},e.prototype._onTouchEnd=function(a){this._stopMove(a.changedTouches[0])},e.prototype._stopMove=function(a){this.prop.moving&&(Math.abs(a.clientX-this.prop.start_mouse_x)e.INERTIA_WINDOW/10?(this.prop.mouse_history.splice(0,d),d=0,c=this.prop.mouse_history[0][d]):(d++,c=this.prop.mouse_history[0][d])},e.prototype.load=function(){if(!this.config.panorama)throw new w("No value given for panorama.");this.setPanorama(this.config.panorama,!1)},e.prototype.getPosition=function(){return{longitude:this.prop.longitude,latitude:this.prop.latitude}},e.prototype.getZoomLevel=function(){return this.prop.zoom_lvl},e.prototype.getSize=function(){return{width:this.prop.size.width,height:this.prop.size.height}},e.prototype.isAutorotateEnabled=function(){return!!this.prop.autorotate_reqid},e.prototype.isGyroscopeEnabled=function(){return!!this.prop.orientation_reqid},e.prototype.isFullscreenEnabled=function(){return x.isFullscreenEnabled(this.container)},e.prototype.render=function(a){a!==!1&&(this.prop.direction=this.sphericalCoordsToVector3(this.prop.longitude,this.prop.latitude),this.config.fisheye&&(this.prop.direction.multiplyScalar(this.config.fisheye/2),this.camera.position.copy(this.prop.direction).negate()),this.camera.lookAt(this.prop.direction)),this.camera.aspect=this.prop.aspect,this.camera.fov=this.prop.vFov,this.camera.updateProjectionMatrix(),this.composer?this.composer.render():this.renderer.render(this.scene,this.camera),this.trigger("render")},e.prototype.destroy=function(){this.stopAll(),this.stopKeyboardControl(),this.isFullscreenEnabled()&&x.exitFullscreen(),window.removeEventListener("resize",this),document.removeEventListener(e.SYSTEM.fullscreenEvent,this),this.config.mousemove&&(this.hud.container.removeEventListener("mousedown",this),this.hud.container.removeEventListener("touchstart",this),window.removeEventListener("mouseup",this),window.removeEventListener("touchend",this),this.hud.container.removeEventListener("mousemove",this),this.hud.container.removeEventListener("touchmove",this)),this.config.mousewheel&&this.hud.container.removeEventListener(e.SYSTEM.mouseWheelEvent,this),this.tooltip&&this.tooltip.destroy(),this.hud&&this.hud.destroy(),this.loader&&this.loader.destroy(),this.navbar&&this.navbar.destroy(),this.panel&&this.panel.destroy(),this.doControls&&this.doControls.disconnect(),this.scene&&(this.scene.remove(this.camera),this.scene.remove(this.mesh)),this.mesh&&(this.mesh.geometry.dispose(),this.mesh.geometry=null,this.mesh.material.map.dispose(),this.mesh.material.map=null,this.mesh.material.dispose(),this.mesh.material=null),this.canvas_container&&this.container.removeChild(this.canvas_container),this.parent.removeChild(this.container),delete this.parent.photoSphereViewer,delete this.parent,delete this.container,delete this.loader,delete this.navbar,delete this.hud,delete this.panel,delete this.tooltip,delete this.canvas_container,delete this.renderer,delete this.composer,delete this.scene,delete this.camera,delete this.mesh,delete this.doControls,delete this.raycaster,delete this.passes,delete this.config},e.prototype.setPanorama=function(a,b,c){"boolean"==typeof b&&(c=b,b=void 0),b&&(this.cleanPosition(b),this.stopAll()),this.config.panorama=a;var d=this;return c&&this.config.transition&&this.scene?(this.config.transition.loader&&(this.loader=new h(this)),this._loadTexture().then(function(a){return d.loader&&(d.loader.destroy(),d.loader=null),d._transition(a,b)}).rethrow()):(this.loader=new h(this),this._loadTexture().then(this._setTexture.bind(this)).then(function(){d.loader&&(d.loader.destroy(),d.loader=null),b?d.rotate(b):d.render()}).rethrow())},e.prototype.stopAll=function(){this.stopAutorotate(),this.stopAnimation(),this.stopGyroscopeControl()},e.prototype.startAutorotate=function(){this.stopAll();var a=this,b=null,c=null;!function d(e){e&&(c=null===b?0:e-b,b=e,a.rotate({longitude:a.prop.longitude+a.config.anim_speed*c/1e3,latitude:a.prop.latitude-(a.prop.latitude-a.config.anim_lat)/200})),a.prop.autorotate_reqid=window.requestAnimationFrame(d)}(null),this.trigger("autorotate",!0)},e.prototype.stopAutorotate=function(){this.prop.start_timeout&&(window.clearTimeout(this.prop.start_timeout),this.prop.start_timeout=null),this.prop.autorotate_reqid&&(window.cancelAnimationFrame(this.prop.autorotate_reqid),this.prop.autorotate_reqid=null,this.trigger("autorotate",!1))},e.prototype.toggleAutorotate=function(){this.isAutorotateEnabled()?this.stopAutorotate():this.startAutorotate()},e.prototype.startGyroscopeControl=function(){if(!this.config.gyroscope)return void console.warn("PhotoSphereViewer: gyroscope disabled");this.stopAll();var a=this;!function b(){a.doControls.update(),a.prop.direction=a.camera.getWorldDirection();var c=a.vector3ToSphericalCoords(a.prop.direction);a.prop.longitude=c.longitude,a.prop.latitude=c.latitude,a.render(!1),a.prop.orientation_reqid=window.requestAnimationFrame(b)}(),this.trigger("gyroscope-updated",!0)},e.prototype.stopGyroscopeControl=function(){this.prop.orientation_reqid&&(window.cancelAnimationFrame(this.prop.orientation_reqid),this.prop.orientation_reqid=null,this.trigger("gyroscope-updated",!1),this.render())},e.prototype.toggleGyroscopeControl=function(){this.isGyroscopeEnabled()?this.stopGyroscopeControl():this.startGyroscopeControl()},e.prototype.rotate=function(a,b){this.cleanPosition(a),this.applyRanges(a),this.prop.longitude=a.longitude,this.prop.latitude=a.latitude,b!==!1&&this.renderer&&(this.render(),this.trigger("position-updated",this.getPosition()))},e.prototype.animate=function(a,b){if(this.stopAll(),!b)return void this.rotate(a);if(this.cleanPosition(a),this.applyRanges(a),!b&&"number"!=typeof b){b=b?x.parseSpeed(b):this.config.anim_speed;var c=Math.acos(Math.cos(this.prop.latitude)*Math.cos(a.latitude)*Math.cos(this.prop.longitude-a.longitude)+Math.sin(this.prop.latitude)*Math.sin(a.latitude));b=c/b*1e3}var d=this.getShortestArc(this.prop.longitude,a.longitude);this.prop.animation_promise=x.animation({properties:{longitude:{start:this.prop.longitude,end:this.prop.longitude+d},latitude:{start:this.prop.latitude,end:a.latitude}},duration:b,easing:"inOutSine",onTick:this.rotate.bind(this)})},e.prototype.stopAnimation=function(){this.prop.animation_promise&&(this.prop.animation_promise.cancel(),this.prop.animation_promise=null)},e.prototype.zoom=function(a,b){this.prop.zoom_lvl=x.stayBetween(Math.round(a),0,100),this.prop.vFov=this.config.max_fov+this.prop.zoom_lvl/100*(this.config.min_fov-this.config.max_fov),this.prop.hFov=2*Math.atan(Math.tan(this.prop.vFov*Math.PI/180/2)*this.prop.aspect)*180/Math.PI,b!==!1&&this.renderer&&(this.render(),this.trigger("zoom-updated",this.getZoomLevel()))},e.prototype.zoomIn=function(){this.prop.zoom_lvl<100&&this.zoom(this.prop.zoom_lvl+1)},e.prototype.zoomOut=function(){this.prop.zoom_lvl>0&&this.zoom(this.prop.zoom_lvl-1)},e.prototype.toggleFullscreen=function(){this.isFullscreenEnabled()?x.exitFullscreen():x.requestFullscreen(this.container)},e.prototype.startKeyboardControl=function(){window.addEventListener("keydown",this)},e.prototype.stopKeyboardControl=function(){window.removeEventListener("keydown",this)},e.loadSystem=function(){var a=e.SYSTEM;a.loaded=!0,a.pixelRatio=window.devicePixelRatio||1,a.isWebGLSupported=x.isWebGLSupported(),a.isCanvasSupported=x.isCanvasSupported(),a.maxTextureWidth=a.isWebGLSupported?x.getMaxTextureWidth():4096,a.mouseWheelEvent=x.mouseWheelEvent(),a.fullscreenEvent=x.fullscreenEvent(),a.deviceOrientationSupported=b(),window.addEventListener("deviceorientation",e.deviceOrientationListener,!1)},e.deviceOrientationListener=function(a){null!==a.alpha?e.SYSTEM.deviceOrientationSupported.resolve():e.SYSTEM.deviceOrientationSupported.reject(),window.removeEventListener("deviceorientation",e.deviceOrientationListener)},e.prototype._setViewerSize=function(a){["width","height"].forEach(function(b){a[b]&&(/^[0-9.]+$/.test(a[b])&&(a[b]+="px"),this.parent.style[b]=a[b])},this)},e.prototype.textureCoordsToSphericalCoords=function(a,b){var c=(a+this.prop.pano_data.cropped_x)/this.prop.pano_data.full_width*x.TwoPI,d=(b+this.prop.pano_data.cropped_y)/this.prop.pano_data.full_height*Math.PI;return{longitude:c>=Math.PI?c-Math.PI:c+Math.PI,latitude:x.HalfPI-d}},e.prototype.sphericalCoordsToTextureCoords=function(a,b){var c=a/x.TwoPI*this.prop.pano_data.full_width,d=b/Math.PI*this.prop.pano_data.full_height;return{x:parseInt(ab[1]?a.longitude>b[1]&&a.longitudeb[0]/2+b[1]/2?(a.longitude=b[0],this.trigger("_side-reached","left")):(a.longitude=b[1],this.trigger("_side-reached","right"))):a.longitudeb[1]&&(a.longitude=b[1],this.trigger("_side-reached","right"))),this.config.latitude_range&&(b=x.clone(this.config.latitude_range),c=this.prop.vFov/180*Math.PI/2,b[0]=x.parseAngle(b[0]+c,-Math.PI),b[1]=x.parseAngle(b[1]-c,-Math.PI),a.latitudeb[1]&&(a.latitude=b[1],this.trigger("_side-reached","top")))},e.prototype.getShortestArc=function(a,b){var c=[0,x.TwoPI,-x.TwoPI];return c.reduce(function(c,d){return d=b-a+d,Math.abs(d)2){c.position2D=this._getPolygonDimensions(c,e);var f="";e.forEach(function(a){f+=a.left+","+a.top+" "}),c.$el.setAttributeNS(null,"points",f)}}else if(d){var g=this._getMarkerPosition(c);d=this._isMarkerVisible(c,g),d&&(c.position2D=g,c.$el.style.transform="translate3D("+g.left+"px, "+g.top+"px, 0px)"+(!c.lockRotation&&a?" rotateZ("+a+"deg)":""))}x.toggleClass(c.$el,"psv-marker--visible",d)}},g.prototype._isMarkerVisible=function(a,b){return a.position3D.dot(this.psv.prop.direction)>0&&b.left+a.width>=0&&b.left-a.width<=this.psv.prop.size.width&&b.top+a.height>=0&&b.top-a.height<=this.psv.prop.size.height},g.prototype._getMarkerPosition=function(a){if(a.dynamicSize){a.$el.classList.add("psv-marker--transparent");var b=a.$el.getBoundingClientRect();a.$el.classList.remove("psv-marker--transparent"),a.width=b.right-b.left,a.height=b.bottom-b.top}var c=this.psv.vector3ToViewerCoords(a.position3D);return c.top-=a.height*a.anchor.top,c.left-=a.width*a.anchor.left,c},g.prototype._getPolygonPositions=function(a){var b=a.positions3D.length,c=a.positions3D.map(function(a){return{vector:a,visible:a.dot(this.psv.prop.direction)>0}},this),d=[];return c.forEach(function(a,e){if(!a.visible){var f=[0===e?c[b-1]:c[e-1],e===b-1?c[0]:c[e+1]];f.forEach(function(b){b.visible&&d.push({visible:b,invisible:a,index:e})})}}),d.reverse().forEach(function(a){c.splice(a.index,0,{vector:this._getPolygonIntermediaryPoint(a.visible.vector,a.invisible.vector),visible:!0})},this),c.filter(function(a){return a.visible}).map(function(a){return this.psv.vector3ToViewerCoords(a.vector)},this)},g.prototype._getPolygonIntermediaryPoint=function(b,c){var d=this.psv.prop.direction.clone().normalize(),f=(new a.Vector3).crossVectors(b,c).normalize(),g=(new a.Vector3).crossVectors(f,b).normalize(),h=(new a.Vector3).addVectors(b.clone().multiplyScalar(-d.dot(g)),g.clone().multiplyScalar(d.dot(b))).normalize(),i=(new a.Vector3).crossVectors(h,d);return h.applyAxisAngle(i,.01).multiplyScalar(e.SPHERE_RADIUS)},g.prototype._getPolygonDimensions=function(a,b){var c=+(1/0),d=+(1/0),e=-(1/0),f=-(1/0);return b.forEach(function(a){c=Math.min(c,a.left),d=Math.min(d,a.top),e=Math.max(e,a.left),f=Math.max(f,a.top)}),a.width=e-c,a.height=f-d,{top:d,left:c}},g.prototype._onMouseEnter=function(a){var b;a.target&&(b=a.target.psvMarker)&&b.tooltip&&!b.isPolygon()&&(this.hoveringMarker=b,this.psv.tooltip.showTooltip({content:b.tooltip.content,position:b.tooltip.position,top:b.position2D.top,left:b.position2D.left,marker:b}))},g.prototype._onMouseLeave=function(a){var b;if(a.target&&(b=a.target.psvMarker)){if(b.isPolygon()&&a.relatedTarget&&x.hasParent(a.relatedTarget,this.psv.tooltip.container))return;this.hoveringMarker=null,this.psv.tooltip.hideTooltip()}},g.prototype._onMouseMove=function(a){if(!this.psv.prop.moving){var b;if(a.target&&(b=a.target.psvMarker)&&b.tooltip&&b.isPolygon()||a.target&&x.hasParent(a.target,this.psv.tooltip.container)&&(b=this.hoveringMarker)){this.hoveringMarker=b;var c=this.psv.container.getBoundingClientRect();this.psv.tooltip.showTooltip({content:b.tooltip.content,position:b.tooltip.position,top:a.clientY-c.top-this.psv.config.tooltip.arrow_size/2,left:a.clientX-c.left-this.psv.config.tooltip.arrow_size,marker:{width:2*this.psv.config.tooltip.arrow_size,height:2*this.psv.config.tooltip.arrow_size}})}else this.hoveringMarker&&this.hoveringMarker.isPolygon()&&this.psv.tooltip.hideTooltip()}},g.prototype._onClick=function(a,b){var c;a.target&&(c=x.getClosest(a.target,".psv-marker"))&&c.psvMarker?(this.currentMarker=c.psvMarker,this.psv.trigger("select-marker",c.psvMarker),this.psv.config.click_event_on_marker?a.marker=c.psvMarker:b.stopPropagation()):this.currentMarker&&(this.psv.trigger("unselect-marker",this.currentMarker),this.currentMarker=null),c&&c.psvMarker&&c.psvMarker.content?this.psv.panel.showPanel(c.psvMarker.content):this.psv.panel.prop.opened&&(b.stopPropagation(),this.psv.panel.hidePanel())},h.prototype=Object.create(f.prototype),h.prototype.constructor=h,h.className="psv-loader-container",h.prototype.create=function(){f.prototype.create.call(this),this.loader=document.createElement("div"),this.loader.className="psv-loader",this.container.appendChild(this.loader),this.canvas=document.createElement("canvas"),this.canvas.className="psv-loader-canvas",this.canvas.width=this.loader.clientWidth,this.canvas.height=this.loader.clientWidth,this.loader.appendChild(this.canvas),this.tickness=(this.loader.offsetWidth-this.loader.clientWidth)/2;var a;if(this.psv.config.loading_img?(a=document.createElement("img"),a.className="psv-loader-image",a.src=this.psv.config.loading_img):this.psv.config.loading_txt&&(a=document.createElement("div"),a.className="psv-loader-text",a.innerHTML=this.psv.config.loading_txt),a){var b=Math.round(Math.sqrt(2*Math.pow(this.canvas.width/2-this.tickness/2,2)));a.style.maxWidth=b+"px",a.style.maxHeight=b+"px",this.loader.appendChild(a)}},h.prototype.destroy=function(){delete this.loader,delete this.canvas,f.prototype.destroy.call(this)},h.prototype.setProgress=function(a){var b=this.canvas.getContext("2d");b.clearRect(0,0,this.canvas.width,this.canvas.height),b.lineWidth=this.tickness,b.strokeStyle=x.getStyle(this.loader,"color"),b.beginPath(),b.arc(this.canvas.width/2,this.canvas.height/2,this.canvas.width/2-this.tickness/2,-Math.PI/2,a/100*2*Math.PI-Math.PI/2),b.stroke()},i.getType=function(a,b){var c=["image","html","polygon_px","polygon_rad","rect","circle","ellipse","path"],d=[];if(c.forEach(function(b){a[b]&&d.push(b)}),0===d.length&&!b)throw new w("missing marker content, either "+c.join(", "));if(d.length>1)throw new w("multiple marker content, either "+c.join(", "));return d[0]},i.prototype.isNormal=function(){return"image"==this.type||"html"==this.type},i.prototype.isPolygon=function(){return"polygon_px"==this.type||"polygon_rad"==this.type},i.prototype.isSvg=function(){return"rect"==this.type||"circle"==this.type||"ellipse"==this.type||"path"==this.type},i.prototype.update=function(a){if(a&&a!==this){var b=i.getType(a,!0);if(void 0!==b&&b!==this.type)throw new w("cannot change marker type");x.deepmerge(this,a)}this.isNormal()?this.$el.setAttribute("class","psv-marker psv-marker--normal"):this.$el.setAttribute("class","psv-marker psv-marker--svg"),this.className&&x.addClasses(this.$el,this.className),this.tooltip&&(this.$el.classList.add("has-tooltip"),"string"==typeof this.tooltip&&(this.tooltip={content:this.tooltip})),this.style&&x.deepmerge(this.$el.style,this.style),this.anchor=x.parsePosition(this.anchor),this.$el.style.transformOrigin=100*this.anchor.left+"% "+100*this.anchor.top+"%",this.isNormal()?this._updateNormal():this.isPolygon()?this._updatePolygon():this._updateSvg()},i.prototype._updateNormal=function(){this.width&&this.height?(this.$el.style.width=this.width+"px",this.$el.style.height=this.height+"px",this.dynamicSize=!1):this.dynamicSize=!0,this.image?this.$el.style.backgroundImage="url("+this.image+")":this.$el.innerHTML=this.html,this.psv.cleanPosition(this),this.position3D=this.psv.sphericalCoordsToVector3(this.longitude,this.latitude)},i.prototype._updateSvg=function(){switch(this.dynamicSize=!0,this.type){case"rect":"number"==typeof this._def?this._def={x:0,y:0,width:this._def,height:this._def}:Array.isArray(this._def)?this._def={x:0,y:0,width:this._def[0],height:this._def[1]}:this._def.x=this._def.y=0;break;case"circle":"number"==typeof this._def?this._def={cx:this._def,cy:this._def,r:this._def}:Array.isArray(this._def)?this._def={cx:this._def[0],cy:this._def[0],r:this._def[0]}:this._def.cx=this._def.cy=this._def.r;break;case"ellipse":"number"==typeof this._def?this._def={cx:this._def,cy:this._def,rx:this._def,ry:this._def}:Array.isArray(this._def)?this._def={cx:this._def[0],cy:this._def[1],rx:this._def[0],ry:this._def[1]}:(this._def.cx=this._def.rx,this._def.cy=this._def.ry);break;case"path":"string"==typeof this._def&&(this._def={d:this._def})}Object.getOwnPropertyNames(this._def).forEach(function(a){this.$el.setAttributeNS(null,a,this._def[a])},this),this.svgStyle?Object.getOwnPropertyNames(this.svgStyle).forEach(function(a){this.$el.setAttributeNS(null,a,this.svgStyle[a])},this):this.$el.setAttributeNS(null,"fill","rgba(0,0,0,0.5)"),this.psv.cleanPosition(this),this.position3D=this.psv.sphericalCoordsToVector3(this.longitude,this.latitude)},i.prototype._updatePolygon=function(){this.dynamicSize=!0,this.svgStyle?Object.getOwnPropertyNames(this.svgStyle).forEach(function(a){this.$el.setAttributeNS(null,a,this.svgStyle[a])},this):this.$el.setAttributeNS(null,"fill","rgba(0,0,0,0.5)"),[this.polygon_rad,this.polygon_px].forEach(function(a){if(a&&"object"!=typeof a[0])for(var b=0;b
',this.content=this.container.querySelector(".psv-panel-content");var a=this.container.querySelector(".psv-panel-close-button");a.addEventListener("click",this.hidePanel.bind(this)),this.psv.config.mousewheel&&this.container.addEventListener(e.SYSTEM.mouseWheelEvent,function(a){a.stopPropagation()});var b=this.container.querySelector(".psv-panel-resizer");b.addEventListener("mousedown",this),b.addEventListener("touchstart",this),this.psv.container.addEventListener("mouseup",this),this.psv.container.addEventListener("touchend",this),this.psv.container.addEventListener("mousemove",this),this.psv.container.addEventListener("touchmove",this)},m.prototype.destroy=function(){this.psv.container.removeEventListener("mousemove",this),this.psv.container.removeEventListener("touchmove",this),this.psv.container.removeEventListener("mouseup",this),this.psv.container.removeEventListener("touchend",this),delete this.prop,delete this.content,f.prototype.destroy.call(this)},m.prototype.handleEvent=function(a){switch(a.type){case"mousedown":this._onMouseDown(a);break;case"touchstart":this._onTouchStart(a);break;case"mousemove":this._onMouseMove(a);break;case"touchmove":this._onTouchMove(a);break;case"mouseup":this._onMouseUp(a);break;case"touchend":this._onMouseUp(a)}},m.prototype.showPanel=function(a,b){this.content.innerHTML=a,this.content.scrollTop=0,this.container.classList.add("psv-panel--open"),x.toggleClass(this.content,"psv-panel-content--no-margin",!!b),this.prop.opened=!0,this.psv.trigger("open-panel")},m.prototype.hidePanel=function(){this.content.innerHTML=null,this.prop.opened=!1,this.container.classList.remove("psv-panel--open"),this.psv.trigger("close-panel")},m.prototype._onMouseDown=function(a){a.stopPropagation(),this._startResize(a)},m.prototype._onTouchStart=function(a){a.stopPropagation(),this._startResize(a.changedTouches[0])},m.prototype._startResize=function(a){this.prop.mouse_x=parseInt(a.clientX),this.prop.mouse_y=parseInt(a.clientY),this.prop.mousedown=!0,this.content.classList.add("psv-panel-content--no-interaction")},m.prototype._onMouseUp=function(a){this.prop.mousedown&&(a.stopPropagation(),this.prop.mousedown=!1,this.content.classList.remove("psv-panel-content--no-interaction"))},m.prototype._onMouseMove=function(a){this.prop.mousedown&&(a.stopPropagation(),this._resize(a))},m.prototype._onTouchMove=function(a){this.prop.mousedown&&(a.stopPropagation(),this._resize(a.touches[0]))},m.prototype._resize=function(a){var b=parseInt(a.clientX),c=parseInt(a.clientY);this.container.style.width=this.container.offsetWidth-(b-this.prop.mouse_x)+"px",this.prop.mouse_x=b,this.prop.mouse_y=c},n.prototype=Object.create(f.prototype),n.prototype.constructor=n,n.className="psv-tooltip",n.publicMethods=["showTooltip","hideTooltip","isTooltipVisible"],n.leftMap={0:"left",.5:"center",1:"right"},n.topMap={0:"top",.5:"center",1:"bottom"},n.prototype.create=function(){f.prototype.create.call(this),this.container.innerHTML='
',this.container.style.top="-1000px",this.container.style.left="-1000px",this.content=this.container.querySelector(".psv-tooltip-content"),this.arrow=this.container.querySelector(".psv-tooltip-arrow"),this.psv.on("render",this)},n.prototype.destroy=function(){this.psv.off("render",this),delete this.config,f.prototype.destroy.call(this)},n.prototype.handleEvent=function(a){switch(a.type){case"render":this.hideTooltip()}},n.prototype.isTooltipVisible=function(){return this.container.classList.contains("psv-tooltip--visible")},n.prototype.showTooltip=function(a){this.timeout&&(window.clearTimeout(this.timeout),this.timeout=null);var b=this.isTooltipVisible(),c=this.container,d=this.content,e=this.arrow;if(a.position||(a.position=["top","center"]),a.marker||(a.marker={width:0,height:0}),"string"==typeof a.position){var f=x.parsePosition(a.position);if(!(f.left in n.leftMap&&f.top in n.topMap))throw new w('unable to parse tooltip position "'+tooltip.position+'"');a.position=[n.topMap[f.top],n.leftMap[f.left]]}if("center"==a.position[0]&&"center"==a.position[1])throw new w('unable to parse tooltip position "center center"');if(b)for(var g=c.classList.length-1;g>=0;g--){var h=c.classList.item(g);"psv-tooltip"!=h&&"visible"!=h&&c.classList.remove(h)}else c.className="psv-tooltip";a.className&&x.addClasses(c,a.className),d.innerHTML=a.content,c.style.top="0px",c.style.left="0px";var i=c.getBoundingClientRect(),j={posClass:a.position.slice(),width:i.right-i.left,height:i.bottom-i.top,top:0,left:0,arrow_top:0,arrow_left:0};this._computeTooltipPosition(j,a);var k=!1;if(j.topthis.psv.prop.size.height-this.config.offset&&(j.posClass[0]="top",k=!0),j.leftthis.psv.prop.size.width-this.config.offset&&(j.posClass[1]="left",k=!0),k&&this._computeTooltipPosition(j,a),c.style.top=j.top+"px",c.style.left=j.left+"px",e.style.top=j.arrow_top+"px",e.style.left=j.arrow_left+"px",c.classList.add("psv-tooltip--"+j.posClass.join("-")),!b){var l=this;this.timeout=window.setTimeout(function(){c.classList.add("psv-tooltip--visible"),l.psv.trigger("show-tooltip"),l.timeout=null},this.config.delay)}},n.prototype.hideTooltip=function(){if(this.timeout&&(window.clearTimeout(this.timeout),this.timeout=null),this.isTooltipVisible()){this.container.classList.remove("psv-tooltip--visible"),this.psv.trigger("hide-tooltip");var a=this;this.timeout=window.setTimeout(function(){a.content.innerHTML=null,a.container.style.top="-1000px",a.container.style.left="-1000px",a.timeout=null},this.config.delay)}},n.prototype._computeTooltipPosition=function(a,b){var c=!1;switch(a.posClass[0]){case"bottom":a.top=b.top+b.marker.height+this.config.offset+this.config.arrow_size,a.arrow_top=2*-this.config.arrow_size,c=!0;break;case"center":a.top=b.top+b.marker.height/2-a.height/2,a.arrow_top=a.height/2-this.config.arrow_size;break;case"top":a.top=b.top-a.height-this.config.offset-this.config.arrow_size,a.arrow_top=a.height,c=!0}switch(a.posClass[1]){case"right":c?(a.left=b.left+b.marker.width/2-this.config.offset-this.config.arrow_size,a.arrow_left=this.config.offset):(a.left=b.left+b.marker.width+this.config.offset+this.config.arrow_size,a.arrow_left=2*-this.config.arrow_size);break;case"center":a.left=b.left+b.marker.width/2-a.width/2,a.arrow_left=a.width/2-this.config.arrow_size;break;case"left":c?(a.left=b.left-a.width+b.marker.width/2+this.config.offset+this.config.arrow_size,a.arrow_left=a.width-this.config.offset-2*this.config.arrow_size):(a.left=b.left-a.width-this.config.offset-this.config.arrow_size,a.arrow_left=a.width)}},o.prototype=Object.create(f.prototype),o.prototype.constructor=o,o.prototype.create=function(){f.prototype.create.call(this),this.constructor.icon&&this.setIcon(this.constructor.icon),this.container.addEventListener("click",function(){this.enabled&&this._onClick()}.bind(this))},o.prototype.setIcon=function(a,b){b||(b=this.container),a?(b.innerHTML=e.ICONS[a],b.querySelector("svg").classList.add("psv-button-svg")):b.innerHTML=""},o.prototype.toggleActive=function(a){a=x.toggleClass(this.container,"psv-button--active",a),this.constructor.iconActive&&this.setIcon(a?this.constructor.iconActive:this.constructor.icon)},o.prototype.disable=function(){this.container.classList.add("psv-button--disabled"),this.enabled=!1},o.prototype.enable=function(){this.container.classList.remove("psv-button--disabled"),this.enabled=!0},o.prototype._onClick=function(){},p.prototype=Object.create(o.prototype),p.prototype.constructor=p,p.id="autorotate",p.className="psv-button psv-button--hover-scale psv-autorotate-button",p.icon="play.svg",p.iconActive="play-active.svg",p.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.autorotate,this.psv.on("autorotate",this)},p.prototype.destroy=function(){this.psv.off("autorotate",this),o.prototype.destroy.call(this)},p.prototype.handleEvent=function(a){switch(a.type){case"autorotate":this.toggleActive(a.args[0])}},p.prototype._onClick=function(){this.psv.toggleAutorotate()},q.prototype=Object.create(o.prototype),q.prototype.constructor=q,q.className="psv-button psv-custom-button",q.prototype.create=function(){o.prototype.create.call(this),this.config.className&&x.addClasses(this.container,this.config.className),this.config.title&&(this.container.title=this.config.title),this.config.content&&(this.container.innerHTML=this.config.content),this.config.enabled!==!1&&this.config.disabled!==!0||this.disable(),this.config.visible!==!1&&this.config.hidden!==!0||this.hide()},q.prototype.destroy=function(){delete this.config,o.prototype.destroy.call(this)},q.prototype._onClick=function(){this.config.onClick&&this.config.onClick.apply(this.psv)},r.prototype=Object.create(o.prototype),r.prototype.constructor=r,r.id="download",r.className="psv-button psv-button--hover-scale psv-download-button",r.icon="download.svg",r.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.download},r.prototype._onClick=function(){var a=document.createElement("a");a.href=this.psv.config.panorama,a.download=this.psv.config.panorama,this.psv.container.appendChild(a),a.click()},s.prototype=Object.create(o.prototype),s.prototype.constructor=s,s.id="fullscreen",s.className="psv-button psv-button--hover-scale psv-fullscreen-button",s.icon="fullscreen-in.svg",s.iconActive="fullscreen-out.svg",s.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.fullscreen,this.psv.on("fullscreen-updated",this)},s.prototype.destroy=function(){this.psv.off("fullscreen-updated",this),o.prototype.destroy.call(this)},s.prototype.handleEvent=function(a){switch(a.type){case"fullscreen-updated":this.toggleActive(a.args[0])}},s.prototype._onClick=function(){this.psv.toggleFullscreen()},t.prototype=Object.create(o.prototype),t.prototype.constructor=t,t.id="gyroscope",t.className="psv-button psv-button--hover-scale psv-gyroscope-button",t.icon="compass.svg",t.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.gyroscope,e.SYSTEM.deviceOrientationSupported.promise.then(this._onAvailabilityChange.bind(this,!0),this._onAvailabilityChange.bind(this,!1)),this.hide(),this.psv.on("gyroscope-updated",this)},t.prototype.destroy=function(){this.psv.off("gyroscope-updated",this),o.prototype.destroy.call(this)},t.prototype.handleEvent=function(a){switch(a.type){case"gyroscope-updated":this.toggleActive(a.args[0])}},t.prototype._onClick=function(){this.psv.toggleGyroscopeControl()},t.prototype._onAvailabilityChange=function(a){if(a){if(!x.checkTHREE("DeviceOrientationControls"))throw new w("Missing Three.js components: DeviceOrientationControls. Get them from threejs-examples package.");this.show()}},u.prototype=Object.create(o.prototype),u.prototype.constructor=u,u.id="markers",u.className="psv-button psv-button--hover-scale psv-markers-button",u.icon="pin.svg",u.publicMethods=["toggleMarkersList","showMarkersList","hideMarkersList"],u.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.markers,this.psv.on("open-panel",this),this.psv.on("close-panel",this)},u.prototype.destroy=function(){this.psv.off("open-panel",this),this.psv.off("close-panel",this),delete this.prop,o.prototype.destroy.call(this)},u.prototype.handleEvent=function(a){switch(a.type){case"open-panel":this._onPanelOpened();break;case"close-panel":this._onPanelClosed()}},u.prototype._onClick=function(){this.toggleMarkersList()},u.prototype.toggleMarkersList=function(){this.prop.panelOpened?this.hideMarkersList():this.showMarkersList()},u.prototype.showMarkersList=function(){var a=[];for(var b in this.psv.hud.markers)a.push(this.psv.hud.markers[b]);var c=this.psv.config.templates.markersList({markers:this.psv.change("render-markers-list",a),config:this.psv.config});this.prop.panelOpening=!0,this.psv.panel.showPanel(c,!0),this.psv.panel.container.querySelector(".psv-markers-list").addEventListener("click",this._onClickItem.bind(this))},u.prototype.hideMarkersList=function(){this.prop.panelOpened&&this.psv.panel.hidePanel()},u.prototype._onClickItem=function(a){var b;a.target&&(b=x.getClosest(a.target,"li"))&&b.dataset.psvMarker&&(this.psv.hud.gotoMarker(b.dataset.psvMarker,1e3),this.psv.panel.hidePanel())},u.prototype._onPanelOpened=function(){this.prop.panelOpening?(this.prop.panelOpening=!1,this.prop.panelOpened=!0):this.prop.panelOpened=!1,this.toggleActive(this.prop.panelOpened)},u.prototype._onPanelClosed=function(){this.prop.panelOpened=!1,this.prop.panelOpening=!1,this.toggleActive(this.prop.panelOpened)},v.prototype=Object.create(o.prototype),v.prototype.constructor=v,v.id="zoom",v.className="psv-button psv-zoom-button",v.prototype.create=function(){o.prototype.create.call(this);var a=document.createElement("div");a.className="psv-zoom-button-minus",a.title=this.psv.config.lang.zoomOut,this.setIcon("zoom-out.svg",a),this.container.appendChild(a);var b=document.createElement("div");b.className="psv-zoom-button-range",this.container.appendChild(b),this.zoom_range=document.createElement("div"),this.zoom_range.className="psv-zoom-button-line",this.zoom_range.title=this.psv.config.lang.zoom,b.appendChild(this.zoom_range),this.zoom_value=document.createElement("div"),this.zoom_value.className="psv-zoom-button-handle",this.zoom_value.title=this.psv.config.lang.zoom,this.zoom_range.appendChild(this.zoom_value);var c=document.createElement("div");c.className="psv-zoom-button-plus",c.title=this.psv.config.lang.zoomIn,this.setIcon("zoom-in.svg",c),this.container.appendChild(c),this.zoom_range.addEventListener("mousedown",this),this.zoom_range.addEventListener("touchstart",this),this.psv.container.addEventListener("mousemove",this),this.psv.container.addEventListener("touchmove",this),this.psv.container.addEventListener("mouseup",this),this.psv.container.addEventListener("touchend",this),a.addEventListener("mousedown",this._zoomOut.bind(this)),c.addEventListener("mousedown",this._zoomIn.bind(this)),this.psv.on("zoom-updated",this),this.psv.once("ready",function(){this._moveZoomValue(this.psv.prop.zoom_lvl)}.bind(this))},v.prototype.destroy=function(){this.psv.container.removeEventListener("mousemove",this),this.psv.container.removeEventListener("touchmove",this),this.psv.container.removeEventListener("mouseup",this),this.psv.container.removeEventListener("touchend",this),delete this.zoom_range,delete this.zoom_value,this.psv.off("zoom-updated",this),o.prototype.destroy.call(this)},v.prototype.handleEvent=function(a){switch(a.type){case"mousedown":this._initZoomChangeWithMouse(a);break;case"touchstart":this._initZoomChangeByTouch(a);break;case"mousemove":this._changeZoomWithMouse(a);break;case"touchmove":this._changeZoomByTouch(a);break;case"mouseup":this._stopZoomChange(a);break;case"touchend":this._stopZoomChange(a);break;case"zoom-updated":this._moveZoomValue(a.args[0]); -}},v.prototype._moveZoomValue=function(a){this.zoom_value.style.left=a/100*this.zoom_range.offsetWidth-this.zoom_value.offsetWidth/2+"px"},v.prototype._initZoomChangeWithMouse=function(a){this.enabled&&(this.prop.mousedown=!0,this._changeZoom(a.clientX))},v.prototype._initZoomChangeByTouch=function(a){this.enabled&&(this.prop.mousedown=!0,this._changeZoom(a.changedTouches[0].clientX))},v.prototype._zoomIn=function(){this.enabled&&(this.prop.buttondown=!0,this.psv.zoomIn(),window.setTimeout(this._startLongPressInterval.bind(this,1),200))},v.prototype._zoomOut=function(){this.enabled&&(this.prop.buttondown=!0,this.psv.zoomOut(),window.setTimeout(this._startLongPressInterval.bind(this,-1),200))},v.prototype._startLongPressInterval=function(a){this.prop.buttondown&&(this.prop.longPressInterval=window.setInterval(function(){this.psv.zoom(this.psv.prop.zoom_lvl+a)}.bind(this),50))},v.prototype._stopZoomChange=function(){this.enabled&&(window.clearInterval(this.prop.longPressInterval),this.prop.longPressInterval=null,this.prop.mousedown=!1,this.prop.buttondown=!1)},v.prototype._changeZoomWithMouse=function(a){this.enabled&&(a.preventDefault(),this._changeZoom(a.clientX))},v.prototype._changeZoomByTouch=function(a){this.enabled&&(a.preventDefault(),this._changeZoom(a.changedTouches[0].clientX))},v.prototype._changeZoom=function(a){if(this.prop.mousedown){var b=parseInt(a)-this.zoom_range.getBoundingClientRect().left,c=b/this.zoom_range.offsetWidth*100;this.psv.zoom(c)}},w.prototype=Object.create(Error.prototype),w.prototype.name="PSVError",w.prototype.constructor=w;var x={};return x.TwoPI=2*Math.PI,x.HalfPI=Math.PI/2,x.checkTHREE=function(b){for(var c=0,d=arguments.length;c(.*)"))?c[1]:null!==(c=a.match("GPano:"+b+'="(.*?)"'))?c[1]:null},x.isFullscreenEnabled=function(a){return(document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement)===a},x.requestFullscreen=function(a){(a.requestFullscreen||a.mozRequestFullScreen||a.webkitRequestFullscreen||a.msRequestFullscreen).call(a)},x.exitFullscreen=function(){(document.exitFullscreen||document.mozCancelFullScreen||document.webkitExitFullscreen||document.msExitFullscreen).call(document)},x.getStyle=function(a,b){return window.getComputedStyle(a,null)[b]},x.parsePosition=function(a){if(!a)return{top:.5,left:.5};if("object"==typeof a)return a;var b=a.toLocaleLowerCase().split(" ").slice(0,2);1===b.length&&(b=void 0!==x.parsePosition.positions[b[0]]?[b[0],"center"]:[b[0],b[0]]);var c="left"!=b[1]&&"right"!=b[1]&&"top"!=b[0]&&"bottom"!=b[0];b=b.map(function(a){return x.parsePosition.positions[a]||a}),c||b.reverse();var d=b.join(" ").match(/^([0-9.]+)% ([0-9.]+)%$/);return d?{left:d[1]/100,top:d[2]/100}:{top:.5,left:.5}},x.parsePosition.positions={top:"0%",bottom:"100%",left:"0%",right:"100%",center:"50%"},x.parseSpeed=function(a){if("string"==typeof a){a=a.toString().trim();var b=parseFloat(a.replace(/^(-?[0-9]+(?:\.[0-9]*)?).*$/,"$1")),c=a.replace(/^-?[0-9]+(?:\.[0-9]*)?(.*)$/,"$1").trim();switch(c.match(/(pm|per minute)$/)&&(b/=60),c){case"dpm":case"degrees per minute":case"dps":case"degrees per second":a=b*Math.PI/180;break;case"radians per minute":case"radians per second":a=b;break;case"rpm":case"revolutions per minute":case"rps":case"revolutions per second":a=b*x.TwoPI;break;default:throw new w('unknown speed unit "'+c+'"')}}return a},x.parseAngle=function(a,b){if("string"==typeof a){var c=a.toLowerCase().trim().match(/^(-?[0-9]+(?:\.[0-9]*)?)(.*)$/);if(!c)throw new w('unknown angle "'+a+'"');var d=parseFloat(c[1]),e=c[2];if(e)switch(e){case"deg":case"degs":a=d/180*Math.PI;break;case"rad":case"rads":a=d;break;default:throw new w('unknown angle unit "'+e+'"')}}return b!==!1&&(void 0===b&&(b=0),a=(a-b)%x.TwoPI,a<0&&(a=x.TwoPI+a),a+=b),a},x.animation=function(a){function c(b){if(d.promise.getStatus()!==-1){null===e&&(e=b);var f,g=(b-e)/a.duration,h={};if(g<1){for(f in a.properties)h[f]=a.properties[f].start+(a.properties[f].end-a.properties[f].start)*a.easing(g);a.onTick(h,g),window.requestAnimationFrame(c)}else{for(f in a.properties)h[f]=a.properties[f].end;a.onTick(h,1),a.onDone&&a.onDone(),d.resolve()}}}var d=b(),e=null;a.easing&&"string"!=typeof a.easing||(a.easing=x.animation.easings[a.easing||"linear"]),void 0!==a.delay?window.setTimeout(function(){window.requestAnimationFrame(c)},a.delay):window.requestAnimationFrame(c);var f=d.promise;return f.cancel=function(){a.onCancel&&a.onCancel(),d.reject()},f},x.animation.easings={linear:function(a){return a},inQuad:function(a){return a*a},outQuad:function(a){return a*(2-a)},inOutQuad:function(a){return a<.5?2*a*a:-1+(4-2*a)*a},inCubic:function(a){return a*a*a},outCubic:function(a){return--a*a*a+1},inOutCubic:function(a){return a<.5?4*a*a*a:(a-1)*(2*a-2)*(2*a-2)+1},inQuart:function(a){return a*a*a*a},outQuart:function(a){return 1- --a*a*a*a},inOutQuart:function(a){return a<.5?8*a*a*a*a:1-8*--a*a*a*a},inQuint:function(a){return a*a*a*a*a},outQuint:function(a){return 1+--a*a*a*a*a},inOutQuint:function(a){return a<.5?16*a*a*a*a*a:1+16*--a*a*a*a*a},inSine:function(a){return 1-Math.cos(a*(Math.PI/2))},outSine:function(a){return Math.sin(a*(Math.PI/2))},inOutSine:function(a){return.5-.5*Math.cos(Math.PI*a)},inExpo:function(a){return Math.pow(2,10*(a-1))},outExpo:function(a){return 1-Math.pow(2,-10*a)},inOutExpo:function(a){return a=2*a-1,a<0?.5*Math.pow(2,10*a):1-.5*Math.pow(2,-10*a)},inCirc:function(a){return 1-Math.sqrt(1-a*a)},outCirc:function(a){return a--,Math.sqrt(1-a*a)},inOutCirc:function(a){return a*=2,a<1?.5-.5*Math.sqrt(1-a*a):.5+.5*Math.sqrt(1-(a-=2)*a)}},x.throttle=function(a,b){var c,d,e,f=null,g=0,h=function(){g=Date.now(),f=null,e=a.apply(c,d),f||(c=d=null)};return function(){var i=Date.now();g||(g=i);var j=b-(i-g);return c=this,d=arguments,j<=0||j>b?(f&&(clearTimeout(f),f=null),g=i,e=a.apply(c,d),f||(c=d=null)):f||(f=setTimeout(h,j)),e}},x.isPlainObject=function(a){if("object"==typeof a&&null!==a){if("function"==typeof Object.getPrototypeOf){var b=Object.getPrototypeOf(a);return b===Object.prototype||null===b}return"[object Object]"==Object.prototype.toString.call(a)}return!1},x.deepmerge=function(a,b){var c=b;return function d(a,b){return Array.isArray(b)?(a&&Array.isArray(a)?a.length=0:a=[],b.forEach(function(b,c){a[c]=d(null,b)})):"object"==typeof b?(a&&!Array.isArray(a)||(a={}),Object.keys(b).forEach(function(e){"object"==typeof b[e]&&b[e]&&x.isPlainObject(b[e])?b[e]!=c&&(a[e]?d(a[e],b[e]):a[e]=d(null,b[e])):a[e]=b[e]})):a=b,a}(a,b)},x.clone=function(a){return x.deepmerge(null,a)},a.GodraysShader={uniforms:{tDiffuse:{type:"t",value:0,texture:null},fX:{type:"f",value:.5},fY:{type:"f",value:.5},fExposure:{type:"f",value:.6},fDecay:{type:"f",value:.93},fDensity:{type:"f",value:.96},fWeight:{type:"f",value:.4},fClamp:{type:"f",value:1}},vertexShader:["varying vec2 vUv;","void main()","{","vUv = vec2( uv.x, uv.y );","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["varying vec2 vUv;","uniform sampler2D tDiffuse;","uniform float fX;","uniform float fY;","uniform float fExposure;","uniform float fDecay;","uniform float fDensity;","uniform float fWeight;","uniform float fClamp;","const int iSamples = 20;","void main()","{","vec2 deltaTextCoord = vec2(vUv - vec2(fX,fY));","deltaTextCoord *= 1.0 / float(iSamples) * fDensity;","vec2 coord = vUv;","float illuminationDecay = 1.0;","vec4 FragColor = vec4(0.0);","for(int i=0; i < iSamples ; i++)","{","coord -= deltaTextCoord;","vec4 texel = texture2D(tDiffuse, coord);","texel *= illuminationDecay * fWeight;","FragColor += texel;","illuminationDecay *= fDecay;","}","FragColor *= fExposure;","FragColor = clamp(FragColor, 0.0, fClamp);","gl_FragColor = FragColor;","}"].join("\n")},function(a){if(a.requestAnimationFrame=a.requestAnimationFrame||a.mozRequestAnimationFrame||a.webkitRequestAnimationFrame||a.msRequestAnimationFrame,a.cancelAnimationFrame=a.cancelAnimationFrame||a.mozCancelAnimationFrame||a.webkitCancelAnimationFrame||a.msCancelAnimationFrame,!a.requestAnimationFrame){var b,c=[],d=[],e=0;a.requestAnimationFrame=function(a){return c.push([++e,a]),b||(b=setInterval(function(){if(c.length){var a=+new Date,e=d;for(d=c,c=e;d.length;)d.shift()[1](a)}else clearInterval(b),b=void 0},20)),e},a.cancelAnimationFrame=function(a){var b,e;for(b=0,e=c.length;bthis.config.latitude_range[1]&&(this.config.latitude_range=[this.config.latitude_range[1],this.config.latitude_range[0]],console.warn("PhotoSphereViewer: latitude_range values must be ordered.")):void 0===this.config.tilt_up_max&&void 0===this.config.tilt_down_max||(this.config.latitude_range=[void 0!==this.config.tilt_down_max?this.config.tilt_down_max-Math.PI/4:-x.HalfPI,void 0!==this.config.tilt_up_max?this.config.tilt_up_max+Math.PI/4:x.HalfPI],console.warn("PhotoSphereViewer: tilt_up_max and tilt_down_max are deprecated, use latitude_range instead.")),this.config.max_fov"),h=a.substring(b,g);if(b===-1||g===-1||h.indexOf("GPano:")===-1)c.resolve(null);else{var i={full_width:parseInt(x.getXMPValue(h,"FullPanoWidthPixels")),full_height:parseInt(x.getXMPValue(h,"FullPanoHeightPixels")),cropped_width:parseInt(x.getXMPValue(h,"CroppedAreaImageWidthPixels")),cropped_height:parseInt(x.getXMPValue(h,"CroppedAreaImageHeightPixels")),cropped_x:parseInt(x.getXMPValue(h,"CroppedAreaLeftPixels")),cropped_y:parseInt(x.getXMPValue(h,"CroppedAreaTopPixels"))};i.full_width&&i.full_height&&i.cropped_width&&i.cropped_height?c.resolve(i):(console.warn("PhotoSphereViewer: invalid XMP data"),c.resolve(null))}}else 3===d.readyState&&e.loader&&e.loader.setProgress(f+=10)},d.onprogress=function(a){if(a.lengthComputable&&e.loader){var b=parseInt(a.loaded/a.total*100);b>f&&(f=b,e.loader.setProgress(f))}},d.onerror=function(){throw e.container.textContent="Cannot load image",new w("Cannot load image")},d.open("GET",a,!0),d.send(null),c.promise},e.prototype._loadTexture=function(c){var d=this;if(this.config.cache_texture){var f=this.getPanoramaCache(c);if(f)return this.prop.pano_data=f.pano_data,b.resolved(f.image)}return this._loadXMP(c).then(function(f){var g=b(),h=new a.ImageLoader,i=f?100:0;h.setCrossOrigin("anonymous");var j=function(b){d.loader&&d.loader.setProgress(100),d.trigger("panorama-load-progress",c,100),!f&&d.config.pano_data&&(f=x.clone(d.config.pano_data)),f||(f={full_width:b.width,full_height:b.height,cropped_width:b.width,cropped_height:b.height,cropped_x:0,cropped_y:0}),d.prop.pano_data=f;var h=Math.min(f.full_width,e.SYSTEM.maxTextureWidth)/f.full_width,i=x.clone(f);i.full_width*=h,i.full_height*=h,i.cropped_width*=h,i.cropped_height*=h,i.cropped_x*=h,i.cropped_y*=h,b.width=i.cropped_width,b.height=i.cropped_height;var j=document.createElement("canvas");j.width=i.full_width,j.height=i.full_height;var k=j.getContext("2d");k.drawImage(b,i.cropped_x,i.cropped_y,i.cropped_width,i.cropped_height);var l=new a.Texture(j);l.needsUpdate=!0,l.minFilter=a.LinearFilter,l.generateMipmaps=!1,d.config.cache_texture&&d._putPanoramaCache({panorama:c,image:l,pano_data:f}),g.resolve(l)},k=function(a){if(a.lengthComputable&&d.loader){var b=parseInt(a.loaded/a.total*100);b>i&&(i=b,d.loader.setProgress(i),d.trigger("panorama-load-progress",c,i))}},l=function(){throw d.container.textContent="Cannot load image",new w("Cannot load image")};return h.load(c,j,k,l),g.promise})},e.prototype._setTexture=function(a){this.scene||this._createScene(),this.mesh.material.map&&this.mesh.material.map.dispose(),this.mesh.material.map=a,this.trigger("panorama-loaded"),this.render()},e.prototype._createScene=function(){this.raycaster=new a.Raycaster,this.renderer=e.SYSTEM.isWebGLSupported&&this.config.webgl?new a.WebGLRenderer:new a.CanvasRenderer,this.renderer.setSize(this.prop.size.width,this.prop.size.height),this.renderer.setPixelRatio(e.SYSTEM.pixelRatio),this.camera=new a.PerspectiveCamera(this.config.default_fov,this.prop.size.width/this.prop.size.height,1,2*e.SPHERE_RADIUS),this.camera.position.set(0,0,0),this.config.gyroscope&&x.checkTHREE("DeviceOrientationControls")&&(this.doControls=new a.DeviceOrientationControls(this.camera)),this.scene=new a.Scene,this.scene.add(this.camera);var b=new a.SphereGeometry(e.SPHERE_RADIUS,this.config.sphere_segments,this.config.sphere_segments,(-x.HalfPI)),c=new a.MeshBasicMaterial;c.side=a.DoubleSide,c.overdraw=e.SYSTEM.isWebGLSupported&&this.config.webgl?0:.5,this.mesh=new a.Mesh(b,c),this.mesh.scale.x=-1,this.scene.add(this.mesh),this.canvas_container=document.createElement("div"),this.canvas_container.className="psv-canvas-container",this.renderer.domElement.className="psv-canvas",this.container.appendChild(this.canvas_container),this.canvas_container.appendChild(this.renderer.domElement),this.config.time_anim!==!1&&(this.prop.start_timeout=window.setTimeout(this.startAutorotate.bind(this),this.config.time_anim)),this.config.transition&&this.config.transition.blur&&(this.composer=new a.EffectComposer(this.renderer),this.passes.render=new a.RenderPass(this.scene,this.camera),this.passes.copy=new a.ShaderPass(a.CopyShader),this.passes.copy.renderToScreen=!0,this.passes.blur=new a.ShaderPass(a.GodraysShader),this.passes.blur.enabled=!1,this.passes.blur.renderToScreen=!0,this.passes.blur.uniforms.fDensity.value=0,this.passes.blur.uniforms.fWeight.value=.5,this.passes.blur.uniforms.fDecay.value=.5,this.passes.blur.uniforms.fExposure.value=1,this.composer.addPass(this.passes.render),this.composer.addPass(this.passes.copy),this.composer.addPass(this.passes.blur))},e.prototype._transition=function(b,c){var d=this,f=new a.SphereGeometry(1.5*e.SPHERE_RADIUS,this.config.sphere_segments,this.config.sphere_segments,(-x.HalfPI)),g=new a.MeshBasicMaterial;g.side=a.DoubleSide,g.overdraw=e.SYSTEM.isWebGLSupported&&this.config.webgl?0:.5,g.map=b,g.transparent=!0,g.opacity=0;var h=new a.Mesh(f,g);if(h.scale.x=-1,c){h.rotateY(c.longitude-this.prop.longitude);var i=new a.Vector3(0,1,0).cross(this.camera.getWorldDirection()).normalize(),j=(new a.Quaternion).setFromAxisAngle(i,c.latitude-this.prop.latitude);h.quaternion.multiplyQuaternions(j,h.quaternion)}this.scene.add(h),this.render();var k=this.prop.zoom_lvl;this.config.transition.blur&&(this.passes.copy.enabled=!1,this.passes.blur.enabled=!0);var l=function(a){g.opacity=a.opacity,d.config.transition.blur&&(d.passes.blur.uniforms.fDensity.value=a.density,d.zoom(a.zoom,!1)),d.render()};return x.animation({properties:{density:{start:0,end:1.5},opacity:{start:0,end:.5},zoom:{start:k,end:100}},duration:d.config.transition.duration/(d.config.transition.blur?4/3:2),easing:d.config.transition.blur?"outCubic":"linear",onTick:l}).then(function(){return x.animation({properties:{density:{start:1.5,end:0},opacity:{start:.5,end:1},zoom:{start:100,end:k}},duration:d.config.transition.duration/(d.config.transition.blur?4:2),easing:d.config.transition.blur?"inCubic":"linear",onTick:l})}).then(function(){d.config.transition.blur&&(d.passes.copy.enabled=!0,d.passes.blur.enabled=!1,d.zoom(k,!1)),d.mesh.material.map.dispose(),d.mesh.material.map=b,d.scene.remove(h),h.geometry.dispose(),h.geometry=null,h.material.dispose(),h.material=null,c?((d.config.latitude_range||d.config.longitude_range)&&(d.config.longitude_range=d.config.latitude_range=null,console.warn("PhotoSphereViewer: trying to perform transition with longitude_range and/or latitude_range, ranges cleared.")),d.rotate(c)):d.render()})},e.prototype._reverseAutorotate=function(){var a=this,b=-this.config.anim_speed,c=this.config.longitude_range;this.config.longitude_range=null,x.animation({properties:{speed:{start:this.config.anim_speed,end:0}},duration:300,easing:"inSine",onTick:function(b){a.config.anim_speed=b.speed}}).then(function(){return x.animation({properties:{speed:{start:0,end:b}},duration:300,easing:"outSine",onTick:function(b){a.config.anim_speed=b.speed}})}).then(function(){a.config.longitude_range=c,a.config.anim_speed=b})},e.prototype._putPanoramaCache=function(a){if(!this.config.cache_texture)throw new w("Cannot add panorama to cache, cache_texture is disabled");var b=this.getPanoramaCache(a.panorama);b?(b.image=a.image,b.pano_data=a.pano_data):(this.prop.cache=this.prop.cache.slice(0,this.config.cache_texture-1),this.prop.cache.unshift(a)),this.trigger("panorama-cached",a.panorama)},e.MOVE_THRESHOLD=4,e.INERTIA_WINDOW=300,e.SPHERE_RADIUS=100,e.KEYMAP={33:"PageUp",34:"PageDown",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",107:"+",109:"-"},e.ICONS={},e.SYSTEM={loaded:!1,pixelRatio:1,isWebGLSupported:!1,isCanvasSupported:!1,deviceOrientationSupported:null,maxTextureWidth:0,mouseWheelEvent:null,fullscreenEvent:null},e.DEFAULTS={panorama:null,container:null,caption:null,autoload:!0,usexmpdata:!0,pano_data:null,webgl:!0,sphere_segments:64,min_fov:30,max_fov:90,default_fov:null,default_long:0,default_lat:0,longitude_range:null,latitude_range:null,move_speed:1,time_anim:2e3,anim_speed:"2rpm",anim_lat:null,fisheye:!1,navbar:["autorotate","zoom","download","markers","caption","gyroscope","fullscreen"],tooltip:{offset:5,arrow_size:7,delay:100},lang:{autorotate:"Automatic rotation",zoom:"Zoom",zoomOut:"Zoom out",zoomIn:"Zoom in",download:"Download",fullscreen:"Fullscreen",markers:"Markers",gyroscope:"Gyroscope"},mousewheel:!0,mousemove:!0,keyboard:!0,gyroscope:!1,move_inertia:!0,click_event_on_marker:!1,transition:{duration:1500,loader:!0,blur:!1},loading_img:null,loading_txt:"Loading...",size:null,cache_texture:5,templates:{},markers:[]},e.TEMPLATES={markersList:'

{{= it.config.lang.markers }}

    {{~ it.markers: marker }}
  • {{? marker.image }}{{?}}

    {{? marker.tooltip }}{{= marker.tooltip.content }}{{?? marker.html }}{{= marker.html }}{{??}}{{= marker.id }}{{?}}

  • {{~}}
'},e.prototype._bindEvents=function(){window.addEventListener("resize",this),document.addEventListener(e.SYSTEM.fullscreenEvent,this),this.config.mousemove&&(this.hud.container.style.cursor="move",this.hud.container.addEventListener("mousedown",this),this.hud.container.addEventListener("touchstart",this),window.addEventListener("mouseup",this),window.addEventListener("touchend",this),this.hud.container.addEventListener("mousemove",this),this.hud.container.addEventListener("touchmove",this)),this.config.mousewheel&&this.hud.container.addEventListener(e.SYSTEM.mouseWheelEvent,this),this.on("_side-reached",function(a){this.isAutorotateEnabled()&&("left"!==a&&"right"!==a||this._reverseAutorotate())})},e.prototype.handleEvent=function(a){switch(a.type){case"resize":x.throttle(this._onResize(),50);break;case"keydown":this._onKeyDown(a);break;case"mousedown":this._onMouseDown(a);break;case"touchstart":this._onTouchStart(a);break;case"mouseup":this._onMouseUp(a);break;case"touchend":this._onTouchEnd(a);break;case"mousemove":this._onMouseMove(a);break;case"touchmove":this._onTouchMove(a);break;case e.SYSTEM.fullscreenEvent:this._fullscreenToggled();break;case e.SYSTEM.mouseWheelEvent:this._onMouseWheel(a)}},e.prototype._onResize=function(){this.container.clientWidth==this.prop.size.width&&this.container.clientHeight==this.prop.size.height||(this.prop.size.width=parseInt(this.container.clientWidth),this.prop.size.height=parseInt(this.container.clientHeight),this.prop.aspect=this.prop.size.width/this.prop.size.height,this.renderer&&(this.renderer.setSize(this.prop.size.width,this.prop.size.height),this.composer&&this.composer.reset(new a.WebGLRenderTarget(this.prop.size.width,this.prop.size.height)),this.render()),this.trigger("size-updated",this.getSize()))},e.prototype._onKeyDown=function(a){var b=0,c=0,d=0,f=a.key||e.KEYMAP[a.keyCode||a.which];switch(f){case"ArrowUp":c=.01;break;case"ArrowDown":c=-.01;break;case"ArrowRight":b=.01;break;case"ArrowLeft":b=-.01;break;case"PageUp":case"+":d=1;break;case"PageDown":case"-":d=-1}0!==d?this.zoom(this.prop.zoom_lvl+d):0===c&&0===b||this.rotate({longitude:this.prop.longitude+b*this.prop.move_speed*this.prop.hFov,latitude:this.prop.latitude+c*this.prop.move_speed*this.prop.vFov})},e.prototype._onMouseDown=function(a){this._startMove(a)},e.prototype._onTouchStart=function(a){1===a.touches.length?this._startMove(a.touches[0]):2===a.touches.length&&this._startZoom(a)},e.prototype._startMove=function(a){this.isGyroscopeEnabled()||(this.stopAll(),this.prop.mouse_x=this.prop.start_mouse_x=parseInt(a.clientX),this.prop.mouse_y=this.prop.start_mouse_y=parseInt(a.clientY),this.prop.moving=!0,this.prop.zooming=!1,this.prop.mouse_history.length=0,this._logMouseMove(a))},e.prototype._startZoom=function(a){var b=[{x:parseInt(a.touches[0].clientX),y:parseInt(a.touches[0].clientY)},{x:parseInt(a.touches[1].clientX),y:parseInt(a.touches[1].clientY)}];this.prop.pinch_dist=Math.sqrt(Math.pow(b[0].x-b[1].x,2)+Math.pow(b[0].y-b[1].y,2)),this.prop.moving=!1,this.prop.zooming=!0},e.prototype._onMouseUp=function(a){this._stopMove(a)},e.prototype._onTouchEnd=function(a){this._stopMove(a.changedTouches[0])},e.prototype._stopMove=function(a){return this.isGyroscopeEnabled()?void this._click(a):(this.prop.moving&&(Math.abs(a.clientX-this.prop.start_mouse_x)e.INERTIA_WINDOW/10?(this.prop.mouse_history.splice(0,d),d=0,c=this.prop.mouse_history[0][d]):(d++,c=this.prop.mouse_history[0][d])},e.prototype.load=function(){if(!this.config.panorama)throw new w("No value given for panorama.");this.setPanorama(this.config.panorama,!1)},e.prototype.getPosition=function(){return{longitude:this.prop.longitude,latitude:this.prop.latitude}},e.prototype.getZoomLevel=function(){return this.prop.zoom_lvl},e.prototype.getSize=function(){return{width:this.prop.size.width,height:this.prop.size.height}},e.prototype.isAutorotateEnabled=function(){return!!this.prop.autorotate_reqid},e.prototype.isGyroscopeEnabled=function(){return!!this.prop.orientation_reqid},e.prototype.isFullscreenEnabled=function(){return x.isFullscreenEnabled(this.parent)},e.prototype.render=function(a){a!==!1&&(this.prop.direction=this.sphericalCoordsToVector3(this.prop.longitude,this.prop.latitude),this.config.fisheye&&(this.prop.direction.multiplyScalar(this.config.fisheye/2),this.camera.position.copy(this.prop.direction).negate()),this.camera.lookAt(this.prop.direction)),this.camera.aspect=this.prop.aspect,this.camera.fov=this.prop.vFov,this.camera.updateProjectionMatrix(),this.composer?this.composer.render():this.renderer.render(this.scene,this.camera),this.trigger("render")},e.prototype.destroy=function(){this.stopAll(),this.stopKeyboardControl(),this.isFullscreenEnabled()&&x.exitFullscreen(),window.removeEventListener("resize",this),document.removeEventListener(e.SYSTEM.fullscreenEvent,this),this.config.mousemove&&(this.hud.container.removeEventListener("mousedown",this),this.hud.container.removeEventListener("touchstart",this),window.removeEventListener("mouseup",this),window.removeEventListener("touchend",this),this.hud.container.removeEventListener("mousemove",this),this.hud.container.removeEventListener("touchmove",this)),this.config.mousewheel&&this.hud.container.removeEventListener(e.SYSTEM.mouseWheelEvent,this),this.tooltip&&this.tooltip.destroy(),this.hud&&this.hud.destroy(),this.loader&&this.loader.destroy(),this.navbar&&this.navbar.destroy(),this.panel&&this.panel.destroy(),this.doControls&&this.doControls.disconnect(),this.scene&&(this.scene.remove(this.camera),this.scene.remove(this.mesh)),this.mesh&&(this.mesh.geometry.dispose(),this.mesh.geometry=null,this.mesh.material.map.dispose(),this.mesh.material.map=null,this.mesh.material.dispose(),this.mesh.material=null),this.canvas_container&&this.container.removeChild(this.canvas_container),this.parent.removeChild(this.container),delete this.parent.photoSphereViewer,delete this.parent,delete this.container,delete this.loader,delete this.navbar,delete this.hud,delete this.panel,delete this.tooltip,delete this.canvas_container,delete this.renderer,delete this.composer,delete this.scene,delete this.camera,delete this.mesh,delete this.doControls,delete this.raycaster,delete this.passes,delete this.config,this.prop.cache.length=0},e.prototype.setPanorama=function(a,b,c){if(null!==this.prop.loading_promise)throw new w("Loading already in progress");"boolean"==typeof b&&(c=b,b=void 0),b&&(this.cleanPosition(b),this.stopAll()),this.config.panorama=a;var d=this;return c&&this.config.transition&&this.scene?(this.config.transition.loader&&(this.loader=new h(this)),this.prop.loading_promise=this._loadTexture(this.config.panorama).then(function(a){return d.loader&&(d.loader.destroy(),d.loader=null),d._transition(a,b)}).ensure(function(){d.loader&&(d.loader.destroy(),d.loader=null),d.prop.loading_promise=null}).rethrow()):(this.loader=new h(this),this.prop.loading_promise=this._loadTexture(this.config.panorama).ensure(function(){d.loader&&(d.loader.destroy(),d.loader=null),d.prop.loading_promise=null}).then(function(a){d._setTexture(a),b&&d.rotate(b)}).rethrow()),this.prop.loading_promise},e.prototype.stopAll=function(){this.stopAutorotate(),this.stopAnimation(),this.stopGyroscopeControl()},e.prototype.startAutorotate=function(){this.stopAll();var a=this,b=null,c=null;!function d(e){e&&(c=null===b?0:e-b,b=e,a.rotate({longitude:a.prop.longitude+a.config.anim_speed*c/1e3,latitude:a.prop.latitude-(a.prop.latitude-a.config.anim_lat)/200})),a.prop.autorotate_reqid=window.requestAnimationFrame(d)}(null),this.trigger("autorotate",!0)},e.prototype.stopAutorotate=function(){this.prop.start_timeout&&(window.clearTimeout(this.prop.start_timeout),this.prop.start_timeout=null),this.prop.autorotate_reqid&&(window.cancelAnimationFrame(this.prop.autorotate_reqid),this.prop.autorotate_reqid=null,this.trigger("autorotate",!1))},e.prototype.toggleAutorotate=function(){this.isAutorotateEnabled()?this.stopAutorotate():this.startAutorotate()},e.prototype.startGyroscopeControl=function(){if(!this.config.gyroscope)return void console.warn("PhotoSphereViewer: gyroscope disabled");this.stopAll();var a=this;!function b(){a.doControls.update(),a.prop.direction=a.camera.getWorldDirection();var c=a.vector3ToSphericalCoords(a.prop.direction);a.prop.longitude=c.longitude,a.prop.latitude=c.latitude,a.render(!1),a.prop.orientation_reqid=window.requestAnimationFrame(b)}(),this.trigger("gyroscope-updated",!0)},e.prototype.stopGyroscopeControl=function(){this.prop.orientation_reqid&&(window.cancelAnimationFrame(this.prop.orientation_reqid),this.prop.orientation_reqid=null,this.trigger("gyroscope-updated",!1),this.render())},e.prototype.toggleGyroscopeControl=function(){this.isGyroscopeEnabled()?this.stopGyroscopeControl():this.startGyroscopeControl()},e.prototype.rotate=function(a,b){this.cleanPosition(a),this.applyRanges(a),this.prop.longitude=a.longitude,this.prop.latitude=a.latitude,b!==!1&&this.renderer&&(this.render(),this.trigger("position-updated",this.getPosition()))},e.prototype.animate=function(a,b){if(this.stopAll(),!b)return void this.rotate(a);if(this.cleanPosition(a),this.applyRanges(a),!b&&"number"!=typeof b){b=b?x.parseSpeed(b):this.config.anim_speed;var c=Math.acos(Math.cos(this.prop.latitude)*Math.cos(a.latitude)*Math.cos(this.prop.longitude-a.longitude)+Math.sin(this.prop.latitude)*Math.sin(a.latitude));b=c/b*1e3}var d=this.getShortestArc(this.prop.longitude,a.longitude);return this.prop.animation_promise=x.animation({properties:{longitude:{start:this.prop.longitude,end:this.prop.longitude+d},latitude:{start:this.prop.latitude,end:a.latitude}},duration:b,easing:"inOutSine",onTick:this.rotate.bind(this)}),this.prop.animation_promise},e.prototype.stopAnimation=function(){this.prop.animation_promise&&(this.prop.animation_promise.cancel(),this.prop.animation_promise=null)},e.prototype.zoom=function(a,b){this.prop.zoom_lvl=x.stayBetween(Math.round(a),0,100),this.prop.vFov=this.config.max_fov+this.prop.zoom_lvl/100*(this.config.min_fov-this.config.max_fov),this.prop.hFov=2*Math.atan(Math.tan(this.prop.vFov*Math.PI/180/2)*this.prop.aspect)*180/Math.PI,b!==!1&&this.renderer&&(this.render(),this.trigger("zoom-updated",this.getZoomLevel()))},e.prototype.zoomIn=function(){this.prop.zoom_lvl<100&&this.zoom(this.prop.zoom_lvl+1)},e.prototype.zoomOut=function(){this.prop.zoom_lvl>0&&this.zoom(this.prop.zoom_lvl-1)},e.prototype.toggleFullscreen=function(){this.isFullscreenEnabled()?x.exitFullscreen():x.requestFullscreen(this.parent)},e.prototype.startKeyboardControl=function(){ +window.addEventListener("keydown",this)},e.prototype.stopKeyboardControl=function(){window.removeEventListener("keydown",this)},e.prototype.preloadPanorama=function(a){if(!this.config.cache_texture)throw new w("Cannot preload panorama, cache_texture is disabled");return this._loadTexture(a)},e.prototype.clearPanoramaCache=function(a){if(!this.config.cache_texture)throw new w("Cannot clear cache, cache_texture is disabled");if(a){for(var b=0,c=this.prop.cache.length;b=Math.PI?c-Math.PI:c+Math.PI,latitude:x.HalfPI-d}},e.prototype.sphericalCoordsToTextureCoords=function(a,b){var c=a/x.TwoPI*this.prop.pano_data.full_width,d=b/Math.PI*this.prop.pano_data.full_height;return{x:parseInt(ab[1]?a.longitude>b[1]&&a.longitudeb[0]/2+b[1]/2?(a.longitude=b[0],this.trigger("_side-reached","left")):(a.longitude=b[1],this.trigger("_side-reached","right"))):a.longitudeb[1]&&(a.longitude=b[1],this.trigger("_side-reached","right"))),this.config.latitude_range&&(b=x.clone(this.config.latitude_range),c=this.prop.vFov/180*Math.PI/2,b[0]=x.parseAngle(Math.min(b[0]+c,b[1]),-Math.PI),b[1]=x.parseAngle(Math.max(b[1]-c,b[0]),-Math.PI),a.latitudeb[1]&&(a.latitude=b[1],this.trigger("_side-reached","top")))},e.prototype.getShortestArc=function(a,b){var c=[0,x.TwoPI,-x.TwoPI];return c.reduce(function(c,d){return d=b-a+d,Math.abs(d)2){c.position2D=this._getPolygonDimensions(c,e);var f="";e.forEach(function(a){f+=a.left+","+a.top+" "}),c.$el.setAttributeNS(null,"points",f)}}else if(d){var g=this._getMarkerPosition(c);d=this._isMarkerVisible(c,g),d&&(c.position2D=g,c.$el.style.transform="translate3D("+g.left+"px, "+g.top+"px, 0px)"+(!c.lockRotation&&a?" rotateZ("+a+"deg)":""))}x.toggleClass(c.$el,"psv-marker--visible",d)}},g.prototype._isMarkerVisible=function(a,b){return a.position3D.dot(this.psv.prop.direction)>0&&b.left+a.width>=0&&b.left-a.width<=this.psv.prop.size.width&&b.top+a.height>=0&&b.top-a.height<=this.psv.prop.size.height},g.prototype._getMarkerPosition=function(a){if(a.dynamicSize){a.$el.classList.add("psv-marker--transparent");var b=a.$el.getBoundingClientRect();a.$el.classList.remove("psv-marker--transparent"),a.width=b.right-b.left,a.height=b.bottom-b.top}var c=this.psv.vector3ToViewerCoords(a.position3D);return c.top-=a.height*a.anchor.top,c.left-=a.width*a.anchor.left,c},g.prototype._getPolygonPositions=function(a){var b=a.positions3D.length,c=a.positions3D.map(function(a){return{vector:a,visible:a.dot(this.psv.prop.direction)>0}},this),d=[];return c.forEach(function(a,e){if(!a.visible){var f=[0===e?c[b-1]:c[e-1],e===b-1?c[0]:c[e+1]];f.forEach(function(b){b.visible&&d.push({visible:b,invisible:a,index:e})})}}),d.reverse().forEach(function(a){c.splice(a.index,0,{vector:this._getPolygonIntermediaryPoint(a.visible.vector,a.invisible.vector),visible:!0})},this),c.filter(function(a){return a.visible}).map(function(a){return this.psv.vector3ToViewerCoords(a.vector)},this)},g.prototype._getPolygonIntermediaryPoint=function(b,c){var d=this.psv.prop.direction.clone().normalize(),f=(new a.Vector3).crossVectors(b,c).normalize(),g=(new a.Vector3).crossVectors(f,b).normalize(),h=(new a.Vector3).addVectors(b.clone().multiplyScalar(-d.dot(g)),g.clone().multiplyScalar(d.dot(b))).normalize(),i=(new a.Vector3).crossVectors(h,d);return h.applyAxisAngle(i,.01).multiplyScalar(e.SPHERE_RADIUS)},g.prototype._getPolygonDimensions=function(a,b){var c=+(1/0),d=+(1/0),e=-(1/0),f=-(1/0);return b.forEach(function(a){c=Math.min(c,a.left),d=Math.min(d,a.top),e=Math.max(e,a.left),f=Math.max(f,a.top)}),a.width=e-c,a.height=f-d,{top:d,left:c}},g.prototype._onMouseEnter=function(a){var b;a.target&&(b=a.target.psvMarker)&&b.tooltip&&!b.isPolygon()&&(this.hoveringMarker=b,this.psv.tooltip.showTooltip({content:b.tooltip.content,position:b.tooltip.position,top:b.position2D.top,left:b.position2D.left,marker:b}))},g.prototype._onMouseLeave=function(a){var b;if(a.target&&(b=a.target.psvMarker)){if(b.isPolygon()&&a.relatedTarget&&x.hasParent(a.relatedTarget,this.psv.tooltip.container))return;this.hoveringMarker=null,this.psv.tooltip.hideTooltip()}},g.prototype._onMouseMove=function(a){if(!this.psv.prop.moving){var b;if(a.target&&(b=a.target.psvMarker)&&b.tooltip&&b.isPolygon()||a.target&&x.hasParent(a.target,this.psv.tooltip.container)&&(b=this.hoveringMarker)){this.hoveringMarker=b;var c=this.psv.container.getBoundingClientRect();this.psv.tooltip.showTooltip({content:b.tooltip.content,position:b.tooltip.position,top:a.clientY-c.top-this.psv.config.tooltip.arrow_size/2,left:a.clientX-c.left-this.psv.config.tooltip.arrow_size,marker:{width:2*this.psv.config.tooltip.arrow_size,height:2*this.psv.config.tooltip.arrow_size}})}else this.hoveringMarker&&this.hoveringMarker.isPolygon()&&this.psv.tooltip.hideTooltip()}},g.prototype._onClick=function(a,b){var c;a.target&&(c=x.getClosest(a.target,".psv-marker"))&&c.psvMarker?(this.currentMarker=c.psvMarker,this.psv.trigger("select-marker",c.psvMarker),this.psv.config.click_event_on_marker?a.marker=c.psvMarker:b.stopPropagation()):this.currentMarker&&(this.psv.trigger("unselect-marker",this.currentMarker),this.currentMarker=null),c&&c.psvMarker&&c.psvMarker.content?this.psv.panel.showPanel(c.psvMarker.content):this.psv.panel.prop.opened&&(b.stopPropagation(),this.psv.panel.hidePanel())},h.prototype=Object.create(f.prototype),h.prototype.constructor=h,h.className="psv-loader-container",h.prototype.create=function(){f.prototype.create.call(this),this.loader=document.createElement("div"),this.loader.className="psv-loader",this.container.appendChild(this.loader),this.canvas=document.createElement("canvas"),this.canvas.className="psv-loader-canvas",this.canvas.width=this.loader.clientWidth,this.canvas.height=this.loader.clientWidth,this.loader.appendChild(this.canvas),this.tickness=(this.loader.offsetWidth-this.loader.clientWidth)/2;var a;if(this.psv.config.loading_img?(a=document.createElement("img"),a.className="psv-loader-image",a.src=this.psv.config.loading_img):this.psv.config.loading_txt&&(a=document.createElement("div"),a.className="psv-loader-text",a.innerHTML=this.psv.config.loading_txt),a){var b=Math.round(Math.sqrt(2*Math.pow(this.canvas.width/2-this.tickness/2,2)));a.style.maxWidth=b+"px",a.style.maxHeight=b+"px",this.loader.appendChild(a)}},h.prototype.destroy=function(){delete this.loader,delete this.canvas,f.prototype.destroy.call(this)},h.prototype.setProgress=function(a){var b=this.canvas.getContext("2d");b.clearRect(0,0,this.canvas.width,this.canvas.height),b.lineWidth=this.tickness,b.strokeStyle=x.getStyle(this.loader,"color"),b.beginPath(),b.arc(this.canvas.width/2,this.canvas.height/2,this.canvas.width/2-this.tickness/2,-Math.PI/2,a/100*2*Math.PI-Math.PI/2),b.stroke()},i.getType=function(a,b){var c=["image","html","polygon_px","polygon_rad","rect","circle","ellipse","path"],d=[];if(c.forEach(function(b){a[b]&&d.push(b)}),0===d.length&&!b)throw new w("missing marker content, either "+c.join(", "));if(d.length>1)throw new w("multiple marker content, either "+c.join(", "));return d[0]},i.prototype.isNormal=function(){return"image"==this.type||"html"==this.type},i.prototype.isPolygon=function(){return"polygon_px"==this.type||"polygon_rad"==this.type},i.prototype.isSvg=function(){return"rect"==this.type||"circle"==this.type||"ellipse"==this.type||"path"==this.type},i.prototype.update=function(a){if(a&&a!==this){var b=i.getType(a,!0);if(void 0!==b&&b!==this.type)throw new w("cannot change marker type");x.deepmerge(this,a)}this.isNormal()?this.$el.setAttribute("class","psv-marker psv-marker--normal"):this.$el.setAttribute("class","psv-marker psv-marker--svg"),this.className&&x.addClasses(this.$el,this.className),this.tooltip&&(this.$el.classList.add("has-tooltip"),"string"==typeof this.tooltip&&(this.tooltip={content:this.tooltip})),this.style&&x.deepmerge(this.$el.style,this.style),this.anchor=x.parsePosition(this.anchor),this.$el.style.transformOrigin=100*this.anchor.left+"% "+100*this.anchor.top+"%",this.isNormal()?this._updateNormal():this.isPolygon()?this._updatePolygon():this._updateSvg()},i.prototype._updateNormal=function(){this.width&&this.height?(this.$el.style.width=this.width+"px",this.$el.style.height=this.height+"px",this.dynamicSize=!1):this.dynamicSize=!0,this.image?this.$el.style.backgroundImage="url("+this.image+")":this.$el.innerHTML=this.html,this.psv.cleanPosition(this),this.position3D=this.psv.sphericalCoordsToVector3(this.longitude,this.latitude)},i.prototype._updateSvg=function(){switch(this.dynamicSize=!0,this.type){case"rect":"number"==typeof this._def?this._def={x:0,y:0,width:this._def,height:this._def}:Array.isArray(this._def)?this._def={x:0,y:0,width:this._def[0],height:this._def[1]}:this._def.x=this._def.y=0;break;case"circle":"number"==typeof this._def?this._def={cx:this._def,cy:this._def,r:this._def}:Array.isArray(this._def)?this._def={cx:this._def[0],cy:this._def[0],r:this._def[0]}:this._def.cx=this._def.cy=this._def.r;break;case"ellipse":"number"==typeof this._def?this._def={cx:this._def,cy:this._def,rx:this._def,ry:this._def}:Array.isArray(this._def)?this._def={cx:this._def[0],cy:this._def[1],rx:this._def[0],ry:this._def[1]}:(this._def.cx=this._def.rx,this._def.cy=this._def.ry);break;case"path":"string"==typeof this._def&&(this._def={d:this._def})}Object.getOwnPropertyNames(this._def).forEach(function(a){this.$el.setAttributeNS(null,a,this._def[a])},this),this.svgStyle?Object.getOwnPropertyNames(this.svgStyle).forEach(function(a){this.$el.setAttributeNS(null,a,this.svgStyle[a])},this):this.$el.setAttributeNS(null,"fill","rgba(0,0,0,0.5)"),this.psv.cleanPosition(this),this.position3D=this.psv.sphericalCoordsToVector3(this.longitude,this.latitude)},i.prototype._updatePolygon=function(){this.dynamicSize=!0,this.svgStyle?Object.getOwnPropertyNames(this.svgStyle).forEach(function(a){this.$el.setAttributeNS(null,a,this.svgStyle[a])},this):this.$el.setAttributeNS(null,"fill","rgba(0,0,0,0.5)"),[this.polygon_rad,this.polygon_px].forEach(function(a){if(a&&"object"!=typeof a[0])for(var b=0;b
',this.content=this.container.querySelector(".psv-panel-content");var a=this.container.querySelector(".psv-panel-close-button");a.addEventListener("click",this.hidePanel.bind(this)),this.psv.config.mousewheel&&this.container.addEventListener(e.SYSTEM.mouseWheelEvent,function(a){a.stopPropagation()});var b=this.container.querySelector(".psv-panel-resizer");b.addEventListener("mousedown",this),b.addEventListener("touchstart",this),this.psv.container.addEventListener("mouseup",this),this.psv.container.addEventListener("touchend",this),this.psv.container.addEventListener("mousemove",this),this.psv.container.addEventListener("touchmove",this)},m.prototype.destroy=function(){this.psv.container.removeEventListener("mousemove",this),this.psv.container.removeEventListener("touchmove",this),this.psv.container.removeEventListener("mouseup",this),this.psv.container.removeEventListener("touchend",this),delete this.prop,delete this.content,f.prototype.destroy.call(this)},m.prototype.handleEvent=function(a){switch(a.type){case"mousedown":this._onMouseDown(a);break;case"touchstart":this._onTouchStart(a);break;case"mousemove":this._onMouseMove(a);break;case"touchmove":this._onTouchMove(a);break;case"mouseup":this._onMouseUp(a);break;case"touchend":this._onMouseUp(a)}},m.prototype.showPanel=function(a,b){this.content.innerHTML=a,this.content.scrollTop=0,this.container.classList.add("psv-panel--open"),x.toggleClass(this.content,"psv-panel-content--no-margin",!!b),this.prop.opened=!0,this.psv.trigger("open-panel")},m.prototype.hidePanel=function(){this.content.innerHTML=null,this.prop.opened=!1,this.container.classList.remove("psv-panel--open"),this.psv.trigger("close-panel")},m.prototype._onMouseDown=function(a){a.stopPropagation(),this._startResize(a)},m.prototype._onTouchStart=function(a){a.stopPropagation(),this._startResize(a.changedTouches[0])},m.prototype._startResize=function(a){this.prop.mouse_x=parseInt(a.clientX),this.prop.mouse_y=parseInt(a.clientY),this.prop.mousedown=!0,this.content.classList.add("psv-panel-content--no-interaction")},m.prototype._onMouseUp=function(a){this.prop.mousedown&&(a.stopPropagation(),this.prop.mousedown=!1,this.content.classList.remove("psv-panel-content--no-interaction"))},m.prototype._onMouseMove=function(a){this.prop.mousedown&&(a.stopPropagation(),this._resize(a))},m.prototype._onTouchMove=function(a){this.prop.mousedown&&(a.stopPropagation(),this._resize(a.touches[0]))},m.prototype._resize=function(a){var b=parseInt(a.clientX),c=parseInt(a.clientY);this.container.style.width=this.container.offsetWidth-(b-this.prop.mouse_x)+"px",this.prop.mouse_x=b,this.prop.mouse_y=c},n.prototype=Object.create(f.prototype),n.prototype.constructor=n,n.className="psv-tooltip",n.publicMethods=["showTooltip","hideTooltip","isTooltipVisible"],n.leftMap={0:"left",.5:"center",1:"right"},n.topMap={0:"top",.5:"center",1:"bottom"},n.prototype.create=function(){f.prototype.create.call(this),this.container.innerHTML='
',this.container.style.top="-1000px",this.container.style.left="-1000px",this.content=this.container.querySelector(".psv-tooltip-content"),this.arrow=this.container.querySelector(".psv-tooltip-arrow"),this.psv.on("render",this)},n.prototype.destroy=function(){this.psv.off("render",this),delete this.config,f.prototype.destroy.call(this)},n.prototype.handleEvent=function(a){switch(a.type){case"render":this.hideTooltip()}},n.prototype.isTooltipVisible=function(){return this.container.classList.contains("psv-tooltip--visible")},n.prototype.showTooltip=function(a){this.timeout&&(window.clearTimeout(this.timeout),this.timeout=null);var b=this.isTooltipVisible(),c=this.container,d=this.content,e=this.arrow;if(a.position||(a.position=["top","center"]),a.marker||(a.marker={width:0,height:0}),"string"==typeof a.position){var f=x.parsePosition(a.position);if(!(f.left in n.leftMap&&f.top in n.topMap))throw new w('unable to parse tooltip position "'+tooltip.position+'"');a.position=[n.topMap[f.top],n.leftMap[f.left]]}if("center"==a.position[0]&&"center"==a.position[1])throw new w('unable to parse tooltip position "center center"');if(b)for(var g=c.classList.length-1;g>=0;g--){var h=c.classList.item(g);"psv-tooltip"!=h&&"visible"!=h&&c.classList.remove(h)}else c.className="psv-tooltip";a.className&&x.addClasses(c,a.className),d.innerHTML=a.content,c.style.top="0px",c.style.left="0px";var i=c.getBoundingClientRect(),j={posClass:a.position.slice(),width:i.right-i.left,height:i.bottom-i.top,top:0,left:0,arrow_top:0,arrow_left:0};this._computeTooltipPosition(j,a);var k=!1;if(j.topthis.psv.prop.size.height-this.config.offset&&(j.posClass[0]="top",k=!0),j.leftthis.psv.prop.size.width-this.config.offset&&(j.posClass[1]="left",k=!0),k&&this._computeTooltipPosition(j,a),c.style.top=j.top+"px",c.style.left=j.left+"px",e.style.top=j.arrow_top+"px",e.style.left=j.arrow_left+"px",c.classList.add("psv-tooltip--"+j.posClass.join("-")),!b){var l=this;this.timeout=window.setTimeout(function(){c.classList.add("psv-tooltip--visible"),l.psv.trigger("show-tooltip"),l.timeout=null},this.config.delay)}},n.prototype.hideTooltip=function(){if(this.timeout&&(window.clearTimeout(this.timeout),this.timeout=null),this.isTooltipVisible()){this.container.classList.remove("psv-tooltip--visible"),this.psv.trigger("hide-tooltip");var a=this;this.timeout=window.setTimeout(function(){a.content.innerHTML=null,a.container.style.top="-1000px",a.container.style.left="-1000px",a.timeout=null},this.config.delay)}},n.prototype._computeTooltipPosition=function(a,b){var c=!1;switch(a.posClass[0]){case"bottom":a.top=b.top+b.marker.height+this.config.offset+this.config.arrow_size,a.arrow_top=2*-this.config.arrow_size,c=!0;break;case"center":a.top=b.top+b.marker.height/2-a.height/2,a.arrow_top=a.height/2-this.config.arrow_size;break;case"top":a.top=b.top-a.height-this.config.offset-this.config.arrow_size,a.arrow_top=a.height,c=!0}switch(a.posClass[1]){case"right":c?(a.left=b.left+b.marker.width/2-this.config.offset-this.config.arrow_size,a.arrow_left=this.config.offset):(a.left=b.left+b.marker.width+this.config.offset+this.config.arrow_size,a.arrow_left=2*-this.config.arrow_size);break;case"center":a.left=b.left+b.marker.width/2-a.width/2,a.arrow_left=a.width/2-this.config.arrow_size;break;case"left":c?(a.left=b.left-a.width+b.marker.width/2+this.config.offset+this.config.arrow_size,a.arrow_left=a.width-this.config.offset-2*this.config.arrow_size):(a.left=b.left-a.width-this.config.offset-this.config.arrow_size,a.arrow_left=a.width)}},o.prototype=Object.create(f.prototype),o.prototype.constructor=o,o.prototype.create=function(){f.prototype.create.call(this),this.constructor.icon&&this.setIcon(this.constructor.icon),this.container.addEventListener("click",function(){this.enabled&&this._onClick()}.bind(this))},o.prototype.setIcon=function(a,b){b||(b=this.container),a?(b.innerHTML=e.ICONS[a],b.querySelector("svg").setAttribute("class","psv-button-svg")):b.innerHTML=""},o.prototype.toggleActive=function(a){a=x.toggleClass(this.container,"psv-button--active",a),this.constructor.iconActive&&this.setIcon(a?this.constructor.iconActive:this.constructor.icon)},o.prototype.disable=function(){this.container.classList.add("psv-button--disabled"),this.enabled=!1},o.prototype.enable=function(){this.container.classList.remove("psv-button--disabled"),this.enabled=!0},o.prototype._onClick=function(){},p.prototype=Object.create(o.prototype),p.prototype.constructor=p,p.id="autorotate",p.className="psv-button psv-button--hover-scale psv-autorotate-button",p.icon="play.svg",p.iconActive="play-active.svg",p.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.autorotate,this.psv.on("autorotate",this)},p.prototype.destroy=function(){this.psv.off("autorotate",this),o.prototype.destroy.call(this)},p.prototype.handleEvent=function(a){switch(a.type){case"autorotate":this.toggleActive(a.args[0])}},p.prototype._onClick=function(){this.psv.toggleAutorotate()},q.prototype=Object.create(o.prototype),q.prototype.constructor=q,q.className="psv-button psv-custom-button",q.prototype.create=function(){o.prototype.create.call(this),this.config.className&&x.addClasses(this.container,this.config.className),this.config.title&&(this.container.title=this.config.title),this.config.content&&(this.container.innerHTML=this.config.content),this.config.enabled!==!1&&this.config.disabled!==!0||this.disable(),this.config.visible!==!1&&this.config.hidden!==!0||this.hide()},q.prototype.destroy=function(){delete this.config,o.prototype.destroy.call(this)},q.prototype._onClick=function(){this.config.onClick&&this.config.onClick.apply(this.psv)},r.prototype=Object.create(o.prototype),r.prototype.constructor=r,r.id="download",r.className="psv-button psv-button--hover-scale psv-download-button",r.icon="download.svg",r.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.download},r.prototype._onClick=function(){var a=document.createElement("a");a.href=this.psv.config.panorama,a.download=this.psv.config.panorama,this.psv.container.appendChild(a),a.click()},s.prototype=Object.create(o.prototype),s.prototype.constructor=s,s.id="fullscreen",s.className="psv-button psv-button--hover-scale psv-fullscreen-button",s.icon="fullscreen-in.svg",s.iconActive="fullscreen-out.svg",s.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.fullscreen,this.psv.on("fullscreen-updated",this)},s.prototype.destroy=function(){this.psv.off("fullscreen-updated",this),o.prototype.destroy.call(this)},s.prototype.handleEvent=function(a){switch(a.type){case"fullscreen-updated":this.toggleActive(a.args[0])}},s.prototype._onClick=function(){this.psv.toggleFullscreen()},t.prototype=Object.create(o.prototype),t.prototype.constructor=t,t.id="gyroscope",t.className="psv-button psv-button--hover-scale psv-gyroscope-button",t.icon="compass.svg",t.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.gyroscope,e.SYSTEM.deviceOrientationSupported.promise.then(this._onAvailabilityChange.bind(this,!0),this._onAvailabilityChange.bind(this,!1)),this.hide(),this.psv.on("gyroscope-updated",this)},t.prototype.destroy=function(){this.psv.off("gyroscope-updated",this),o.prototype.destroy.call(this)},t.prototype.handleEvent=function(a){switch(a.type){case"gyroscope-updated":this.toggleActive(a.args[0])}},t.prototype._onClick=function(){this.psv.toggleGyroscopeControl()},t.prototype._onAvailabilityChange=function(a){if(a){if(!x.checkTHREE("DeviceOrientationControls"))throw new w("Missing Three.js components: DeviceOrientationControls. Get them from three.js-examples package.");this.show()}},u.prototype=Object.create(o.prototype),u.prototype.constructor=u,u.id="markers",u.className="psv-button psv-button--hover-scale psv-markers-button",u.icon="pin.svg",u.publicMethods=["toggleMarkersList","showMarkersList","hideMarkersList"],u.prototype.create=function(){o.prototype.create.call(this),this.container.title=this.psv.config.lang.markers,this.psv.on("open-panel",this),this.psv.on("close-panel",this)},u.prototype.destroy=function(){this.psv.off("open-panel",this),this.psv.off("close-panel",this),delete this.prop,o.prototype.destroy.call(this)},u.prototype.handleEvent=function(a){switch(a.type){case"open-panel":this._onPanelOpened();break;case"close-panel":this._onPanelClosed()}},u.prototype._onClick=function(){this.toggleMarkersList()},u.prototype.toggleMarkersList=function(){this.prop.panelOpened?this.hideMarkersList():this.showMarkersList()},u.prototype.showMarkersList=function(){var a=[];for(var b in this.psv.hud.markers)a.push(this.psv.hud.markers[b]);var c=this.psv.config.templates.markersList({markers:this.psv.change("render-markers-list",a),config:this.psv.config});this.prop.panelOpening=!0,this.psv.panel.showPanel(c,!0),this.psv.panel.container.querySelector(".psv-markers-list").addEventListener("click",this._onClickItem.bind(this))},u.prototype.hideMarkersList=function(){this.prop.panelOpened&&this.psv.panel.hidePanel()},u.prototype._onClickItem=function(a){var b;a.target&&(b=x.getClosest(a.target,"li"))&&b.dataset.psvMarker&&(this.psv.hud.gotoMarker(b.dataset.psvMarker,1e3),this.psv.panel.hidePanel())},u.prototype._onPanelOpened=function(){this.prop.panelOpening?(this.prop.panelOpening=!1,this.prop.panelOpened=!0):this.prop.panelOpened=!1,this.toggleActive(this.prop.panelOpened)},u.prototype._onPanelClosed=function(){this.prop.panelOpened=!1,this.prop.panelOpening=!1,this.toggleActive(this.prop.panelOpened)},v.prototype=Object.create(o.prototype), +v.prototype.constructor=v,v.id="zoom",v.className="psv-button psv-zoom-button",v.prototype.create=function(){o.prototype.create.call(this);var a=document.createElement("div");a.className="psv-zoom-button-minus",a.title=this.psv.config.lang.zoomOut,this.setIcon("zoom-out.svg",a),this.container.appendChild(a);var b=document.createElement("div");b.className="psv-zoom-button-range",this.container.appendChild(b),this.zoom_range=document.createElement("div"),this.zoom_range.className="psv-zoom-button-line",this.zoom_range.title=this.psv.config.lang.zoom,b.appendChild(this.zoom_range),this.zoom_value=document.createElement("div"),this.zoom_value.className="psv-zoom-button-handle",this.zoom_value.title=this.psv.config.lang.zoom,this.zoom_range.appendChild(this.zoom_value);var c=document.createElement("div");c.className="psv-zoom-button-plus",c.title=this.psv.config.lang.zoomIn,this.setIcon("zoom-in.svg",c),this.container.appendChild(c),this.zoom_range.addEventListener("mousedown",this),this.zoom_range.addEventListener("touchstart",this),this.psv.container.addEventListener("mousemove",this),this.psv.container.addEventListener("touchmove",this),this.psv.container.addEventListener("mouseup",this),this.psv.container.addEventListener("touchend",this),a.addEventListener("mousedown",this._zoomOut.bind(this)),c.addEventListener("mousedown",this._zoomIn.bind(this)),this.psv.on("zoom-updated",this),this.psv.once("ready",function(){this._moveZoomValue(this.psv.prop.zoom_lvl)}.bind(this))},v.prototype.destroy=function(){this.psv.container.removeEventListener("mousemove",this),this.psv.container.removeEventListener("touchmove",this),this.psv.container.removeEventListener("mouseup",this),this.psv.container.removeEventListener("touchend",this),delete this.zoom_range,delete this.zoom_value,this.psv.off("zoom-updated",this),o.prototype.destroy.call(this)},v.prototype.handleEvent=function(a){switch(a.type){case"mousedown":this._initZoomChangeWithMouse(a);break;case"touchstart":this._initZoomChangeByTouch(a);break;case"mousemove":this._changeZoomWithMouse(a);break;case"touchmove":this._changeZoomByTouch(a);break;case"mouseup":this._stopZoomChange(a);break;case"touchend":this._stopZoomChange(a);break;case"zoom-updated":this._moveZoomValue(a.args[0])}},v.prototype._moveZoomValue=function(a){this.zoom_value.style.left=a/100*this.zoom_range.offsetWidth-this.zoom_value.offsetWidth/2+"px"},v.prototype._initZoomChangeWithMouse=function(a){this.enabled&&(this.prop.mousedown=!0,this._changeZoom(a.clientX))},v.prototype._initZoomChangeByTouch=function(a){this.enabled&&(this.prop.mousedown=!0,this._changeZoom(a.changedTouches[0].clientX))},v.prototype._zoomIn=function(){this.enabled&&(this.prop.buttondown=!0,this.psv.zoomIn(),window.setTimeout(this._startLongPressInterval.bind(this,1),200))},v.prototype._zoomOut=function(){this.enabled&&(this.prop.buttondown=!0,this.psv.zoomOut(),window.setTimeout(this._startLongPressInterval.bind(this,-1),200))},v.prototype._startLongPressInterval=function(a){this.prop.buttondown&&(this.prop.longPressInterval=window.setInterval(function(){this.psv.zoom(this.psv.prop.zoom_lvl+a)}.bind(this),50))},v.prototype._stopZoomChange=function(){this.enabled&&(window.clearInterval(this.prop.longPressInterval),this.prop.longPressInterval=null,this.prop.mousedown=!1,this.prop.buttondown=!1)},v.prototype._changeZoomWithMouse=function(a){this.enabled&&(a.preventDefault(),this._changeZoom(a.clientX))},v.prototype._changeZoomByTouch=function(a){this.enabled&&(a.preventDefault(),this._changeZoom(a.changedTouches[0].clientX))},v.prototype._changeZoom=function(a){if(this.prop.mousedown){var b=parseInt(a)-this.zoom_range.getBoundingClientRect().left,c=b/this.zoom_range.offsetWidth*100;this.psv.zoom(c)}},w.prototype=Object.create(Error.prototype),w.prototype.name="PSVError",w.prototype.constructor=w;var x={};return x.TwoPI=2*Math.PI,x.HalfPI=Math.PI/2,x.checkTHREE=function(b){for(var c=0,d=arguments.length;c(.*)"))?c[1]:null!==(c=a.match("GPano:"+b+'="(.*?)"'))?c[1]:null},x.isFullscreenEnabled=function(a){return(document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement)===a},x.requestFullscreen=function(a){(a.requestFullscreen||a.mozRequestFullScreen||a.webkitRequestFullscreen||a.msRequestFullscreen).call(a)},x.exitFullscreen=function(){(document.exitFullscreen||document.mozCancelFullScreen||document.webkitExitFullscreen||document.msExitFullscreen).call(document)},x.getStyle=function(a,b){return window.getComputedStyle(a,null)[b]},x.parsePosition=function(a){if(!a)return{top:.5,left:.5};if("object"==typeof a)return a;var b=a.toLocaleLowerCase().split(" ").slice(0,2);1===b.length&&(b=void 0!==x.parsePosition.positions[b[0]]?[b[0],"center"]:[b[0],b[0]]);var c="left"!=b[1]&&"right"!=b[1]&&"top"!=b[0]&&"bottom"!=b[0];b=b.map(function(a){return x.parsePosition.positions[a]||a}),c||b.reverse();var d=b.join(" ").match(/^([0-9.]+)% ([0-9.]+)%$/);return d?{left:d[1]/100,top:d[2]/100}:{top:.5,left:.5}},x.parsePosition.positions={top:"0%",bottom:"100%",left:"0%",right:"100%",center:"50%"},x.parseSpeed=function(a){if("string"==typeof a){a=a.toString().trim();var b=parseFloat(a.replace(/^(-?[0-9]+(?:\.[0-9]*)?).*$/,"$1")),c=a.replace(/^-?[0-9]+(?:\.[0-9]*)?(.*)$/,"$1").trim();switch(c.match(/(pm|per minute)$/)&&(b/=60),c){case"dpm":case"degrees per minute":case"dps":case"degrees per second":a=b*Math.PI/180;break;case"radians per minute":case"radians per second":a=b;break;case"rpm":case"revolutions per minute":case"rps":case"revolutions per second":a=b*x.TwoPI;break;default:throw new w('unknown speed unit "'+c+'"')}}return a},x.parseAngle=function(a,b){if("string"==typeof a){var c=a.toLowerCase().trim().match(/^(-?[0-9]+(?:\.[0-9]*)?)(.*)$/);if(!c)throw new w('unknown angle "'+a+'"');var d=parseFloat(c[1]),e=c[2];if(e)switch(e){case"deg":case"degs":a=d/180*Math.PI;break;case"rad":case"rads":a=d;break;default:throw new w('unknown angle unit "'+e+'"')}}return b!==!1&&(void 0===b&&(b=0),a=(a-b)%x.TwoPI,a<0&&(a=x.TwoPI+a),a+=b),a},x.animation=function(a){function c(b){if(d.promise.getStatus()!==-1){null===e&&(e=b);var f,g=(b-e)/a.duration,h={};if(g<1){for(f in a.properties)h[f]=a.properties[f].start+(a.properties[f].end-a.properties[f].start)*a.easing(g);a.onTick(h,g),window.requestAnimationFrame(c)}else{for(f in a.properties)h[f]=a.properties[f].end;a.onTick(h,1),a.onDone&&a.onDone(),d.resolve()}}}var d=b(),e=null;a.easing&&"string"!=typeof a.easing||(a.easing=x.animation.easings[a.easing||"linear"]),void 0!==a.delay?window.setTimeout(function(){window.requestAnimationFrame(c)},a.delay):window.requestAnimationFrame(c);var f=d.promise;return f.cancel=function(){a.onCancel&&a.onCancel(),d.reject()},f},x.animation.easings={linear:function(a){return a},inQuad:function(a){return a*a},outQuad:function(a){return a*(2-a)},inOutQuad:function(a){return a<.5?2*a*a:-1+(4-2*a)*a},inCubic:function(a){return a*a*a},outCubic:function(a){return--a*a*a+1},inOutCubic:function(a){return a<.5?4*a*a*a:(a-1)*(2*a-2)*(2*a-2)+1},inQuart:function(a){return a*a*a*a},outQuart:function(a){return 1- --a*a*a*a},inOutQuart:function(a){return a<.5?8*a*a*a*a:1-8*--a*a*a*a},inQuint:function(a){return a*a*a*a*a},outQuint:function(a){return 1+--a*a*a*a*a},inOutQuint:function(a){return a<.5?16*a*a*a*a*a:1+16*--a*a*a*a*a},inSine:function(a){return 1-Math.cos(a*(Math.PI/2))},outSine:function(a){return Math.sin(a*(Math.PI/2))},inOutSine:function(a){return.5-.5*Math.cos(Math.PI*a)},inExpo:function(a){return Math.pow(2,10*(a-1))},outExpo:function(a){return 1-Math.pow(2,-10*a)},inOutExpo:function(a){return a=2*a-1,a<0?.5*Math.pow(2,10*a):1-.5*Math.pow(2,-10*a)},inCirc:function(a){return 1-Math.sqrt(1-a*a)},outCirc:function(a){return a--,Math.sqrt(1-a*a)},inOutCirc:function(a){return a*=2,a<1?.5-.5*Math.sqrt(1-a*a):.5+.5*Math.sqrt(1-(a-=2)*a)}},x.throttle=function(a,b){var c,d,e,f=null,g=0,h=function(){g=Date.now(),f=null,e=a.apply(c,d),f||(c=d=null)};return function(){var i=Date.now();g||(g=i);var j=b-(i-g);return c=this,d=arguments,j<=0||j>b?(f&&(clearTimeout(f),f=null),g=i,e=a.apply(c,d),f||(c=d=null)):f||(f=setTimeout(h,j)),e}},x.isPlainObject=function(a){if("object"==typeof a&&null!==a){if("function"==typeof Object.getPrototypeOf){var b=Object.getPrototypeOf(a);return b===Object.prototype||null===b}return"[object Object]"==Object.prototype.toString.call(a)}return!1},x.deepmerge=function(a,b){var c=b;return function d(a,b){return Array.isArray(b)?(a&&Array.isArray(a)?a.length=0:a=[],b.forEach(function(b,c){a[c]=d(null,b)})):"object"==typeof b?(a&&!Array.isArray(a)||(a={}),Object.keys(b).forEach(function(e){"object"==typeof b[e]&&b[e]&&x.isPlainObject(b[e])?b[e]!=c&&(a[e]?d(a[e],b[e]):a[e]=d(null,b[e])):a[e]=b[e]})):a=b,a}(a,b)},x.clone=function(a){return x.deepmerge(null,a)},a.GodraysShader={uniforms:{tDiffuse:{type:"t",value:0,texture:null},fX:{type:"f",value:.5},fY:{type:"f",value:.5},fExposure:{type:"f",value:.6},fDecay:{type:"f",value:.93},fDensity:{type:"f",value:.96},fWeight:{type:"f",value:.4},fClamp:{type:"f",value:1}},vertexShader:["varying vec2 vUv;","void main()","{","vUv = vec2( uv.x, uv.y );","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["varying vec2 vUv;","uniform sampler2D tDiffuse;","uniform float fX;","uniform float fY;","uniform float fExposure;","uniform float fDecay;","uniform float fDensity;","uniform float fWeight;","uniform float fClamp;","const int iSamples = 20;","void main()","{","vec2 deltaTextCoord = vec2(vUv - vec2(fX,fY));","deltaTextCoord *= 1.0 / float(iSamples) * fDensity;","vec2 coord = vUv;","float illuminationDecay = 1.0;","vec4 FragColor = vec4(0.0);","for(int i=0; i < iSamples ; i++)","{","coord -= deltaTextCoord;","vec4 texel = texture2D(tDiffuse, coord);","texel *= illuminationDecay * fWeight;","FragColor += texel;","illuminationDecay *= fDecay;","}","FragColor *= fExposure;","FragColor = clamp(FragColor, 0.0, fClamp);","gl_FragColor = FragColor;","}"].join("\n")},function(a){if(a.requestAnimationFrame=a.requestAnimationFrame||a.mozRequestAnimationFrame||a.webkitRequestAnimationFrame||a.msRequestAnimationFrame,a.cancelAnimationFrame=a.cancelAnimationFrame||a.mozCancelAnimationFrame||a.webkitCancelAnimationFrame||a.msCancelAnimationFrame,!a.requestAnimationFrame){var b,c=[],d=[],e=0;a.requestAnimationFrame=function(a){return c.push([++e,a]),b||(b=setInterval(function(){if(c.length){var a=+new Date,e=d;for(d=c,c=e;d.length;)d.shift()[1](a)}else clearInterval(b),b=void 0},20)),e},a.cancelAnimationFrame=function(a){var b,e;for(b=0,e=c.length;b - - - - - - - - + + + + + + + +