From e70525f51b3ac41652b152ccc01496d23db755df Mon Sep 17 00:00:00 2001 From: malangfox Date: Thu, 16 Jun 2022 15:43:01 +0900 Subject: [PATCH] chore(release): Release 3.6.3 --- .gitignore | 2 +- dist/PanoViewer/view360.panoviewer.js | 6679 +++++++ dist/PanoViewer/view360.panoviewer.js.map | 1 + dist/PanoViewer/view360.panoviewer.min.js | 10 + dist/PanoViewer/view360.panoviewer.min.js.map | 1 + dist/PanoViewer/view360.panoviewer.pkgd.js | 14123 +++++++++++++++ .../PanoViewer/view360.panoviewer.pkgd.js.map | 1 + .../PanoViewer/view360.panoviewer.pkgd.min.js | 10 + .../view360.panoviewer.pkgd.min.js.map | 1 + dist/SpinViewer/view360.spinviewer.js | 768 + dist/SpinViewer/view360.spinviewer.js.map | 1 + dist/SpinViewer/view360.spinviewer.min.js | 10 + dist/SpinViewer/view360.spinviewer.min.js.map | 1 + dist/SpinViewer/view360.spinviewer.pkgd.js | 4655 +++++ .../SpinViewer/view360.spinviewer.pkgd.js.map | 1 + .../SpinViewer/view360.spinviewer.pkgd.min.js | 10 + .../view360.spinviewer.pkgd.min.js.map | 1 + dist/view360.esm.js | 7366 ++++++++ dist/view360.js | 7411 ++++++++ dist/view360.js.map | 1 + dist/view360.min.js | 10 + dist/view360.min.js.map | 1 + dist/view360.pkgd.js | 14855 ++++++++++++++++ dist/view360.pkgd.js.map | 1 + dist/view360.pkgd.min.js | 10 + dist/view360.pkgd.min.js.map | 1 + package.json | 2 +- 27 files changed, 55931 insertions(+), 2 deletions(-) create mode 100644 dist/PanoViewer/view360.panoviewer.js create mode 100644 dist/PanoViewer/view360.panoviewer.js.map create mode 100644 dist/PanoViewer/view360.panoviewer.min.js create mode 100644 dist/PanoViewer/view360.panoviewer.min.js.map create mode 100644 dist/PanoViewer/view360.panoviewer.pkgd.js create mode 100644 dist/PanoViewer/view360.panoviewer.pkgd.js.map create mode 100644 dist/PanoViewer/view360.panoviewer.pkgd.min.js create mode 100644 dist/PanoViewer/view360.panoviewer.pkgd.min.js.map create mode 100644 dist/SpinViewer/view360.spinviewer.js create mode 100644 dist/SpinViewer/view360.spinviewer.js.map create mode 100644 dist/SpinViewer/view360.spinviewer.min.js create mode 100644 dist/SpinViewer/view360.spinviewer.min.js.map create mode 100644 dist/SpinViewer/view360.spinviewer.pkgd.js create mode 100644 dist/SpinViewer/view360.spinviewer.pkgd.js.map create mode 100644 dist/SpinViewer/view360.spinviewer.pkgd.min.js create mode 100644 dist/SpinViewer/view360.spinviewer.pkgd.min.js.map create mode 100644 dist/view360.esm.js create mode 100644 dist/view360.js create mode 100644 dist/view360.js.map create mode 100644 dist/view360.min.js create mode 100644 dist/view360.min.js.map create mode 100644 dist/view360.pkgd.js create mode 100644 dist/view360.pkgd.js.map create mode 100644 dist/view360.pkgd.min.js create mode 100644 dist/view360.pkgd.min.js.map diff --git a/.gitignore b/.gitignore index b5a7a994f..be5ceaef0 100644 --- a/.gitignore +++ b/.gitignore @@ -207,7 +207,7 @@ report/ temp/ demo/_data/version.yml demo/release/ -dist/ + packages/**/*/dist/ declaration/ .jekyll-cache/ diff --git a/dist/PanoViewer/view360.panoviewer.js b/dist/PanoViewer/view360.panoviewer.js new file mode 100644 index 000000000..af11f0393 --- /dev/null +++ b/dist/PanoViewer/view360.panoviewer.js @@ -0,0 +1,6679 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@egjs/component'), require('promise-polyfill'), require('@egjs/agent'), require('@egjs/axes'), require('gl-matrix'), require('@egjs/imready')) : + typeof define === 'function' && define.amd ? define(['@egjs/component', 'promise-polyfill', '@egjs/agent', '@egjs/axes', 'gl-matrix', '@egjs/imready'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.eg = global.eg || {}, global.eg.view360 = factory(global.eg.Component, global.Promise, global.eg.agent, global.eg.Axes, global.glMatrix, global.eg.ImReady))); +}(this, (function (Component, Promise$1, agent$1, Axes, glMatrix, ImReady) { 'use strict'; + + var VERSION = "3.6.3"; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); + }; + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + function __generator(thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }, + f, + y, + t, + g; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; + + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + + switch (op[0]) { + case 0: + case 1: + t = op; + break; + + case 4: + _.label++; + return { + value: op[1], + done: false + }; + + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + + case 7: + op = _.ops.pop(); + + _.trys.pop(); + + continue; + + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + + if (t && _.label < t[2]) { + _.label = t[2]; + + _.ops.push(op); + + break; + } + + if (t[2]) _.ops.pop(); + + _.trys.pop(); + + continue; + } + + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; + } + } + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + + return ar; + } + + var merge = function (target) { + var srcs = []; + + for (var _i = 1; _i < arguments.length; _i++) { + srcs[_i - 1] = arguments[_i]; + } + + srcs.forEach(function (source) { + Object.keys(source).forEach(function (key) { + var value = source[key]; + + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = __spread(target[key], value); + } else { + target[key] = value; + } + }); + }); + return target; + }; + var toImageElement = function (image) { + var images = image instanceof Array ? image : [image]; + var parsedImages = images.map(function (img) { + var imgEl = img; + + if (typeof img === "string") { + imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = img; + } + + return imgEl; + }); + return parsedImages.length === 1 ? parsedImages[0] : parsedImages; + }; + var toVideoElement = function (videoCandidate) { + if (videoCandidate instanceof HTMLVideoElement) { + return videoCandidate; + } else { + // url + var video_1 = document.createElement("video"); + video_1.setAttribute("crossorigin", "anonymous"); + video_1.setAttribute("webkit-playsinline", ""); + video_1.setAttribute("playsinline", ""); + + if (videoCandidate instanceof Array) { + videoCandidate.forEach(function (v) { + return appendSourceElement(video_1, v); + }); + } else { + appendSourceElement(video_1, videoCandidate); + } + + var sourceCount = video_1.querySelectorAll("source").length; + + if (sourceCount > 0) { + if (video_1.readyState < 1) { + video_1.load(); + } + } + + return video_1; + } + }; + /** + * + * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src} + */ + + var appendSourceElement = function (video, videoUrl) { + var videoSrc; + var videoType; + + if (typeof videoUrl === "object") { + videoSrc = videoUrl.src; + videoType = videoUrl.type; + } else if (typeof videoUrl === "string") { + videoSrc = videoUrl; + } + + if (!videoSrc) { + return false; + } + + var sourceElement = document.createElement("source"); + sourceElement.src = videoSrc; + + if (videoType) { + sourceElement.type = videoType; + } + + video.appendChild(sourceElement); + }; + + /* eslint-disable @typescript-eslint/no-implied-eval */ + /* eslint-disable no-new-func, no-nested-ternary */ + + var win = typeof window !== "undefined" && window.Math === Math ? window : typeof self !== "undefined" && self.Math === Math ? self : Function("return this")(); + /* eslint-enable no-new-func, no-nested-ternary */ + + var doc = win.document; + var nav = win.navigator; + var agent = agent$1(); + var osName = agent.os.name; + var browserName = agent.browser.name; + var IS_IOS = osName === "ios"; + var IS_SAFARI_ON_DESKTOP = osName === "mac" && browserName === "safari"; + + /* eslint-disable @typescript-eslint/naming-convention */ + win.Float32Array = typeof win.Float32Array !== "undefined" ? win.Float32Array : win.Array; + var Float32Array$1 = win.Float32Array; + var getComputedStyle = win.getComputedStyle; + var userAgent = win.navigator && win.navigator.userAgent; + var SUPPORT_TOUCH = ("ontouchstart" in win); + var SUPPORT_DEVICEMOTION = ("ondevicemotion" in win); + var DeviceMotionEvent = win.DeviceMotionEvent; + var devicePixelRatio = win.devicePixelRatio; + + var TRANSFORM = function () { + var _a; + + var docStyle = (_a = doc === null || doc === void 0 ? void 0 : doc.documentElement.style) !== null && _a !== void 0 ? _a : {}; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in docStyle) { + return target[i]; + } + } + + return ""; + }(); // check for will-change support + + + var SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports && win.CSS.supports("will-change", "transform"); + var WEBXR_SUPPORTED = false; + + var checkXRSupport = function () { + var navigator = window.navigator; + + if (!navigator.xr) { + return; + } + + if (navigator.xr.isSessionSupported) { + navigator.xr.isSessionSupported("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } else if (navigator.xr.supportsSession) { + navigator.xr.supportsSession("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } + }; + + /** + * Original Code + * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js + * Math Util + * modified by egjs + */ + + var quatToVec3 = function (quaternion) { + var baseV = glMatrix.vec3.fromValues(0, 0, 1); + glMatrix.vec3.transformQuat(baseV, baseV, quaternion); + return baseV; + }; + + var toDegree = function (a) { + return a * 180 / Math.PI; + }; + + var util = {}; + + util.isPowerOfTwo = function (n) { + return n && (n & n - 1) === 0; + }; + + util.extractPitchFromQuat = function (quaternion) { + var baseV = quatToVec3(quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + }; + + util.hypot = Math.hypot || function (x, y) { + return Math.sqrt(x * x + y * y); + }; // implement reference + // the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식 + // calculating angle between two vectors : http://darkpgmr.tistory.com/121 + + + var ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] + }; + + var getRotationDelta = function (prevQ, curQ, rotateKind) { + var targetAxis = glMatrix.vec3.fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + var meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + var prevQuaternion = glMatrix.quat.clone(prevQ); + var curQuaternion = glMatrix.quat.clone(curQ); + glMatrix.quat.normalize(prevQuaternion, prevQuaternion); + glMatrix.quat.normalize(curQuaternion, curQuaternion); + var prevPoint = glMatrix.vec3.fromValues(0, 0, 1); + var curPoint = glMatrix.vec3.fromValues(0, 0, 1); + glMatrix.vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + glMatrix.vec3.transformQuat(curPoint, curPoint, curQuaternion); + glMatrix.vec3.transformQuat(targetAxis, targetAxis, curQuaternion); + var rotateDistance = glMatrix.vec3.dot(targetAxis, glMatrix.vec3.cross(glMatrix.vec3.create(), prevPoint, curPoint)); + var rotateDirection = rotateDistance > 0 ? 1 : -1; // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + + var meshPoint2 = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + var meshPoint3; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = glMatrix.vec3.fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = glMatrix.vec3.fromValues(rotateDirection, 0, 0); + } + + glMatrix.vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion); + glMatrix.vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion); + var vecU = meshPoint2; + var vecV = meshPoint3; + var vecN = glMatrix.vec3.create(); + glMatrix.vec3.cross(vecN, vecU, vecV); + glMatrix.vec3.normalize(vecN, vecN); + var coefficientA = vecN[0]; + var coefficientB = vecN[1]; + var coefficientC = vecN[2]; // const coefficientD = -1 * vec3.dot(vecN, meshPoint1); + // a point on the plane + + curPoint = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + glMatrix.vec3.transformQuat(curPoint, curPoint, curQuaternion); // a point should project on the plane + + prevPoint = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + glMatrix.vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); // distance between prevPoint and the plane + + var distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + var projectedPrevPoint = glMatrix.vec3.create(); + glMatrix.vec3.subtract(projectedPrevPoint, prevPoint, glMatrix.vec3.scale(glMatrix.vec3.create(), vecN, distance)); + var trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (glMatrix.vec3.length(projectedPrevPoint) * glMatrix.vec3.length(curPoint)); // defensive block + + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + + var theta = Math.acos(trigonometricRatio); + var crossVec = glMatrix.vec3.cross(glMatrix.vec3.create(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + var thetaDirection; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + + var deltaRadian = theta * thetaDirection * rotateDirection; + return toDegree(deltaRadian); + }; + + var angleBetweenVec2 = function (v1, v2) { + var det = v1[0] * v2[1] - v2[0] * v1[1]; + var theta = -Math.atan2(det, glMatrix.vec2.dot(v1, v2)); + return theta; + }; + + util.yawOffsetBetween = function (viewDir, targetDir) { + var viewDirXZ = glMatrix.vec2.fromValues(viewDir[0], viewDir[2]); + var targetDirXZ = glMatrix.vec2.fromValues(targetDir[0], targetDir[2]); + glMatrix.vec2.normalize(viewDirXZ, viewDirXZ); + glMatrix.vec2.normalize(targetDirXZ, targetDirXZ); + var theta = -angleBetweenVec2(viewDirXZ, targetDirXZ); + return theta; + }; + + util.sign = function (x) { + return Math.sign ? Math.sign(x) : Number(x > 0) - Number(x < 0) || +x; + }; + + util.toDegree = toDegree; + util.getRotationDelta = getRotationDelta; + util.angleBetweenVec2 = angleBetweenVec2; + + var toAxis = function (source, offset) { + return offset.reduce(function (acc, v, i) { + if (source[i]) { + acc[source[i]] = v; + } + + return acc; + }, {}); + }; + + /** + * Returns a number value indiciating the version of Chrome being used, + * or otherwise `null` if not on Chrome. + * + * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19 + */ + + /** + * In Chrome m65, `devicemotion` events are broken but subsequently fixed + * in 65.0.3325.148. Since many browsers use Chromium, ensure that + * we scope this detection by branch and build numbers to provide + * a proper fallback. + * https://github.com/immersive-web/webvr-polyfill/issues/307 + */ + + var version = -1; // It should not be null because it will be compared with number + + var branch = null; + var build = null; + var match = /Chrome\/([0-9]+)\.(?:[0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(userAgent); + + if (match) { + version = parseInt(match[1], 10); + branch = match[2]; + build = match[3]; + } + + var CHROME_VERSION = version; + var IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === "3325" && parseInt(build, 10) < 148; + var IS_ANDROID = /Android/i.test(userAgent); + var CONTROL_MODE_VR = 1; + var CONTROL_MODE_YAWPITCH = 2; + var TOUCH_DIRECTION_NONE = 1; + var TOUCH_DIRECTION_YAW = 2; + var TOUCH_DIRECTION_PITCH = 4; + var TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH; + /* Const for MovableCoord */ + + var MC_DECELERATION = 0.0014; + var MC_MAXIMUM_DURATION = 1000; + var MC_BIND_SCALE = [0.20, 0.20]; + var MAX_FIELD_OF_VIEW = 110; + var PAN_SCALE = 320; // const DELTA_THRESHOLD = 0.015; + + var YAW_RANGE_HALF = 180; + var PITCH_RANGE_HALF = 90; + var CIRCULAR_PITCH_RANGE_HALF = 180; + var GYRO_MODE = { + NONE: "none", + YAWPITCH: "yawPitch", + VR: "VR" + }; + + /* eslint-disable */ + var MathUtil = win.MathUtil || {}; + MathUtil.degToRad = Math.PI / 180; + MathUtil.radToDeg = 180 / Math.PI; // Some minimal math functionality borrowed from THREE.Math and stripped down + // for the purposes of this library. + + MathUtil.Vector2 = function (x, y) { + this.x = x || 0; + this.y = y || 0; + }; + + MathUtil.Vector2.prototype = { + constructor: MathUtil.Vector2, + set: function (x, y) { + this.x = x; + this.y = y; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + return this; + }, + subVectors: function (a, b) { + this.x = a.x - b.x; + this.y = a.y - b.y; + return this; + } + }; + + MathUtil.Vector3 = function (x, y, z) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + }; + + MathUtil.Vector3.prototype = { + constructor: MathUtil.Vector3, + set: function (x, y, z) { + this.x = x; + this.y = y; + this.z = z; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + return this; + }, + length: function () { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + }, + normalize: function () { + var scalar = this.length(); + + if (scalar !== 0) { + var invScalar = 1 / scalar; + this.multiplyScalar(invScalar); + } else { + this.x = 0; + this.y = 0; + this.z = 0; + } + + return this; + }, + multiplyScalar: function (scalar) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + }, + applyQuaternion: function (q) { + var x = this.x; + var y = this.y; + var z = this.z; + var qx = q.x; + var qy = q.y; + var qz = q.z; + var qw = q.w; // calculate quat * vector + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + + this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return this; + }, + dot: function (v) { + return this.x * v.x + this.y * v.y + this.z * v.z; + }, + crossVectors: function (a, b) { + var ax = a.x; + var ay = a.y; + var az = a.z; + var bx = b.x; + var by = b.y; + var bz = b.z; + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; + return this; + } + }; + + MathUtil.Quaternion = function (x, y, z, w) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w !== undefined ? w : 1; + }; + + MathUtil.Quaternion.prototype = { + constructor: MathUtil.Quaternion, + set: function (x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + return this; + }, + copy: function (quaternion) { + this.x = quaternion.x; + this.y = quaternion.y; + this.z = quaternion.z; + this.w = quaternion.w; + return this; + }, + setFromEulerXYZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + return this; + }, + setFromEulerYXZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + return this; + }, + setFromAxisAngle: function (axis, angle) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // assumes axis is normalized + var halfAngle = angle / 2; + var s = Math.sin(halfAngle); + this.x = axis.x * s; + this.y = axis.y * s; + this.z = axis.z * s; + this.w = Math.cos(halfAngle); + return this; + }, + multiply: function (q) { + return this.multiplyQuaternions(this, q); + }, + multiplyQuaternions: function (a, b) { + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + var qax = a.x; + var qay = a.y; + var qaz = a.z; + var qaw = a.w; + var qbx = b.x; + var qby = b.y; + var qbz = b.z; + var qbw = b.w; + this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; + return this; + }, + inverse: function () { + this.x *= -1; + this.y *= -1; + this.z *= -1; + this.normalize(); + return this; + }, + normalize: function () { + var l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + + if (l === 0) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 1; + } else { + l = 1 / l; + this.x = this.x * l; + this.y = this.y * l; + this.z = this.z * l; + this.w = this.w * l; + } + + return this; + }, + slerp: function (qb, t) { + if (t === 0) return this; + if (t === 1) return this.copy(qb); + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + + var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z; + + if (cosHalfTheta < 0) { + this.w = -qb.w; + this.x = -qb.x; + this.y = -qb.y; + this.z = -qb.z; + cosHalfTheta = -cosHalfTheta; + } else { + this.copy(qb); + } + + if (cosHalfTheta >= 1.0) { + this.w = w; + this.x = x; + this.y = y; + this.z = z; + return this; + } + + var halfTheta = Math.acos(cosHalfTheta); + var sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta); + + if (Math.abs(sinHalfTheta) < 0.001) { + this.w = 0.5 * (w + this.w); + this.x = 0.5 * (x + this.x); + this.y = 0.5 * (y + this.y); + this.z = 0.5 * (z + this.z); + return this; + } + + var ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta; + var ratioB = Math.sin(t * halfTheta) / sinHalfTheta; + this.w = w * ratioA + this.w * ratioB; + this.x = x * ratioA + this.x * ratioB; + this.y = y * ratioA + this.y * ratioB; + this.z = z * ratioA + this.z * ratioB; + return this; + }, + setFromUnitVectors: function () { + // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final + // assumes direction vectors vFrom and vTo are normalized + var v1; + var r; + var EPS = 0.000001; + return function (vFrom, vTo) { + if (v1 === undefined) v1 = new MathUtil.Vector3(); + r = vFrom.dot(vTo) + 1; + + if (r < EPS) { + r = 0; + + if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { + v1.set(-vFrom.y, vFrom.x, 0); + } else { + v1.set(0, -vFrom.z, vFrom.y); + } + } else { + v1.crossVectors(vFrom, vTo); + } + + this.x = v1.x; + this.y = v1.y; + this.z = v1.z; + this.w = r; + this.normalize(); + return this; + }; + }() + }; + + /* eslint-disable */ + + /* + * Copyright 2015 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + var _a; // tslint:disable: only-arrow-functions + var userAgent$1 = (_a = nav === null || nav === void 0 ? void 0 : nav.userAgent) !== null && _a !== void 0 ? _a : ""; + var Util = win.Util || {}; + Util.MIN_TIMESTEP = 0.001; + Util.MAX_TIMESTEP = 1; + + Util.base64 = function (mimeType, base64) { + return "data:" + mimeType + ";base64," + base64; + }; + + Util.clamp = function (value, min, max) { + return Math.min(Math.max(min, value), max); + }; + + Util.lerp = function (a, b, t) { + return a + (b - a) * t; + }; + + Util.isIOS = function () { + var isIOS = /iPad|iPhone|iPod/.test(nav === null || nav === void 0 ? void 0 : nav.platform); + return function () { + return isIOS; + }; + }(); + + Util.isWebViewAndroid = function () { + var isWebViewAndroid = userAgent$1.indexOf("Version") !== -1 && userAgent$1.indexOf("Android") !== -1 && userAgent$1.indexOf("Chrome") !== -1; + return function () { + return isWebViewAndroid; + }; + }(); + + Util.isSafari = function () { + var isSafari = /^((?!chrome|android).)*safari/i.test(userAgent$1); + return function () { + return isSafari; + }; + }(); + + Util.isFirefoxAndroid = function () { + var isFirefoxAndroid = userAgent$1.indexOf("Firefox") !== -1 && userAgent$1.indexOf("Android") !== -1; + return function () { + return isFirefoxAndroid; + }; + }(); + + Util.isR7 = function () { + var isR7 = userAgent$1.indexOf("R7 Build") !== -1; + return function () { + return isR7; + }; + }(); + + Util.isLandscapeMode = function () { + var rtn = win.orientation === 90 || win.orientation === -90; + return Util.isR7() ? !rtn : rtn; + }; // Helper method to validate the time steps of sensor timestamps. + + + Util.isTimestampDeltaValid = function (timestampDeltaS) { + if (isNaN(timestampDeltaS)) { + return false; + } + + if (timestampDeltaS <= Util.MIN_TIMESTEP) { + return false; + } + + if (timestampDeltaS > Util.MAX_TIMESTEP) { + return false; + } + + return true; + }; + + Util.getScreenWidth = function () { + return Math.max(win.screen.width, win.screen.height) * win.devicePixelRatio; + }; + + Util.getScreenHeight = function () { + return Math.min(win.screen.width, win.screen.height) * win.devicePixelRatio; + }; + + Util.requestFullscreen = function (element) { + if (Util.isWebViewAndroid()) { + return false; + } + + if (element.requestFullscreen) { + element.requestFullscreen(); + } else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } else { + return false; + } + + return true; + }; + + Util.exitFullscreen = function () { + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else if (doc.webkitExitFullscreen) { + doc.webkitExitFullscreen(); + } else if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } else { + return false; + } + + return true; + }; + + Util.getFullscreenElement = function () { + return doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement; + }; + + Util.linkProgram = function (gl, vertexSource, fragmentSource, attribLocationMap) { + // No error checking for brevity. + var vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vertexSource); + gl.compileShader(vertexShader); + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + for (var attribName in attribLocationMap) gl.bindAttribLocation(program, attribLocationMap[attribName], attribName); + + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + return program; + }; + + Util.getProgramUniforms = function (gl, program) { + var uniforms = {}; + var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + var uniformName = ""; + + for (var i = 0; i < uniformCount; i++) { + var uniformInfo = gl.getActiveUniform(program, i); + uniformName = uniformInfo.name.replace("[0]", ""); + uniforms[uniformName] = gl.getUniformLocation(program, uniformName); + } + + return uniforms; + }; + + Util.orthoMatrix = function (out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 2 * nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = (far + near) * nf; + out[15] = 1; + return out; + }; + + Util.copyArray = function (source, dest) { + for (var i = 0, n = source.length; i < n; i++) { + dest[i] = source[i]; + } + }; + + Util.isMobile = function () { + var check = false; + + (function (a) { + if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; + })(userAgent$1 || (nav === null || nav === void 0 ? void 0 : nav.vendor) || win.opera); + + return check; + }; + + Util.extend = function (dest, src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dest[key] = src[key]; + } + } + + return dest; + }; + + Util.safariCssSizeWorkaround = function (canvas) { + // TODO(smus): Remove this workaround when Safari for iOS is fixed. + // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556). + // + // "To the last I grapple with thee; + // from hell's heart I stab at thee; + // for hate's sake I spit my last breath at thee." + // -- Moby Dick, by Herman Melville + if (Util.isIOS()) { + var width_1 = canvas.style.width; + var height_1 = canvas.style.height; + canvas.style.width = parseInt(width_1) + 1 + "px"; + canvas.style.height = parseInt(height_1) + "px"; + setTimeout(function () { + canvas.style.width = width_1; + canvas.style.height = height_1; + }, 100); + } // Debug only. + + + win.Util = Util; + win.canvas = canvas; + }; + + Util.isDebug = function () { + return Util.getQueryParameter("debug"); + }; + + Util.getQueryParameter = function (name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"); + var results = regex.exec(location.search); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); + }; + + Util.frameDataFromPose = function () { + var piOver180 = Math.PI / 180.0; + var rad45 = Math.PI * 0.25; // Borrowed from glMatrix. + + function mat4_perspectiveFromFieldOfView(out, fov, near, far) { + var upTan = Math.tan(fov ? fov.upDegrees * piOver180 : rad45); + var downTan = Math.tan(fov ? fov.downDegrees * piOver180 : rad45); + var leftTan = Math.tan(fov ? fov.leftDegrees * piOver180 : rad45); + var rightTan = Math.tan(fov ? fov.rightDegrees * piOver180 : rad45); + var xScale = 2.0 / (leftTan + rightTan); + var yScale = 2.0 / (upTan + downTan); + out[0] = xScale; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + out[4] = 0.0; + out[5] = yScale; + out[6] = 0.0; + out[7] = 0.0; + out[8] = -((leftTan - rightTan) * xScale * 0.5); + out[9] = (upTan - downTan) * yScale * 0.5; + out[10] = far / (near - far); + out[11] = -1.0; + out[12] = 0.0; + out[13] = 0.0; + out[14] = far * near / (near - far); + out[15] = 0.0; + return out; + } + + function mat4_fromRotationTranslation(out, q, v) { + // Quaternion math + var x = q[0]; + var y = q[1]; + var z = q[2]; + var w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - (yy + zz); + out[1] = xy + wz; + out[2] = xz - wy; + out[3] = 0; + out[4] = xy - wz; + out[5] = 1 - (xx + zz); + out[6] = yz + wx; + out[7] = 0; + out[8] = xz + wy; + out[9] = yz - wx; + out[10] = 1 - (xx + yy); + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + + function mat4_translate(out, a, v) { + var x = v[0]; + var y = v[1]; + var z = v[2]; + var a00; + var a01; + var a02; + var a03; + var a10; + var a11; + var a12; + var a13; + var a20; + var a21; + var a22; + var a23; + + if (a === out) { + out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; + out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; + out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; + out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; + } else { + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a03; + out[4] = a10; + out[5] = a11; + out[6] = a12; + out[7] = a13; + out[8] = a20; + out[9] = a21; + out[10] = a22; + out[11] = a23; + out[12] = a00 * x + a10 * y + a20 * z + a[12]; + out[13] = a01 * x + a11 * y + a21 * z + a[13]; + out[14] = a02 * x + a12 * y + a22 * z + a[14]; + out[15] = a03 * x + a13 * y + a23 * z + a[15]; + } + + return out; + } + + function mat4_invert(out, a) { + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + var a30 = a[12]; + var a31 = a[13]; + var a32 = a[14]; + var a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + return out; + } + + var defaultOrientation = new Float32Array([0, 0, 0, 1]); + var defaultPosition = new Float32Array([0, 0, 0]); + + function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) { + mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar); + var orientation = pose.orientation || defaultOrientation; + var position = pose.position || defaultPosition; + mat4_fromRotationTranslation(view, orientation, position); + if (parameters) mat4_translate(view, view, parameters.offset); + mat4_invert(view, view); + } + + return function (frameData, pose, vrDisplay) { + if (!frameData || !pose) return false; + frameData.pose = pose; + frameData.timestamp = pose.timestamp; + updateEyeMatrices(frameData.leftProjectionMatrix, frameData.leftViewMatrix, pose, vrDisplay.getEyeParameters("left"), vrDisplay); + updateEyeMatrices(frameData.rightProjectionMatrix, frameData.rightViewMatrix, pose, vrDisplay.getEyeParameters("right"), vrDisplay); + return true; + }; + }(); + + Util.isInsideCrossDomainIFrame = function () { + var isFramed = win.self !== win.top; + var refDomain = Util.getDomainFromUrl(doc.referrer); + var thisDomain = Util.getDomainFromUrl(win.location.href); + return isFramed && refDomain !== thisDomain; + }; // From http://stackoverflow.com/a/23945027. + + + Util.getDomainFromUrl = function (url) { + var domain; // Find & remove protocol (http, ftp, etc.) and get domain. + + if (url.indexOf("://") > -1) { + domain = url.split("/")[2]; + } else { + domain = url.split("/")[0]; + } // find & remove port number + + + domain = domain.split(":")[0]; + return domain; + }; + + /* eslint-disable */ + /** + * Given an orientation and the gyroscope data, predicts the future orientation + * of the head. This makes rendering appear faster. + * + * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf + * @param {Number} predictionTimeS time from head movement to the appearance of + * the corresponding image. + */ + + var PosePredictor = + /*#__PURE__*/ + function () { + function PosePredictor(predictionTimeS) { + this.predictionTimeS = predictionTimeS; // The quaternion corresponding to the previous state. + + this.previousQ = new MathUtil.Quaternion(); // Previous time a prediction occurred. + + this.previousTimestampS = null; // The delta quaternion that adjusts the current pose. + + this.deltaQ = new MathUtil.Quaternion(); // The output quaternion. + + this.outQ = new MathUtil.Quaternion(); + } + + var __proto = PosePredictor.prototype; + + __proto.getPrediction = function (currentQ, gyro, timestampS) { + if (!this.previousTimestampS) { + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return currentQ; + } // Calculate axis and angle based on gyroscope rotation rate data. + + + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + var angularSpeed = gyro.length(); // If we're rotating slowly, don't do prediction. + + if (angularSpeed < MathUtil.degToRad * 20) { + if (Util.isDebug()) { + console.log("Moving slowly, at %s deg/s: no prediction", (MathUtil.radToDeg * angularSpeed).toFixed(1)); + } + + this.outQ.copy(currentQ); + this.previousQ.copy(currentQ); + return this.outQ; + } // Get the predicted angle based on the time delta and latency. + + + var deltaT = timestampS - this.previousTimestampS; + var predictAngle = angularSpeed * this.predictionTimeS; + this.deltaQ.setFromAxisAngle(axis, predictAngle); + this.outQ.copy(this.previousQ); + this.outQ.multiply(this.deltaQ); + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return this.outQ; + }; + + return PosePredictor; + }(); + + var STILLNESS_THRESHOLD = 200; // millisecond + + var DeviceMotion = + /*#__PURE__*/ + function (_super) { + __extends(DeviceMotion, _super); + + function DeviceMotion() { + var _this = _super.call(this) || this; + + _this._onDeviceMotion = _this._onDeviceMotion.bind(_this); + _this._onDeviceOrientation = _this._onDeviceOrientation.bind(_this); + _this._onChromeWithoutDeviceMotion = _this._onChromeWithoutDeviceMotion.bind(_this); + _this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION; + _this.isAndroid = IS_ANDROID; + _this.stillGyroVec = glMatrix.vec3.create(); + _this.rawGyroVec = glMatrix.vec3.create(); + _this.adjustedGyroVec = glMatrix.vec3.create(); + _this._timer = -1; + _this.lastDevicemotionTimestamp = 0; + _this._isEnabled = false; + + _this.enable(); + + return _this; + } + + var __proto = DeviceMotion.prototype; + + __proto.enable = function () { + if (this.isAndroid) { + win.addEventListener("deviceorientation", this._onDeviceOrientation); + } + + if (this.isWithoutDeviceMotion) { + win.addEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + } else { + win.addEventListener("devicemotion", this._onDeviceMotion); + } + + this._isEnabled = true; + }; + + __proto.disable = function () { + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + win.removeEventListener("devicemotion", this._onDeviceMotion); + this._isEnabled = false; + }; + + __proto._onChromeWithoutDeviceMotion = function (e) { + var alpha = e.alpha, + beta = e.beta, + gamma = e.gamma; // There is deviceorientation event trigged with empty values + // on Headless Chrome. + + if (alpha === null) { + return; + } // convert to radian + + + alpha = (alpha || 0) * Math.PI / 180; + beta = (beta || 0) * Math.PI / 180; + gamma = (gamma || 0) * Math.PI / 180; + this.trigger(new Component.ComponentEvent("devicemotion", { + inputEvent: { + deviceorientation: { + alpha: alpha, + beta: beta, + gamma: -gamma + } + } + })); + }; + + __proto._onDeviceOrientation = function () { + var _this = this; + + if (this._timer) { + clearTimeout(this._timer); + } + + this._timer = win.setTimeout(function () { + if (new Date().getTime() - _this.lastDevicemotionTimestamp < STILLNESS_THRESHOLD) { + glMatrix.vec3.copy(_this.stillGyroVec, _this.rawGyroVec); + } + }, STILLNESS_THRESHOLD); + }; + + __proto._onDeviceMotion = function (e) { + // desktop chrome triggers devicemotion event with empthy sensor values. + // Those events should ignored. + var isGyroSensorAvailable = !(e.rotationRate.alpha == null); + var isGravitySensorAvailable = !(e.accelerationIncludingGravity.x == null); + + if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) { + return; + } + + var devicemotionEvent = __assign({}, e); + + devicemotionEvent.interval = e.interval; + devicemotionEvent.timeStamp = e.timeStamp; + devicemotionEvent.type = e.type; + devicemotionEvent.rotationRate = { + alpha: e.rotationRate.alpha, + beta: e.rotationRate.beta, + gamma: e.rotationRate.gamma + }; + devicemotionEvent.accelerationIncludingGravity = { + x: e.accelerationIncludingGravity.x, + y: e.accelerationIncludingGravity.y, + z: e.accelerationIncludingGravity.z + }; + devicemotionEvent.acceleration = { + x: e.acceleration.x, + y: e.acceleration.y, + z: e.acceleration.z + }; + + if (this.isAndroid) { + glMatrix.vec3.set(this.rawGyroVec, e.rotationRate.alpha || 0, e.rotationRate.beta || 0, e.rotationRate.gamma || 0); + glMatrix.vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec); + this.lastDevicemotionTimestamp = new Date().getTime(); + devicemotionEvent.adjustedRotationRate = { + alpha: this.adjustedGyroVec[0], + beta: this.adjustedGyroVec[1], + gamma: this.adjustedGyroVec[2] + }; + } + + this.trigger(new Component.ComponentEvent("devicemotion", { + inputEvent: devicemotionEvent + })); + }; + + return DeviceMotion; + }(Component); + + var SensorSample = + /*#__PURE__*/ + function () { + function SensorSample(sample, timestampS) { + this.set(sample, timestampS); + } + + var __proto = SensorSample.prototype; + + __proto.set = function (sample, timestampS) { + this.sample = sample; + this.timestampS = timestampS; + }; + + __proto.copy = function (sensorSample) { + this.set(sensorSample.sample, sensorSample.timestampS); + }; + + return SensorSample; + }(); + + /* eslint-disable */ + /** + * An implementation of a simple complementary filter, which fuses gyroscope and + * accelerometer data from the 'devicemotion' event. + * + * Accelerometer data is very noisy, but stable over the long term. + * Gyroscope data is smooth, but tends to drift over the long term. + * + * This fusion is relatively simple: + * 1. Get orientation estimates from accelerometer by applying a low-pass filter + * on that data. + * 2. Get orientation estimates from gyroscope by integrating over time. + * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the + * short term. + */ + + var ComplementaryFilter = + /*#__PURE__*/ + function () { + function ComplementaryFilter(kFilter) { + this.addGyroMeasurement = function (vector, timestampS) { + this.currentGyroMeasurement.set(vector, timestampS); + var deltaT = timestampS - this.previousGyroMeasurement.timestampS; + + if (Util.isTimestampDeltaValid(deltaT)) { + this.run_(); + } + + this.previousGyroMeasurement.copy(this.currentGyroMeasurement); + }; + + this.kFilter = kFilter; // Raw sensor measurements. + + this.currentAccelMeasurement = new SensorSample(); + this.currentGyroMeasurement = new SensorSample(); + this.previousGyroMeasurement = new SensorSample(); // Set default look direction to be in the correct direction. + + if (Util.isIOS()) { + this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1); + } else { + this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1); + } + + this.previousFilterQ = new MathUtil.Quaternion(); + this.previousFilterQ.copy(this.filterQ); // Orientation based on the accelerometer. + + this.accelQ = new MathUtil.Quaternion(); // Whether or not the orientation has been initialized. + + this.isOrientationInitialized = false; // Running estimate of gravity based on the current orientation. + + this.estimatedGravity = new MathUtil.Vector3(); // Measured gravity based on accelerometer. + + this.measuredGravity = new MathUtil.Vector3(); // Debug only quaternion of gyro-based orientation. + + this.gyroIntegralQ = new MathUtil.Quaternion(); + } + + var __proto = ComplementaryFilter.prototype; + + __proto.addAccelMeasurement = function (vector, timestampS) { + this.currentAccelMeasurement.set(vector, timestampS); + }; + + __proto.getOrientation = function () { + return this.filterQ; + }; + + __proto.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); + + if (Util.isDebug()) { + console.log("Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)", MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ), this.estimatedGravity.x.toFixed(1), this.estimatedGravity.y.toFixed(1), this.estimatedGravity.z.toFixed(1), this.measuredGravity.x.toFixed(1), this.measuredGravity.y.toFixed(1), this.measuredGravity.z.toFixed(1)); + } // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + }; + + __proto.accelToQuaternion_ = function (accel) { + var normAccel = new MathUtil.Vector3(); + normAccel.copy(accel); + normAccel.normalize(); + var quat = new MathUtil.Quaternion(); + quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel); + quat.inverse(); + return quat; + }; + + __proto.gyroToQuaternionDelta_ = function (gyro, dt) { + // Extract axis and angle from the gyroscope data. + var quat = new MathUtil.Quaternion(); + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + quat.setFromAxisAngle(axis, gyro.length() * dt); + return quat; + }; + + return ComplementaryFilter; + }(); + + ComplementaryFilter.prototype.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + + if (!this.isFilterQuaternionInitialized) { + this.isFilterQuaternionInitialized = true; + } + }; + + ComplementaryFilter.prototype.getOrientation = function () { + if (this.isFilterQuaternionInitialized) { + return this.filterQ; + } else { + return null; + } + }; + + var K_FILTER = 0.98; + var PREDICTION_TIME_S = 0.040; + + var FusionPoseSensor = + /*#__PURE__*/ + function (_super) { + __extends(FusionPoseSensor, _super); + + function FusionPoseSensor() { + var _this = _super.call(this) || this; + + _this.deviceMotion = new DeviceMotion(); + _this.accelerometer = new MathUtil.Vector3(); + _this.gyroscope = new MathUtil.Vector3(); + _this._onDeviceMotionChange = _this._onDeviceMotionChange.bind(_this); + _this._onScreenOrientationChange = _this._onScreenOrientationChange.bind(_this); + _this.filter = new ComplementaryFilter(K_FILTER); + _this.posePredictor = new PosePredictor(PREDICTION_TIME_S); + _this.filterToWorldQ = new MathUtil.Quaternion(); + _this.isFirefoxAndroid = Util.isFirefoxAndroid(); // This includes iPhone & iPad(both desktop and mobile mode) ref #326 + + _this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP; // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18 + + _this.isChromeUsingDegrees = CHROME_VERSION >= 66; + _this._isEnabled = false; // Set the filter to world transform, depending on OS. + + if (_this.isIOS) { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2); + } else { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2); + } + + _this.inverseWorldToScreenQ = new MathUtil.Quaternion(); + _this.worldToScreenQ = new MathUtil.Quaternion(); + _this.originalPoseAdjustQ = new MathUtil.Quaternion(); + + _this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -win.orientation * Math.PI / 180); + + _this._setScreenTransform(); // Adjust this filter for being in landscape mode. + + + if (Util.isLandscapeMode()) { + _this.filterToWorldQ.multiply(_this.inverseWorldToScreenQ); + } // Keep track of a reset transform for resetSensor. + + + _this.resetQ = new MathUtil.Quaternion(); + + _this.deviceMotion.on("devicemotion", _this._onDeviceMotionChange); + + _this.enable(); + + return _this; + } + + var __proto = FusionPoseSensor.prototype; + + __proto.enable = function () { + if (this.isEnabled()) { + return; + } + + this.deviceMotion.enable(); + this._isEnabled = true; + win.addEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.disable = function () { + if (!this.isEnabled()) { + return; + } + + this.deviceMotion.disable(); + this._isEnabled = false; + win.removeEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.isEnabled = function () { + return this._isEnabled; + }; + + __proto.destroy = function () { + this.disable(); + this.deviceMotion = null; + }; + + __proto.getOrientation = function () { + var _this = this; + + var orientation; // Hack around using deviceorientation instead of devicemotion + + if (this.deviceMotion.isWithoutDeviceMotion && this._deviceOrientationQ) { + this.deviceOrientationFixQ = this.deviceOrientationFixQ || function () { + var y = new MathUtil.Quaternion().setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -_this._alpha); + return y; + }(); + + orientation = this._deviceOrientationQ; + var out = new MathUtil.Quaternion(); + out.copy(orientation); + out.multiply(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.worldToScreenQ); + out.multiplyQuaternions(this.deviceOrientationFixQ, out); // return quaternion as glmatrix quaternion object + + var outQuat = glMatrix.quat.fromValues(out.x, out.y, out.z, out.w); + return glMatrix.quat.normalize(outQuat, outQuat); + } else { + // Convert from filter space to the the same system used by the + // deviceorientation event. + orientation = this.filter.getOrientation(); + + if (!orientation) { + return null; + } + + var out = this._convertFusionToPredicted(orientation); // return quaternion as glmatrix quaternion object + + + var outQuat = glMatrix.quat.fromValues(out.x, out.y, out.z, out.w); + return glMatrix.quat.normalize(outQuat, outQuat); + } + }; + + __proto._triggerChange = function () { + var orientation = this.getOrientation(); // if orientation is not prepared. don't trigger change event + + if (!orientation) { + return; + } + + if (!this._prevOrientation) { + this._prevOrientation = orientation; + return; + } + + if (glMatrix.quat.equals(this._prevOrientation, orientation)) { + return; + } + + this.trigger(new Component.ComponentEvent("change", { + quaternion: orientation + })); + }; + + __proto._convertFusionToPredicted = function (orientation) { + // Predict orientation. + this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS); // Convert to THREE coordinate system: -Z forward, Y up, X right. + + var out = new MathUtil.Quaternion(); + out.copy(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.predictedQ); + out.multiply(this.worldToScreenQ); + return out; + }; + + __proto._onDeviceMotionChange = function (_a) { + var inputEvent = _a.inputEvent; + var deviceorientation = inputEvent.deviceorientation; + var deviceMotion = inputEvent; + var accGravity = deviceMotion.accelerationIncludingGravity; + var rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate; + var timestampS = deviceMotion.timeStamp / 1000; + + if (deviceorientation) { + if (!this._alpha) { + this._alpha = deviceorientation.alpha; + } + + this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion(); + + this._deviceOrientationQ.setFromEulerYXZ(deviceorientation.beta, deviceorientation.alpha, deviceorientation.gamma); + + this._triggerChange(); + } else { + // Firefox Android timeStamp returns one thousandth of a millisecond. + if (this.isFirefoxAndroid) { + timestampS /= 1000; + } + + this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z); + this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma); // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate` + // is reported in degrees, so we first convert to radians. + + if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) { + this.gyroscope.multiplyScalar(Math.PI / 180); + } + + this.filter.addAccelMeasurement(this.accelerometer, timestampS); + this.filter.addGyroMeasurement(this.gyroscope, timestampS); + + this._triggerChange(); + + this.previousTimestampS = timestampS; + } + }; + + __proto._onScreenOrientationChange = function () { + this._setScreenTransform(); + }; + + __proto._setScreenTransform = function () { + this.worldToScreenQ.set(0, 0, 0, 1); + var orientation = win.orientation; + + switch (orientation) { + case 0: + break; + + case 90: + case -90: + case 180: + this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI); + break; + } + + this.inverseWorldToScreenQ.copy(this.worldToScreenQ); + this.inverseWorldToScreenQ.inverse(); + }; + + return FusionPoseSensor; + }(Component); + + var getDeltaYaw = function (prvQ, curQ) { + var yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + var yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(util.extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + }; + + var getDeltaPitch = function (prvQ, curQ) { + var pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + return pitchDelta; + }; // eslint-disable-next-line @typescript-eslint/ban-types + + + var TiltMotionInput = + /*#__PURE__*/ + function (_super) { + __extends(TiltMotionInput, _super); + + function TiltMotionInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.element = el; + _this._prevQuaternion = null; + _this._quaternion = null; + _this.fusionPoseSensor = null; + _this.options = __assign({ + scale: 1, + threshold: 0 + }, options); + _this._onPoseChange = _this._onPoseChange.bind(_this); + return _this; + } + + var __proto = TiltMotionInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this.observer) { + return this; + } + + this.observer = observer; + this.fusionPoseSensor = new FusionPoseSensor(); + this.fusionPoseSensor.enable(); + + this._attachEvent(); + + return this; + }; + + __proto.disconnect = function () { + if (!this.observer) { + return this; + } + + this._dettachEvent(); + + this.fusionPoseSensor.disable(); + this.fusionPoseSensor.destroy(); + this.fusionPoseSensor = null; + this.observer = null; + return this; + }; + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + this.options = null; + this.axes = null; + this._prevQuaternion = null; + this._quaternion = null; + }; + + __proto._onPoseChange = function (event) { + if (!this._prevQuaternion) { + this._prevQuaternion = glMatrix.quat.clone(event.quaternion); + this._quaternion = glMatrix.quat.clone(event.quaternion); + return; + } + + glMatrix.quat.copy(this._prevQuaternion, this._quaternion); + glMatrix.quat.copy(this._quaternion, event.quaternion); + this.observer.change(this, event, toAxis(this.axes, [getDeltaYaw(this._prevQuaternion, this._quaternion), getDeltaPitch(this._prevQuaternion, this._quaternion)])); + }; + + __proto._attachEvent = function () { + this.fusionPoseSensor.on("change", this._onPoseChange); + }; + + __proto._dettachEvent = function () { + this.fusionPoseSensor.off("change", this._onPoseChange); + }; + + return TiltMotionInput; + }(Component); + + var screenRotationAngleInst = null; + var refCount = 0; + + var ScreenRotationAngle = + /*#__PURE__*/ + function () { + function ScreenRotationAngle() { + refCount++; + + if (screenRotationAngleInst) { + return screenRotationAngleInst; + } + /* eslint-disable */ + + + screenRotationAngleInst = this; + /* eslint-enable */ + + this._onDeviceOrientation = this._onDeviceOrientation.bind(this); + this._onOrientationChange = this._onOrientationChange.bind(this); + this._spinR = 0; + this._screenOrientationAngle = 0; + win.addEventListener("deviceorientation", this._onDeviceOrientation); + win.addEventListener("orientationchange", this._onOrientationChange); + } + + var __proto = ScreenRotationAngle.prototype; + + __proto.getRadian = function () { + // Join with screen orientation + // this._testVal = this._spinR + ", " + this._screenOrientationAngle + ", " + window.orientation; + return this._spinR + glMatrix.glMatrix.toRadian(this._screenOrientationAngle); + }; + + __proto.unref = function () { + if (--refCount > 0) { + return; + } + + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("orientationchange", this._onOrientationChange); + this._spinR = 0; + this._screenOrientationAngle = 0; + /* eslint-disable */ + + screenRotationAngleInst = null; + /* eslint-enable */ + + refCount = 0; + }; + + __proto._onDeviceOrientation = function (e) { + if (e.beta === null || e.gamma === null) { + // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it. + return; + } // Radian + + + var betaR = glMatrix.glMatrix.toRadian(e.beta); + var gammaR = glMatrix.glMatrix.toRadian(e.gamma); + /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */ + + this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR)); + }; + + __proto._onOrientationChange = function () { + if (win.screen && win.screen.orientation && win.screen.orientation.angle !== undefined) { + this._screenOrientationAngle = screen.orientation.angle; + } else if (win.orientation !== undefined) { + /* iOS */ + this._screenOrientationAngle = win.orientation >= 0 ? win.orientation : 360 + win.orientation; + } + }; + + return ScreenRotationAngle; + }(); + + /** + * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle. + * + * The reason for using this function is that in VR mode, + * the roll angle is adjusted in the direction opposite to the screen rotation angle. + * + * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move. + * @extends PanInput + */ + + var RotationPanInput = + /*#__PURE__*/ + function (_super) { + __extends(RotationPanInput, _super); + /** + * Constructor + * @private + * @param {HTMLElement} el target element + * @param {Object} [options] The option object + * @param {Boolean} [options.useRotation] Whether to use rotation(or VR) + */ + + + function RotationPanInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this, el, options) || this; + + _this._useRotation = false; + _this._screenRotationAngle = null; + + _this.setUseRotation(!!(options && options.useRotation)); + + _this._userDirection = Axes.DIRECTION_ALL; + return _this; + } + + var __proto = RotationPanInput.prototype; + + __proto.setUseRotation = function (useRotation) { + this._useRotation = useRotation; + + if (this._screenRotationAngle) { + this._screenRotationAngle.unref(); + + this._screenRotationAngle = null; + } + + if (this._useRotation) { + this._screenRotationAngle = new ScreenRotationAngle(); + } + }; + + __proto.connect = function (observer) { + // User intetened direction + this._userDirection = this._direction; // In VR Mode, Use ALL direction if direction is not none + // Because horizontal and vertical is changed dynamically by screen rotation. + // this._direction is used to initialize hammerjs + + if (this._useRotation && this._direction & Axes.DIRECTION_ALL) { + this._direction = Axes.DIRECTION_HORIZONTAL; + } + + return _super.prototype.connect.call(this, observer); + }; + + __proto.destroy = function () { + if (this._useRotation && this._screenRotationAngle) { + this._screenRotationAngle.unref(); + } + + _super.prototype.destroy.call(this); + }; + + __proto._getOffset = function (properties, useDirection) { + if (this._useRotation === false) { + return _super.prototype._getOffset.call(this, properties, useDirection); + } + + var offset = _super.prototype._getOffset.call(this, properties, [true, true]); + + var newOffset = [0, 0]; + + var theta = this._screenRotationAngle.getRadian(); + + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); // RotateZ + + newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta; + newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta; // Use only user allowed direction. + + if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) { + newOffset[0] = 0; + } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) { + newOffset[1] = 0; + } + + return newOffset; + }; + + return RotationPanInput; + }(Axes.PanInput); + /** + * Override getDirectionByAngle to return DIRECTION_ALL + * Ref: https://github.com/naver/egjs-axes/issues/99 + * + * But we obey axes's rule. If axes's rule is problem, let's apply following code. + */ + // PanInput.getDirectionByAngle = function (angle, thresholdAngle) { + // return DIRECTION_ALL; + // }; + + var Y_AXIS_VECTOR = glMatrix.vec3.fromValues(0, 1, 0); + + var DeviceQuaternion = + /*#__PURE__*/ + function (_super) { + __extends(DeviceQuaternion, _super); + + function DeviceQuaternion() { + var _this = _super.call(this) || this; + + _this._fusionPoseSensor = new FusionPoseSensor(); + _this._quaternion = glMatrix.quat.create(); + + _this._fusionPoseSensor.enable(); + + _this._fusionPoseSensor.on("change", function (e) { + _this._quaternion = e.quaternion; + + _this.trigger(new Component.ComponentEvent("change", { + isTrusted: true + })); + }); + + return _this; + } + + var __proto = DeviceQuaternion.prototype; + + __proto.getCombinedQuaternion = function (yaw) { + var yawQ = glMatrix.quat.setAxisAngle(glMatrix.quat.create(), Y_AXIS_VECTOR, glMatrix.glMatrix.toRadian(-yaw)); + var conj = glMatrix.quat.conjugate(glMatrix.quat.create(), this._quaternion); // Multiply pitch quaternion -> device quaternion -> yaw quaternion + + var outQ = glMatrix.quat.multiply(glMatrix.quat.create(), conj, yawQ); + return outQ; + }; + + __proto.destroy = function () { + // detach all event handler + this.off(); + + if (this._fusionPoseSensor) { + this._fusionPoseSensor.off(); + + this._fusionPoseSensor.destroy(); + + this._fusionPoseSensor = null; + } + }; + + return DeviceQuaternion; + }(Component); + + var DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF]; + var DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF]; + var CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF]; + /** + * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates. + * @alias eg.YawPitchControl + * @extends eg.Component + * + * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + */ + + var YawPitchControl = + /*#__PURE__*/ + function (_super) { + __extends(YawPitchControl, _super); + /** + * @param {object} options The option object of the eg.YawPitch module + * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module + * @param {number} [options.yaw=0] initial yaw (degree) + * @param {number} [options.pitch=0] initial pitch (degree) + * @param {number} [options.fov=65] initial field of view (degree) + * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown + * @param {boolean} [options.useZoom=true] Indicates whether zoom is available + * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled + * @param {string} [config.gyroMode=yawPitch] Enables control through device motion. + * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move) + * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw + * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch + * @param {number[]} [options.fovRange=[30, 110] Range of FOV + * @param {number} [options.aspectRatio=1] Aspect Ratio + */ + + + function YawPitchControl(options) { + var _this = _super.call(this) || this; + + _this.options = {}; + + var opt = __assign({ + element: null, + yaw: 0, + pitch: 0, + fov: 65, + showPolePoint: false, + useZoom: true, + useKeyboard: true, + gyroMode: GYRO_MODE.YAWPITCH, + touchDirection: TOUCH_DIRECTION_ALL, + yawRange: DEFAULT_YAW_RANGE, + pitchRange: DEFAULT_PITCH_RANGE, + fovRange: [30, 110], + aspectRatio: 1 + /* TODO: Need Mandatory? */ + + }, options); + + _this._element = opt.element; + _this._initialFov = opt.fov; + _this._enabled = false; + _this._isAnimating = false; + _this._deviceQuaternion = null; + + _this._initAxes(opt); + + _this.option(opt); + + return _this; + } + /** + * Update Pan Scale + * + * Scale(Sensitivity) values of panning is related with fov and height. + * If at least one of them is changed, this function need to be called. + * @param {*} param + */ + + + var __proto = YawPitchControl.prototype; + + __proto.updatePanScale = function (param) { + if (param === void 0) { + param = {}; + } + + var fov = this._axes.get().fov; + + var areaHeight = param.height || parseInt(window.getComputedStyle(this._element).height, 10); + var scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight; + this._axesPanInput.options.scale = [scale, scale]; + this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW; + return this; + }; + /* + * Override component's option method + * to call method for updating values which is affected by option change. + * + * @param {*} args + */ + + + __proto.option = function (key, newValue) { + // Getter + if (!key) { + return this._getOptions(); + } else if (key && typeof key === "string" && typeof newValue === "undefined") { + return this._getOptions(key); + } // Setter + + + var newOptions = {}; + var changedKeyList = []; // TODO: if value is not changed, then do not push on changedKeyList. + + if (typeof key === "string") { + changedKeyList.push(key); + newOptions[key] = newValue; + } else { + var options = key; // Retrieving object here + + changedKeyList = Object.keys(options); + newOptions = __assign({}, options); + } + + this._setOptions(this._getValidatedOptions(newOptions)); + + this._applyOptions(changedKeyList); + + return this; + }; + /** + * Enable YawPitch functionality + * @method eg.YawPitch#enable + */ + + + __proto.enable = function () { + if (this._enabled) { + return this; + } + + this._enabled = true; // touchDirection is decided by parameter is valid string (Ref. Axes.connect) + + this._applyOptions(Object.keys(this.options)); // TODO: Is this code is needed? Check later. + + + this.updatePanScale(); + return this; + }; + /** + * Disable YawPitch functionality + * @method eg.YawPitch#disable + */ + + + __proto.disable = function (persistOrientation) { + if (persistOrientation === void 0) { + persistOrientation = false; + } + + if (!this._enabled) { + return this; + } // TODO: Check peristOrientation is needed! + + + if (!persistOrientation) { + this._resetOrientation(); + } + + this._axes.disconnect(); + + this._enabled = false; + return this; + }; + /** + * Set one or more of yaw, pitch, fov + * @param {Object} coordinate yaw, pitch, fov + * @param {Number} duration Animation duration. if it is above 0 then it's animated. + */ + + + __proto.lookAt = function (_a, duration) { + var yaw = _a.yaw, + pitch = _a.pitch, + fov = _a.fov; + + var pos = this._axes.get(); + + var y = yaw === undefined ? 0 : yaw - pos.yaw; + var p = pitch === undefined ? 0 : pitch - pos.pitch; + var f = fov === undefined ? 0 : fov - pos.fov; // Allow duration of animation to have more than MC_MAXIMUM_DURATION. + + this._axes.options.maximumDuration = Infinity; + + this._axes.setBy({ + yaw: y, + pitch: p, + fov: f + }, duration); + }; + + __proto.getYawPitch = function () { + var yawPitch = this._axes.get(); + + return { + yaw: yawPitch.yaw, + pitch: yawPitch.pitch + }; + }; + + __proto.getFov = function () { + return this._axes.get().fov; + }; + + __proto.getQuaternion = function () { + var pos = this._axes.get(); + + return this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + }; + + __proto.shouldRenderWithQuaternion = function () { + return this.options.gyroMode === GYRO_MODE.VR; + }; + /** + * Destroys objects + */ + + + __proto.destroy = function () { + /* eslint-disable @typescript-eslint/no-unused-expressions */ + this._axes && this._axes.destroy(); + this._axesPanInput && this._axesPanInput.destroy(); + this._axesWheelInput && this._axesWheelInput.destroy(); + this._axesTiltMotionInput && this._axesTiltMotionInput.destroy(); + this._axesPinchInput && this._axesPinchInput.destroy(); + this._axesMoveKeyInput && this._axesMoveKeyInput.destroy(); + this._deviceQuaternion && this._deviceQuaternion.destroy(); + /* eslint-enable @typescript-eslint/no-unused-expressions */ + }; + + __proto._initAxes = function (opt) { + var _this = this; + + var yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio); + + var pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint); + + var useRotation = opt.gyroMode === GYRO_MODE.VR; + this._axesPanInput = new RotationPanInput(this._element, { + useRotation: useRotation + }); + this._axesWheelInput = new Axes.WheelInput(this._element, { + scale: -4 + }); + this._axesTiltMotionInput = null; + this._axesPinchInput = SUPPORT_TOUCH ? new Axes.PinchInput(this._element, { + scale: -1 + }) : null; + this._axesMoveKeyInput = new Axes.MoveKeyInput(this._element, { + scale: [-6, 6] + }); + this._axes = new Axes({ + yaw: { + range: yRange, + circular: this._isCircular(yRange), + bounce: [0, 0] + }, + pitch: { + range: pRange, + circular: this._isCircular(pRange), + bounce: [0, 0] + }, + fov: { + range: opt.fovRange, + circular: [false, false], + bounce: [0, 0] + } + }, { + deceleration: MC_DECELERATION, + maximumDuration: MC_MAXIMUM_DURATION + }, { + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }).on({ + // TODO: change event type after Axes event type inference update + hold: function (evt) { + // Restore maximumDuration not to be spin too mush. + _this._axes.options.maximumDuration = MC_MAXIMUM_DURATION; + + _this.trigger(new Component.ComponentEvent("hold", { + isTrusted: evt.isTrusted + })); + }, + change: function (evt) { + if (evt.delta.fov !== 0) { + _this._updateControlScale(evt); + + _this.updatePanScale(); + } + + _this._triggerChange(evt); + }, + release: function (evt) { + _this._triggerChange(evt); + }, + animationEnd: function (evt) { + _this.trigger(new Component.ComponentEvent("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + }; + + __proto._getValidatedOptions = function (newOptions) { + if (newOptions.yawRange) { + newOptions.yawRange = this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio); + } + + if (newOptions.pitchRange) { + newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov); + } + + return newOptions; + }; + + __proto._getOptions = function (key) { + var value; + + if (typeof key === "string") { + value = this.options[key]; + } else if (arguments.length === 0) { + value = this.options; + } + + return value; + }; + + __proto._setOptions = function (options) { + for (var key in options) { + this.options[key] = options[key]; + } + }; + + __proto._applyOptions = function (keys) { + var options = this.options; + var axes = this._axes; + var isVR = options.gyroMode === GYRO_MODE.VR; + var isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH; // If it's VR mode, restrict user interaction to yaw direction only + + var touchDirection = isVR ? TOUCH_DIRECTION_YAW & options.touchDirection : options.touchDirection; // If one of below is changed, call updateControlScale() + + if (keys.some(function (key) { + return key === "showPolePoint" || key === "fov" || key === "aspectRatio" || key === "yawRange" || key === "pitchRange"; + })) { + // If fov is changed, update pan scale + if (keys.indexOf("fov") >= 0) { + axes.setTo({ + "fov": options.fov + }); + this.updatePanScale(); + } + + this._updateControlScale(); + } + + if (keys.some(function (key) { + return key === "fovRange"; + })) { + var fovRange = options.fovRange; + var prevFov = axes.get().fov; + var nextFov = axes.get().fov; + glMatrix.vec2.copy(axes.axis.fov.range, fovRange); + + if (nextFov < fovRange[0]) { + nextFov = fovRange[0]; + } else if (prevFov > fovRange[1]) { + nextFov = fovRange[1]; + } + + if (prevFov !== nextFov) { + axes.setTo({ + fov: nextFov + }, 0); + + this._updateControlScale(); + + this.updatePanScale(); + } + } + + if (keys.some(function (key) { + return key === "gyroMode"; + }) && SUPPORT_DEVICEMOTION) { + // Disconnect first + if (this._axesTiltMotionInput) { + this._axes.disconnect(this._axesTiltMotionInput); + + this._axesTiltMotionInput.destroy(); + + this._axesTiltMotionInput = null; + } + + if (this._deviceQuaternion) { + this._deviceQuaternion.destroy(); + + this._deviceQuaternion = null; + } + + if (isVR) { + this._initDeviceQuaternion(); + } else if (isYawPitch) { + this._axesTiltMotionInput = new TiltMotionInput(this._element); + + this._axes.connect(["yaw", "pitch"], this._axesTiltMotionInput); + } + + this._axesPanInput.setUseRotation(isVR); + } + + if (keys.some(function (key) { + return key === "useKeyboard"; + })) { + var useKeyboard = options.useKeyboard; + + if (useKeyboard) { + axes.connect(["yaw", "pitch"], this._axesMoveKeyInput); + } else { + axes.disconnect(this._axesMoveKeyInput); + } + } + + if (keys.some(function (key) { + return key === "useZoom"; + })) { + var useZoom = options.useZoom; // Disconnect first + + axes.disconnect(this._axesWheelInput); + + if (useZoom) { + axes.connect(["fov"], this._axesWheelInput); + } + } + + this._togglePinchInputByOption(options.touchDirection, options.useZoom); + + if (keys.some(function (key) { + return key === "touchDirection"; + }) && this._enabled) { + this._enableTouch(touchDirection); + } + }; + + __proto._togglePinchInputByOption = function (touchDirection, useZoom) { + if (this._axesPinchInput) { + // disconnect first + this._axes.disconnect(this._axesPinchInput); // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll. + + + if (useZoom && touchDirection === TOUCH_DIRECTION_ALL && // TODO: Get rid of using private property of axes instance. + this._axes._inputs.indexOf(this._axesPinchInput) === -1) { + this._axes.connect(["fov"], this._axesPinchInput); + } + } + }; + + __proto._enableTouch = function (direction) { + // Disconnect first + if (this._axesPanInput) { + this._axes.disconnect(this._axesPanInput); + } + + var yawEnabled = direction & TOUCH_DIRECTION_YAW ? "yaw" : null; + var pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? "pitch" : null; + + this._axes.connect([yawEnabled, pitchEnabled], this._axesPanInput); + }; + + __proto._initDeviceQuaternion = function () { + var _this = this; + + this._deviceQuaternion = new DeviceQuaternion(); + + this._deviceQuaternion.on("change", function (e) { + _this._triggerChange(e); + }); + }; + + __proto._getValidYawRange = function (newYawRange, newFov, newAspectRatio) { + var ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1); + + var fov = newFov || this._axes.get().fov; + + var horizontalFov = fov * ratio; + var isValid = newYawRange[1] - newYawRange[0] >= horizontalFov; + + if (isValid) { + return newYawRange; + } else { + return this.options.yawRange || DEFAULT_YAW_RANGE; + } + }; + + __proto._getValidPitchRange = function (newPitchRange, newFov) { + var fov = newFov || this._axes.get().fov; + + var isValid = newPitchRange[1] - newPitchRange[0] >= fov; + + if (isValid) { + return newPitchRange; + } else { + return this.options.pitchRange || DEFAULT_PITCH_RANGE; + } + }; + + __proto._isCircular = function (range) { + return range[1] - range[0] < 360 ? [false, false] : [true, true]; + }; + /** + * Update yaw/pitch min/max by 5 factor + * + * 1. showPolePoint + * 2. fov + * 3. yawRange + * 4. pitchRange + * 5. aspectRatio + * + * If one of above is changed, call this function + */ + + + __proto._updateControlScale = function (changeEvt) { + var opt = this.options; + + var fov = this._axes.get().fov; + + var pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint); + + var yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio); // TODO: If not changed!? + + + var pos = this._axes.get(); + + var y = pos.yaw; + var p = pos.pitch; + glMatrix.vec2.copy(this._axes.axis.yaw.range, yRange); + glMatrix.vec2.copy(this._axes.axis.pitch.range, pRange); + this._axes.axis.yaw.circular = this._isCircular(yRange); + this._axes.axis.pitch.circular = this._isCircular(pRange); + /** + * update yaw/pitch by it's range. + */ + + if (y < yRange[0]) { + y = yRange[0]; + } else if (y > yRange[1]) { + y = yRange[1]; + } + + if (p < pRange[0]) { + p = pRange[0]; + } else if (p > pRange[1]) { + p = pRange[1]; + } + + if (changeEvt) { + changeEvt.set({ + yaw: y, + pitch: p + }); + } + + this._axes.setTo({ + yaw: y, + pitch: p + }, 0); + + return this; + }; + + __proto._updatePitchRange = function (pitchRange, fov, showPolePoint) { + if (this.options.gyroMode === GYRO_MODE.VR) { + // Circular pitch on VR + return CIRCULAR_PITCH_RANGE; + } + + var verticalAngle = pitchRange[1] - pitchRange[0]; + var halfFov = fov / 2; + var isPanorama = verticalAngle < 180; + + if (showPolePoint && !isPanorama) { + // Use full pinch range + return pitchRange.concat(); + } // Round value as movableCood do. + + + return [pitchRange[0] + halfFov, pitchRange[1] - halfFov]; + }; + + __proto._updateYawRange = function (yawRange, fov, aspectRatio) { + if (this.options.gyroMode === GYRO_MODE.VR) { + return DEFAULT_YAW_RANGE; + } + + var horizontalAngle = yawRange[1] - yawRange[0]; + /** + * Full 360 Mode + */ + + if (horizontalAngle >= 360) { + // Don't limit yaw range on Full 360 mode. + return yawRange.concat(); + } + /** + * Panorama mode + */ + // Ref : https://github.com/naver/egjs-view360/issues/290 + + + var halfHorizontalFov = util.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.glMatrix.toRadian(fov / 2)))); // Round value as movableCood do. + + return [yawRange[0] + halfHorizontalFov, yawRange[1] - halfHorizontalFov]; + }; // TODO: update param type after Axes event type inference update + + + __proto._triggerChange = function (evt) { + var pos = this._axes.get(); + + var opt = this.options; + var event = { + targetElement: opt.element, + isTrusted: evt.isTrusted, + yaw: pos.yaw, + pitch: pos.pitch, + fov: pos.fov, + quaternion: null + }; + + if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) { + event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + } + + this.trigger(new Component.ComponentEvent("change", event)); + }; // TODO: makes constant to be logic + + + __proto._adjustAspectRatio = function (input) { + var inputRange = [0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670, 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19, 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26, 2.30, 2.60, 3.00, 5.00, 6.00]; + var outputRange = [0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710, 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15, 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72, 1.82, 1.92, 2.00, 2.24, 2.30]; + var rangeIdx = -1; + + for (var i = 0; i < inputRange.length - 1; i++) { + if (inputRange[i] <= input && inputRange[i + 1] >= input) { + rangeIdx = i; + break; + } + } + + if (rangeIdx === -1) { + if (inputRange[0] > input) { + return outputRange[0]; + } else { + // FIXME: this looks definitely wrong + return outputRange[outputRange[0].length - 1]; + } + } + + var inputA = inputRange[rangeIdx]; + var inputB = inputRange[rangeIdx + 1]; + var outputA = outputRange[rangeIdx]; + var outputB = outputRange[rangeIdx + 1]; + return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA)); + }; + + __proto._lerp = function (a, b, fraction) { + return a + fraction * (b - a); + }; + + __proto._resetOrientation = function () { + var opt = this.options; + + this._axes.setTo({ + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }, 0); + + return this; + }; + + YawPitchControl.VERSION = VERSION; // Expose DeviceOrientationControls sub module for test purpose + + YawPitchControl.CONTROL_MODE_VR = CONTROL_MODE_VR; + YawPitchControl.CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH; + YawPitchControl.TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL; + YawPitchControl.TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW; + YawPitchControl.TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH; + YawPitchControl.TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE; + return YawPitchControl; + }(Component); + + /** + * Constant value for errors + * @ko 에러에 대한 상수 값 + * @namespace + * @name ERROR_TYPE + * @memberof eg.view360.PanoViewer + */ + + var ERROR_TYPE = { + /** + * Unsupported device + * @ko 미지원 기기 + * @name INVALID_DEVICE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 10 + */ + INVALID_DEVICE: 10, + + /** + * Webgl not support + * @ko WEBGL 미지원 + * @name NO_WEBGL + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 11 + */ + NO_WEBGL: 11, + + /** + * Failed to load image + * @ko 이미지 로드 실패 + * @name FAIL_IMAGE_LOAD + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 12 + */ + FAIL_IMAGE_LOAD: 12, + + /** + * Failed to bind texture + * @ko 텍스쳐 바인딩 실패 + * @name FAIL_BIND_TEXTURE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 13 + */ + FAIL_BIND_TEXTURE: 13, + + /** + * Only one resource(image or video) should be specified + * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함) + * @name INVALID_RESOURCE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 14 + */ + INVALID_RESOURCE: 14, + + /** + * WebGL context lost occurred + * @ko WebGL context lost 발생 + * @name RENDERING_CONTEXT_LOST + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 15 + */ + RENDERING_CONTEXT_LOST: 15 + }; + /** + * Constant value for events + * @ko 이벤트에 대한 상수 값 + * @namespace + * @name EVENTS + * @memberof eg.view360.PanoViewer + */ + + var PANOVIEWER_EVENTS = { + /** + * Events that is fired when PanoViewer is ready to show image and handle user interaction. + * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트 + * @name READY + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default ready + */ + READY: "ready", + + /** + * Events that is fired when direction or fov is changed. + * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트 + * @name VIEW_CHANGE + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default viewChange + */ + VIEW_CHANGE: "viewChange", + + /** + * Events that is fired when animation which is triggered by inertia is ended. + * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트 + * @name ANIMATION_END + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default animationEnd + */ + ANIMATION_END: "animationEnd", + + /** + * Events that is fired when error occurs + * @ko 에러 발생 시 발생하는 이벤트 + * @name ERROR + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default error + */ + ERROR: "error" + }; + /** + * Constant value for projection type + * @ko 프로젝션 타입 대한 상수 값 + * @namespace + * @name PROJECTION_TYPE + * @memberof eg.view360.PanoViewer + */ + + var PROJECTION_TYPE = { + /** + * Constant value for equirectangular type. + * @ko equirectangular 에 대한 상수 값. + * @name EQUIRECTANGULAR + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default equirectangular + */ + EQUIRECTANGULAR: "equirectangular", + + /** + * Constant value for cubemap type. + * @ko cubemap 에 대한 상수 값. + * @name CUBEMAP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubemap + */ + CUBEMAP: "cubemap", + + /** + * Constant value for cubestrip type. + * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC. + * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다. + * @name CUBESTRIP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubestrip + */ + CUBESTRIP: "cubestrip", + + /** + * Constant value for PANORAMA type. + * + * PANORAMA is a format for a panorma image which is taken from smartphone. + * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다. + * + * @name PANORAMA + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default panorama + */ + PANORAMA: "panorama", + + /** + * Constant value for EQUI_STEREOSCOPY type. + * + * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present. + * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다. + * + * @name STEREOSCOPIC_EQUI + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default stereoequi + */ + STEREOSCOPIC_EQUI: "stereoequi" + }; + /** + * A constant value for the format of the stereoscopic equirectangular projection type. + * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값 + * @namespace + * @name STEREO_FORMAT + * @memberof eg.view360.PanoViewer + */ + + var STEREO_FORMAT = { + /** + * A constant value for format of top bottom stereoscopic 360 equirectangular projection. + * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name TOP_BOTTOM + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dv" + */ + TOP_BOTTOM: "3dv", + + /** + * A constant value for format of left right stereoscopic 360 equirectangular projection. + * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name LEFT_RIGHT + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dh" + */ + LEFT_RIGHT: "3dh", + + /** + * A constant value specifying media is not in stereoscopic format. + * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값. + * @name NONE + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "" + */ + NONE: "" + }; // eslint-disable-next-line @typescript-eslint/no-unused-vars + + var PANOVIEWER_OPTIONS = { + image: true, + video: true, + projectionType: true, + cubemapConfig: true, + stereoFormat: true, + width: true, + height: true, + yaw: true, + pitch: true, + fov: true, + showPolePoint: true, + useZoom: true, + useKeyboard: true, + gyroMode: true, + yawRange: true, + pitchRange: true, + fovRange: true, + touchDirection: true, + canvasClass: true + }; + var DEFAULT_CANVAS_CLASS = "view360-canvas"; + + var Constants = { + __proto__: null, + GYRO_MODE: GYRO_MODE, + PANOVIEWER_EVENTS: PANOVIEWER_EVENTS, + ERROR_TYPE: ERROR_TYPE, + PROJECTION_TYPE: PROJECTION_TYPE, + STEREO_FORMAT: STEREO_FORMAT, + PANOVIEWER_OPTIONS: PANOVIEWER_OPTIONS, + DEFAULT_CANVAS_CLASS: DEFAULT_CANVAS_CLASS + }; + + var WEBGL_ERROR_CODE = { + "0": "NO_ERROR", + "1280": "INVALID_ENUM", + "1281": "INVALID_VALUE", + "1282": "INVALID_OPERATION", + "1285": "OUT_OF_MEMORY", + "1286": "INVALID_FRAMEBUFFER_OPERATION", + "37442": "CONTEXT_LOST_WEBGL" + }; + var webglAvailability = null; // eslint-disable-next-line @typescript-eslint/naming-convention + + var WebGLUtils = + /*#__PURE__*/ + function () { + function WebGLUtils() {} + + WebGLUtils.createShader = function (gl, type, source) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + + if (success) { + return shader; + } // eslint-disable-next-line + + + console.error(gl.getShaderInfoLog(shader)); + return null; + }; + + WebGLUtils.createProgram = function (gl, vertexShader, fragmentShader) { + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + var success = gl.getProgramParameter(program, gl.LINK_STATUS); + + if (success) { + return program; + } + + gl.deleteProgram(program); + return null; + }; + + WebGLUtils.initBuffer = function (gl, target + /* bind point */ + , data, itemSize, attr) { + var buffer = gl.createBuffer(); + gl.bindBuffer(target, buffer); + gl.bufferData(target, data, gl.STATIC_DRAW); + + if (buffer) { + buffer.itemSize = itemSize; + buffer.numItems = data.length / itemSize; + } + + if (attr !== undefined) { + gl.enableVertexAttribArray(attr); + gl.vertexAttribPointer(attr, buffer.itemSize, gl.FLOAT, false, 0, 0); + } + + return buffer; + }; + + WebGLUtils.getWebglContext = function (canvas, userContextAttributes) { + var e_1, _a; + + var webglIdentifiers = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + var context = null; + + var contextAttributes = __assign({ + preserveDrawingBuffer: false, + antialias: false + }, userContextAttributes); + + var onWebglcontextcreationerror = function (e) { + return e.statusMessage; + }; + + canvas.addEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + + try { + for (var webglIdentifiers_1 = __values(webglIdentifiers), webglIdentifiers_1_1 = webglIdentifiers_1.next(); !webglIdentifiers_1_1.done; webglIdentifiers_1_1 = webglIdentifiers_1.next()) { + var identifier = webglIdentifiers_1_1.value; + + try { + context = canvas.getContext(identifier, contextAttributes); + } catch (t) {} // eslint-disable-line no-empty + + + if (context) { + break; + } + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (webglIdentifiers_1_1 && !webglIdentifiers_1_1.done && (_a = webglIdentifiers_1.return)) _a.call(webglIdentifiers_1); + } finally { + if (e_1) throw e_1.error; + } + } + + canvas.removeEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + return context; + }; + + WebGLUtils.createTexture = function (gl, textureTarget) { + var texture = gl.createTexture(); + gl.bindTexture(textureTarget, texture); + gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindTexture(textureTarget, null); + return texture; + }; + /** + * Returns the webgl availability of the current browser. + * @method WebGLUtils#isWebGLAvailable + * @retuen {Boolean} isWebGLAvailable + */ + + + WebGLUtils.isWebGLAvailable = function () { + if (webglAvailability === null) { + var canvas = document.createElement("canvas"); + var webglContext = WebGLUtils.getWebglContext(canvas); + webglAvailability = !!webglContext; // webglContext Resource forced collection + + if (webglContext) { + var loseContextExtension = webglContext.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + } + + return !!webglAvailability; + }; + /** + * Returns whether webgl is stable in the current browser. + * @method WebGLUtils#isStableWebGL + * @retuen {Boolean} isStableWebGL + */ + + + WebGLUtils.isStableWebGL = function () { + var agentInfo = agent$1(); + var isStableWebgl = true; + + if (agentInfo.os.name === "android") { + var version = parseFloat(agentInfo.os.version); + + if (version <= 4.3 && version >= 1) { + isStableWebgl = false; + } else if (version === 4.4) { + if (agentInfo.browser.name !== "chrome") { + isStableWebgl = false; + } + } + } + + return isStableWebgl; + }; + + WebGLUtils.getErrorNameFromWebGLErrorCode = function (code) { + if (!(code in WEBGL_ERROR_CODE)) { + return "UNKNOWN_ERROR"; + } + + return WEBGL_ERROR_CODE[code]; + }; + /** + * This function is wrapper for texImage2D to handle exceptions on texImage2D. + * Purpose is to prevent service from being stopped by script error. + */ + + + WebGLUtils.texImage2D = function (gl, target, pixels) { + try { + gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + } catch (error) { + /* eslint-disable no-console */ + console.error("WebGLUtils.texImage2D error:", error); + /* eslint-enable no-console */ + } + }; + + WebGLUtils.getMaxTextureSize = function (gl) { + // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test + return gl.getParameter(gl.MAX_TEXTURE_SIZE); + }; + + return WebGLUtils; + }(); + + var agentInfo = agent$1(); + var isIE11 = agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11; + var EVENTS = { + ERROR: "error" + }; + /** + * + * Extends Component for firing errors occurs internally. + */ + + var Renderer = + /*#__PURE__*/ + function (_super) { + __extends(Renderer, _super); + + function Renderer() { + var _this = _super.call(this) || this; + + _this._forceDimension = null; + _this._pixelCanvas = null; + _this._pixelContext = null; + return _this; + } + + var __proto = Renderer.prototype; + + __proto.render = function (_a) { + var gl = _a.gl, + shaderProgram = _a.shaderProgram, + indexBuffer = _a.indexBuffer, + mvMatrix = _a.mvMatrix, + pMatrix = _a.pMatrix; + gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); + gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); + + if (indexBuffer) { + gl.drawElements(gl.TRIANGLES, indexBuffer.numItems, gl.UNSIGNED_SHORT, 0); + } + }; // Define interface for Renderers + + /** + * Following MUST BE DEFINED on Child of Renderer + * + * DATA + * + * - getVertexPositionData + * - getIndexData + * - getTextureCoordData + * + * SOURCE + * + * - getVertexShaderSource + * - getFragmentShaderSource + * + * TEXTURE + * + * - bindTexture + */ + + + __proto.getDimension = function (pixelSource) { + var width = pixelSource.naturalWidth || pixelSource.videoWidth; + var height = pixelSource.naturalHeight || pixelSource.videoHeight; + return { + width: width, + height: height + }; + }; + /** + * Update data used by shader + */ + + + __proto.updateShaderData = function (param) { + /* + * Update following data in implementation layer. + * If the data is not changed, it does not need to implement this function. + * + * - _VERTEX_POSITION_DATA + * - _TEXTURE_COORD_DATA + * - _INDEX_DATA + */ + }; + /** + * + * @param {HTMLImageElement | HTMLVideoElement} image + * @param {Object = {width, height}} forceDimension Forced dimension to resize + */ + + + __proto._initPixelSource = function (image, forceDimension) { + if (forceDimension === void 0) { + forceDimension = null; + } + + var isIE11Video = isIE11 && image instanceof HTMLVideoElement; + + if (isIE11Video || forceDimension) { + var _a = forceDimension || this.getDimension(image), + width = _a.width, + height = _a.height; + + this._pixelCanvas = document.createElement("canvas"); + this._pixelCanvas.width = width; + this._pixelCanvas.height = height; + this._pixelContext = this._pixelCanvas.getContext("2d"); + } + + this._forceDimension = forceDimension; + }; + + __proto._getPixelSource = function (image) { + if (!this._pixelCanvas) { + return image; + } + /** + * IE11 && Video + * or + * Dimension is forced (Image is larger than texture size.) + */ + + + var contentDimension = this.getDimension(image); + var textureDimension = this._forceDimension || contentDimension; + + if (this._pixelCanvas.width !== textureDimension.width) { + this._pixelCanvas.width = textureDimension.width; + } + + if (this._pixelCanvas.height !== textureDimension.height) { + this._pixelCanvas.height = textureDimension.height; + } + + if (this._forceDimension) { + this._pixelContext.drawImage(image, 0, 0, contentDimension.width, contentDimension.height, 0, 0, textureDimension.width, textureDimension.height); + } else { + this._pixelContext.drawImage(image, 0, 0); + } + + return this._pixelCanvas; + }; + + __proto._extractTileConfig = function (imageConfig) { + var tileConfig = Array.isArray(imageConfig.tileConfig) ? imageConfig.tileConfig : Array.apply(void 0, __spread(Array(6))).map(function () { + return imageConfig.tileConfig; + }); + tileConfig = tileConfig.map(function (config) { + return __assign({ + flipHorizontal: false, + rotation: 0 + }, config); + }); + return tileConfig; + }; + + __proto._triggerError = function (error) { + /* eslint-disable no-console */ + console.error("Renderer Error:", error); + /* eslint-enable no-console */ + + this.trigger(new Component.ComponentEvent(EVENTS.ERROR, { + message: typeof error === "string" ? error : error.message + })); + }; + + Renderer.EVENTS = EVENTS; + return Renderer; + }(Component); + + var CubeRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CubeRenderer, _super); + + function CubeRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeRenderer.prototype; + + CubeRenderer.extractOrder = function (imageConfig) { + return imageConfig.order || "RLUDBF"; + }; + + __proto.getVertexPositionData = function () { + CubeRenderer._VERTEX_POSITION_DATA = CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // top + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // bottom + 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + return CubeRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + if (CubeRenderer._INDEX_DATA) { + return CubeRenderer._INDEX_DATA; + } + + var indexData = []; + var vertexPositionData = this.getVertexPositionData(); + + for (var i = 0; i < vertexPositionData.length / 3; i += 4) { + indexData.push(i, i + 2, i + 1, i, i + 3, i + 2); + } + + CubeRenderer._INDEX_DATA = indexData; + return indexData; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; + var vertexOrder = "BFUDRL"; + var order = CubeRenderer.extractOrder(imageConfig); + var base = this.getVertexPositionData(); + + var tileConfig = this._extractTileConfig(imageConfig); + + var elemSize = 3; + var vertexPerTile = 4; + var trim = imageConfig.trim; + var texCoords = vertexOrder.split("").map(function (face) { + return tileConfig[order.indexOf(face)]; + }).map(function (config, i) { + var rotation = Math.floor(config.rotation / 90); + var ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2]; + + for (var r = 0; r < Math.abs(rotation); r++) { + if (config.flipHorizontal && rotation > 0 || !config.flipHorizontal && rotation < 0) { + ordermap.push(ordermap.shift()); + } else { + ordermap.unshift(ordermap.pop()); + } + } + + var elemPerTile = elemSize * vertexPerTile; + var tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile); + var tileTemp = []; + + for (var j = 0; j < vertexPerTile; j++) { + tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize); + } + + return tileTemp; + }).map(function (coord) { + return _this._shrinkCoord({ + image: image, + faceCoords: coord, + trim: trim + }); + }).reduce(function (acc, val) { + return __spread(acc, val.reduce(function (coords, coord) { + return __spread(coords, coord); + }, [])); + }, []); + return texCoords; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}"; + }; + + __proto.updateTexture = function (gl, image, imageConfig) { + var baseOrder = "RLUDBF"; + var order = CubeRenderer.extractOrder(imageConfig); + var orderMap = {}; + order.split("").forEach(function (v, i) { + orderMap[v] = i; + }); + + try { + if (image instanceof Array) { + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]); + } + } else { + var maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image); + + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + var tile = this.extractTileFromImage(image, tileIdx, maxCubeMapTextureSize); + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile); + } + } + } catch (e) { + this._triggerError(e); + } + }; + + __proto.bindTexture = function (gl, texture, image, imageConfig) { + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + this.updateTexture(gl, image, imageConfig); + }; + + __proto.getSourceTileSize = function (image) { + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var aspectRatio = width / height; + var inputTextureSize; + + if (aspectRatio === 1 / 6) { + inputTextureSize = width; + } else if (aspectRatio === 6) { + inputTextureSize = height; + } else if (aspectRatio === 2 / 3) { + inputTextureSize = width / 2; + } else { + inputTextureSize = width / 3; + } + + return inputTextureSize; + }; + + __proto.extractTileFromImage = function (image, tileIdx, outputTextureSize) { + var width = this.getDimension(image).width; + var inputTextureSize = this.getSourceTileSize(image); + var canvas = document.createElement("canvas"); + canvas.width = outputTextureSize; + canvas.height = outputTextureSize; + var context = canvas.getContext("2d"); + var tilePerRow = width / inputTextureSize; + var x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow); + var y = Math.floor(tileIdx / tilePerRow) * inputTextureSize; + context.drawImage(image, x, y, inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize); + return canvas; + }; + + __proto.getMaxCubeMapTextureSize = function (gl, image) { + var agentInfo = agent$1(); + var maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); + var imageWidth = this.getSourceTileSize(image); + + if (agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11) { + if (!util.isPowerOfTwo(imageWidth)) { + for (var i = 1; i < maxCubeMapTextureSize; i *= 2) { + if (i < imageWidth) { + continue; + } else { + imageWidth = i; + break; + } + } + } + } + + if (agentInfo.os.name === "ios") { + var majorVersion = agentInfo.os.majorVersion; // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다. + + if (majorVersion === 9) { + imageWidth = 1024; + } // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다. + + + if (majorVersion === 8) { + imageWidth = 512; + } + } // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수 + + + return Math.min(maxCubeMapTextureSize, imageWidth); + }; + + __proto._shrinkCoord = function (coordData) { + var image = coordData.image, + faceCoords = coordData.faceCoords, + trim = coordData.trim; + var inputTextureSize = Array.isArray(image) ? this.getDimension(image[0]).width : this.getSourceTileSize(image); // Shrink by "trim" px + + var SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize); + var axisMultipliers = [0, 1, 2].map(function (axisIndex) { + var axisDir = util.sign(faceCoords[0][axisIndex]); + var notSameDir = faceCoords.some(function (coord) { + return util.sign(coord[axisIndex]) !== axisDir; + }); + return notSameDir; + }).map(function (notSameDir) { + return notSameDir ? SHRINK_MULTIPLIER : 1; + }); + return faceCoords.map(function (coords) { + return coords.map(function (coord, axisIndex) { + return coord * axisMultipliers[axisIndex]; + }); + }); + }; + + CubeRenderer._VERTEX_POSITION_DATA = null; + CubeRenderer._INDEX_DATA = null; + return CubeRenderer; + }(Renderer); + + var CubeStripRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CubeStripRenderer, _super); + + function CubeStripRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeStripRenderer.prototype; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"; + }; + + __proto.getVertexPositionData = function () { + if (!this._vertices) { + this._vertices = [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + } + + return this._vertices; + }; + + __proto.getIndexData = function () { + var _this = this; // TODO: 한번만 계산하도록 수정하기 + + + var indices = function () { + var indexData = []; + + for (var i = 0; i < _this._vertices.length / 3; i += 4) { + indexData.push(i, i + 1, i + 2, i, i + 2, i + 3); + } + + return indexData; + }(); + + return indices; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; // TODO: make it cols, rows as config. + + var cols = 3; + var rows = 2; + var textureSize = this.getDimension(image); + var trim = imageConfig.trim; + var order = imageConfig.order || "RLUDFB"; + var coords = []; // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다. + + for (var r = rows - 1; r >= 0; r--) { + for (var c = 0; c < cols; c++) { + var coord = [c / cols, r / rows, (c + 1) / cols, r / rows, (c + 1) / cols, (r + 1) / rows, c / cols, (r + 1) / rows]; + coords.push(coord); + } + } + + var tileConfigs = this._extractTileConfig(imageConfig); // Transform Coord By Flip & Rotation + + + coords = coords // shrink coord to avoid pixel bleeding + .map(function (coord) { + return _this._shrinkCoord(coord, textureSize, trim); + }).map(function (coord, i) { + return _this._transformCoord(coord, tileConfigs[i]); + }); // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치 + + return "BFUDRL".split("").map(function (face) { + return order.indexOf(face); + }).map(function (index) { + return coords[index]; + }).reduce(function (acc, val) { + return acc.concat(val); + }, []); + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto._transformCoord = function (coord, tileConfig) { + var newCoord = coord.slice(); + + if (tileConfig.flipHorizontal) { + newCoord = this._flipHorizontalCoord(newCoord); + } + + if (tileConfig.rotation) { + newCoord = this._rotateCoord(newCoord, tileConfig.rotation); + } + + return newCoord; + }; + + __proto._shrinkCoord = function (coord, textureSize, trim) { + var width = textureSize.width, + height = textureSize.height; // Shrink by "trim" px + + var SHRINK_Y = trim * (1 / height); + var SHRINK_X = trim * (1 / width); + return [coord[0] + SHRINK_X, coord[1] + SHRINK_Y, coord[2] - SHRINK_X, coord[3] + SHRINK_Y, coord[4] - SHRINK_X, coord[5] - SHRINK_Y, coord[6] + SHRINK_X, coord[7] - SHRINK_Y]; + }; + + __proto._rotateCoord = function (coord, rotationAngle) { + var SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord. + + var shiftCount = Math.floor(rotationAngle / 90) % 4; + + if (shiftCount === 0) { + return coord; + } + + var moved; + var rotatedCoord = []; + + if (shiftCount > 0) { + moved = coord.splice(0, shiftCount * SIZE); + rotatedCoord = coord.concat(moved); + } else { + moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE); + rotatedCoord = moved.concat(coord); + } + + return rotatedCoord; + }; + + __proto._flipHorizontalCoord = function (coord) { + return [coord[2], coord[3], coord[0], coord[1], coord[6], coord[7], coord[4], coord[5]]; + }; + + return CubeStripRenderer; + }(Renderer); + + var latitudeBands = 60; + var longitudeBands = 60; + var radius = 2; + var ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + var textureCoordData = []; + var vertexPositionData = []; + var indexData = []; + var latIdx; + var lngIdx; + + for (latIdx = 0; latIdx <= latitudeBands; latIdx++) { + var theta = (latIdx / latitudeBands - 0.5) * Math.PI; + var sinTheta = Math.sin(theta); + var cosTheta = Math.cos(theta); + + for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) { + var phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + var sinPhi = Math.sin(phi); + var cosPhi = Math.cos(phi); + var x = cosPhi * cosTheta; + var y = sinTheta; + var z = sinPhi * cosTheta; + var u = lngIdx / longitudeBands; + var v = latIdx / latitudeBands; + textureCoordData.push(u, v); + vertexPositionData.push(radius * x, radius * y, radius * z); + + if (lngIdx !== longitudeBands && latIdx !== latitudeBands) { + var a = latIdx * (longitudeBands + 1) + lngIdx; + var b = a + longitudeBands + 1; + indexData.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + + var SphereRenderer = + /*#__PURE__*/ + function (_super) { + __extends(SphereRenderer, _super); + + function SphereRenderer(format) { + var _this = _super.call(this) || this; + + _this._stereoFormat = format; + return _this; + } + + var __proto = SphereRenderer.prototype; + + __proto.render = function (ctx) { + var gl = ctx.gl, + shaderProgram = ctx.shaderProgram; + var leftEyeScaleOffset; + var rightEyeScaleOffset; + + switch (this._stereoFormat) { + case STEREO_FORMAT.TOP_BOTTOM: + leftEyeScaleOffset = [1, 0.5, 0, 0]; + rightEyeScaleOffset = [1, 0.5, 0, 0.5]; + break; + + case STEREO_FORMAT.LEFT_RIGHT: + leftEyeScaleOffset = [0.5, 1, 0, 0]; + rightEyeScaleOffset = [0.5, 1, 0.5, 0]; + break; + + default: + leftEyeScaleOffset = [1, 1, 0, 0]; + rightEyeScaleOffset = [1, 1, 0, 0]; + } + + var uTexScaleOffset = gl.getUniformLocation(shaderProgram, "uTexScaleOffset"); + gl.uniform4fv(uTexScaleOffset, __spread(leftEyeScaleOffset, rightEyeScaleOffset)); + + _super.prototype.render.call(this, ctx); + }; + + __proto.getVertexPositionData = function () { + return SphereRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return SphereRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return SphereRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + SphereRenderer._VERTEX_POSITION_DATA = vertexPositionData; + SphereRenderer._TEXTURE_COORD_DATA = textureCoordData; + SphereRenderer._INDEX_DATA = indexData; + return SphereRenderer; + }(Renderer); + + var MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6; + var longitudeBands$1 = 60; + var textureCoordData$1 = []; + var vertexPositionData$1 = []; + var indexData$1 = []; + + var CylinderRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CylinderRenderer, _super); + + function CylinderRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CylinderRenderer.prototype; + + __proto.getVertexPositionData = function () { + return CylinderRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return CylinderRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return CylinderRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + var resizeDimension; + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device texture limit(" + maxSize + "))"); // Request resizing texture. + + /** + * TODO: Is it need to apply on another projection type? + */ + + + resizeDimension = width > height ? { + width: maxSize, + height: maxSize * height / width + } : { + width: maxSize * width / height, + height: maxSize + }; + } // Pixel Source for IE11 & Video or resizing needed + + + this._initPixelSource(image, resizeDimension); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto.updateShaderData = function (_a) { + var _b = _a.imageAspectRatio, + imageAspectRatio = _b === void 0 ? MIN_ASPECT_RATIO_FOR_FULL_PANORAMA : _b; + var lngIdx; + var cylinderMaxRadian; + var halfCylinderY; + var rotated; + var aspectRatio; // Exception case: orientation is rotated. + + if (imageAspectRatio < 1) { + /** + * If rotated is true, we assume that image is rotated counter clockwise. + * TODO: If there's other rotation, it is need to implement by each rotation. + */ + rotated = true; + aspectRatio = 1 / imageAspectRatio; + } else { + rotated = false; + aspectRatio = imageAspectRatio; + } + + if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) { + var fov = 360 / aspectRatio; + cylinderMaxRadian = 2 * Math.PI; // 360 deg + + halfCylinderY = Math.tan(glMatrix.glMatrix.toRadian(fov / 2)); + } else { + cylinderMaxRadian = aspectRatio; + halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1. + } // initialize shader data before update + + + textureCoordData$1.length = 0; + vertexPositionData$1.length = 0; + indexData$1.length = 0; + var CYLIDER_Y = [-halfCylinderY, halfCylinderY]; + var startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360) + // console.log("cylinderMaxRadian:", glMatrix.toDegree(cylinderMaxRadian), "CYLIDER_Y", CYLIDER_Y, "start angle", glMatrix.toDegree(startAngleForCenterAlign)); + + for (var yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength + /* bottom & top */ + ; yIdx++) { + for (lngIdx = 0; lngIdx <= longitudeBands$1; lngIdx++) { + var angle = startAngleForCenterAlign + lngIdx / longitudeBands$1 * cylinderMaxRadian; + var x = Math.cos(angle); + var y = CYLIDER_Y[yIdx]; + var z = Math.sin(angle); + var u = void 0; + var v = void 0; + + if (rotated) { + // Rotated 90 degree (counter clock wise) + u = 1 - yIdx; // yLength - yIdx; + + v = lngIdx / longitudeBands$1; + } else { + // // Normal case (Not rotated) + u = lngIdx / longitudeBands$1; + v = yIdx; + } + + textureCoordData$1.push(u, v); + vertexPositionData$1.push(x, y, z); + + if (yIdx === 0 && lngIdx < longitudeBands$1) { + var a = lngIdx; + var b = a + longitudeBands$1 + 1; + indexData$1.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + }; + + CylinderRenderer._VERTEX_POSITION_DATA = vertexPositionData$1; + CylinderRenderer._TEXTURE_COORD_DATA = textureCoordData$1; + CylinderRenderer._INDEX_DATA = indexData$1; + return CylinderRenderer; + }(Renderer); + + var VR_DISPLAY_PRESENT_CHANGE = "vrdisplaypresentchange"; + var DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1]; + var DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1]; + var EYES = { + LEFT: "left", + RIGHT: "right" + }; + + var VRManager = + /*#__PURE__*/ + function () { + function VRManager() { + var _this = this; + + this.destroy = function () { + var vrDisplay = _this._vrDisplay; + + _this.removeEndCallback(_this.destroy); + + if (vrDisplay && vrDisplay.isPresenting) { + void vrDisplay.exitPresent(); + } + + _this._clear(); + }; + + this._frameData = new window.VRFrameData(); + + this._clear(); + } + + var __proto = VRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._vrDisplay; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function () { + return Boolean(this._vrDisplay); + }; + + __proto.beforeRender = function (gl) { + // Render to the default backbuffer + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + }; + + __proto.afterRender = function () { + this._vrDisplay.submitFrame(); + }; + + __proto.getEyeParams = function (gl) { + var display = this._vrDisplay; + var halfWidth = gl.drawingBufferWidth * 0.5; + var height = gl.drawingBufferHeight; + var frameData = this._frameData; + display.getFrameData(frameData); + var leftMVMatrix = frameData.leftViewMatrix; + var rightMVMatrix = frameData.rightViewMatrix; + glMatrix.mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset); + glMatrix.mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset); + return [{ + viewport: [0, 0, halfWidth, height], + mvMatrix: leftMVMatrix, + pMatrix: frameData.leftProjectionMatrix + }, { + viewport: [halfWidth, 0, halfWidth, height], + mvMatrix: rightMVMatrix, + pMatrix: frameData.rightProjectionMatrix + }]; + }; + + __proto.isPresenting = function () { + return Boolean(this._vrDisplay && this._vrDisplay.isPresenting); + }; + + __proto.addEndCallback = function (callback) { + window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.removeEndCallback = function (callback) { + window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.requestPresent = function (canvas) { + var _this = this; + + return navigator.getVRDisplays().then(function (displays) { + var vrDisplay = displays.length && displays[0]; + + if (!vrDisplay) { + return Promise$1.reject(new Error("No displays available.")); + } + + if (!vrDisplay.capabilities.canPresent) { + return Promise$1.reject(new Error("Display lacking capability to present.")); + } + + return vrDisplay.requestPresent([{ + source: canvas + }]).then(function () { + var leftEye = vrDisplay.getEyeParameters(EYES.LEFT); + var rightEye = vrDisplay.getEyeParameters(EYES.RIGHT); + canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2; + canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight); + + _this._setDisplay(vrDisplay); + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setDisplay = function (vrDisplay) { + this._vrDisplay = vrDisplay; + var layers = vrDisplay.getLayers(); + + if (layers.length) { + var layer = layers[0]; + this._leftBounds = layer.leftBounds; + this._rightBounds = layer.rightBounds; + } + + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._vrDisplay = null; + this._leftBounds = DEFAULT_LEFT_BOUNDS; + this._rightBounds = DEFAULT_RIGHT_BOUNDS; + this._yawOffset = 0; + }; + + return VRManager; + }(); + + var XR_REFERENCE_SPACE = "local"; + + var XRManager = + /*#__PURE__*/ + function () { + function XRManager(options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + this.destroy = function () { + var xrSession = _this._xrSession; + + _this.removeEndCallback(_this.destroy); + + if (xrSession) { + // Capture to avoid errors + xrSession.end().then(function () { + return void 0; + }, function () { + return void 0; + }); + } + + _this._clear(); + }; + + this._clear(); + + this._options = options; + } + + var __proto = XRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._xrSession; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function (frame) { + var pose = frame.getViewerPose(this._xrRefSpace); + return Boolean(pose); + }; + + __proto.beforeRender = function (gl, frame) { + var session = frame.session; + var baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + }; // eslint-disable-next-line @typescript-eslint/no-empty-function + + + __proto.afterRender = function () {}; + + __proto.getEyeParams = function (gl, frame) { + var _this = this; + + var session = frame.session; + var pose = frame.getViewerPose(this._xrRefSpace); + + if (!pose) { + // Can't render + return null; + } + + var glLayer = session.renderState.baseLayer; + return pose.views.map(function (view) { + var viewport = glLayer.getViewport(view); + var mvMatrix = view.transform.inverse.matrix; + + if (IS_SAFARI_ON_DESKTOP) { + glMatrix.mat4.rotateX(mvMatrix, mvMatrix, glMatrix.glMatrix.toRadian(180)); + } + + glMatrix.mat4.rotateY(mvMatrix, mvMatrix, _this._yawOffset); + return { + viewport: [viewport.x, viewport.y, viewport.width, viewport.height], + mvMatrix: mvMatrix, + pMatrix: view.projectionMatrix + }; + }); + }; + + __proto.isPresenting = function () { + return this._presenting; + }; + + __proto.addEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.addEventListener("end", callback); + }; + + __proto.removeEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.removeEventListener("end", callback); + }; + + __proto.requestPresent = function (canvas, gl) { + return __awaiter(this, void 0, void 0, function () { + var options, attributes; + + var _this = this; + + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = merge({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + attributes = gl.getContextAttributes(); + if (!(attributes && attributes.xrCompatible !== true)) return [3 + /*break*/ + , 2]; + return [4 + /*yield*/ + , gl.makeXRCompatible()]; + + case 1: + _a.sent(); + + _a.label = 2; + + case 2: + return [2 + /*return*/ + , navigator.xr.requestSession("immersive-vr", options).then(function (session) { + var xrLayer = new window.XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + return session.requestReferenceSpace(XR_REFERENCE_SPACE).then(function (refSpace) { + _this._setSession(session, xrLayer, refSpace); + }); + })]; + } + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setSession = function (session, xrLayer, refSpace) { + this._xrSession = session; + this._xrLayer = xrLayer; + this._xrRefSpace = refSpace; + this._presenting = true; + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._xrSession = null; + this._xrLayer = null; + this._xrRefSpace = null; + this._presenting = false; + this._yawOffset = 0; + this._options = {}; + }; + + return XRManager; + }(); + + var WebGLAnimator = + /*#__PURE__*/ + function () { + function WebGLAnimator() { + var _this = this; + /** + * There can be more than 1 argument when we use XRSession's raf + */ + + + this._onLoop = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + _this._callback.apply(_this, __spread(args)); + + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + }; + /** + * MacOS X Safari Bug Fix + * This code guarantees that rendering should be occurred. + * + * In MacOS X(10.14.2), Safari (12.0.2) + * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term + * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms) + * So browser cannot render the frame and may be freezing. + */ + + + this._onLoopNextTick = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + var before = performance.now(); + + _this._callback.apply(_this, __spread(args)); + + var diff = performance.now() - before; + + if (_this._rafTimer >= 0) { + clearTimeout(_this._rafTimer); + _this._rafTimer = -1; + } + /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */ + + + if (diff < 16) { + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + } else { + /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */ + _this._rafTimer = window.setTimeout(_this._onLoop, 0); + } + }; + + this._callback = null; + this._context = window; + this._rafId = -1; + this._rafTimer = -1; + } + + var __proto = WebGLAnimator.prototype; + + __proto.setCallback = function (callback) { + this._callback = callback; + }; + + __proto.setContext = function (context) { + this._context = context; + }; + + __proto.start = function () { + var context = this._context; + var callback = this._callback; // No context / callback set + + if (!context || !callback) return; // Animation already started + + if (this._rafId >= 0 || this._rafTimer >= 0) return; + + if (IS_SAFARI_ON_DESKTOP) { + this._rafId = context.requestAnimationFrame(this._onLoopNextTick); + } else { + this._rafId = context.requestAnimationFrame(this._onLoop); + } + }; + + __proto.stop = function () { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + + this._rafId = -1; + this._rafTimer = -1; + }; + + return WebGLAnimator; + }(); + + var ImageType = PROJECTION_TYPE; // eslint-disable-next-line @typescript-eslint/naming-convention + + var DEVICE_PIXEL_RATIO = devicePixelRatio || 1; // DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다. + + if (DEVICE_PIXEL_RATIO > 2) { + DEVICE_PIXEL_RATIO = 2; + } // define custom events name + + /** + * TODO: how to manage events/errortype with PanoViewer + * + * I think renderer events should be seperated from viewer events although it has same name. + */ + + + var EVENTS$1 = { + BIND_TEXTURE: "bindTexture", + IMAGE_LOADED: "imageLoaded", + ERROR: "error", + RENDERING_CONTEXT_LOST: "renderingContextLost", + RENDERING_CONTEXT_RESTORE: "renderingContextRestore" + }; + var ERROR_TYPE$1 = { + INVALID_DEVICE: 10, + NO_WEBGL: 11, + FAIL_IMAGE_LOAD: 12, + RENDERER_ERROR: 13 + }; + + var PanoImageRenderer = + /*#__PURE__*/ + function (_super) { + __extends(PanoImageRenderer, _super); + + function PanoImageRenderer(image, width, height, isVideo, container, canvasClass, sphericalConfig, renderingContextAttributes) { + var _this = // Super constructor + _super.call(this) || this; + + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + + _this.exitVR = function () { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; + if (!vr) return; + vr.removeEndCallback(_this.exitVR); + vr.destroy(); + _this._vr = null; // Restore canvas & context on iOS + + if (IS_IOS) { + _this._restoreStyle(); + } + + _this.updateViewportDimensions(_this.width, _this.height); + + _this._updateViewport(); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + _this._bindBuffers(); + + _this._shouldForceDraw = true; + animator.stop(); + animator.setContext(window); + animator.setCallback(_this._render.bind(_this)); + animator.start(); + }; + + _this._renderStereo = function (time, frame) { + var e_1, _a; + + var vr = _this._vr; + var gl = _this.context; + var eyeParams = vr.getEyeParams(gl, frame); + if (!eyeParams) return; + vr.beforeRender(gl, frame); + + try { + // Render both eyes + for (var _b = __values([0, 1]), _c = _b.next(); !_c.done; _c = _b.next()) { + var eyeIndex = _c.value; + var eyeParam = eyeParams[eyeIndex]; + _this.mvMatrix = eyeParam.mvMatrix; + _this.pMatrix = eyeParam.pMatrix; + gl.viewport.apply(gl, __spread(eyeParam.viewport)); + gl.uniform1f(_this.shaderProgram.uEye, eyeIndex); + + _this._bindBuffers(); + + _this._draw(); + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + + vr.afterRender(); + }; + + _this._onFirstVRFrame = function (time, frame) { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; // If rendering is not ready, wait for next frame + + if (!vr.canRender(frame)) return; + var minusZDir = glMatrix.vec3.fromValues(0, 0, -1); + var eyeParam = vr.getEyeParams(gl, frame)[0]; // Extract only rotation + + var mvMatrix = glMatrix.mat3.fromMat4(glMatrix.mat3.create(), eyeParam.mvMatrix); + var pMatrix = glMatrix.mat3.fromMat4(glMatrix.mat3.create(), eyeParam.pMatrix); + var mvInv = glMatrix.mat3.invert(glMatrix.mat3.create(), mvMatrix); + var pInv = glMatrix.mat3.invert(glMatrix.mat3.create(), pMatrix); + var viewDir = glMatrix.vec3.transformMat3(glMatrix.vec3.create(), minusZDir, pInv); + glMatrix.vec3.transformMat3(viewDir, viewDir, mvInv); + var yawOffset = util.yawOffsetBetween(viewDir, glMatrix.vec3.fromValues(0, 0, 1)); + + if (yawOffset === 0) { + // If the yawOffset is exactly 0, then device sensor is not ready + // So read it again until it has any value in it + return; + } + + vr.setYawOffset(yawOffset); + animator.setCallback(_this._renderStereo); + }; + + _this.sphericalConfig = sphericalConfig; + _this.fieldOfView = sphericalConfig.fieldOfView; + _this.width = width; + _this.height = height; + _this._lastQuaternion = null; + _this._lastYaw = null; + _this._lastPitch = null; + _this._lastFieldOfView = null; + _this.pMatrix = glMatrix.mat4.create(); + _this.mvMatrix = glMatrix.mat4.create(); // initialzie pMatrix + + glMatrix.mat4.perspective(_this.pMatrix, glMatrix.glMatrix.toRadian(_this.fieldOfView), width / height, 0.1, 100); + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + _this.canvas = _this._initCanvas(container, canvasClass, width, height); + + _this._setDefaultCanvasStyle(); + + _this._wrapper = null; // canvas wrapper + + _this._wrapperOrigStyle = null; + _this._renderingContextAttributes = renderingContextAttributes; + _this._image = null; + _this._imageConfig = null; + _this._imageIsReady = false; + _this._shouldForceDraw = false; + _this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still. + + _this._onContentLoad = _this._onContentLoad.bind(_this); + _this._onContentError = _this._onContentError.bind(_this); + _this._animator = new WebGLAnimator(); // VR/XR manager + + _this._vr = null; + + if (image) { + _this.setImage({ + image: image, + imageType: sphericalConfig.imageType, + isVideo: isVideo, + cubemapConfig: sphericalConfig.cubemapConfig + }); + } + + return _this; + } // FIXME: Please refactor me to have more loose connection to yawpitchcontrol + + + var __proto = PanoImageRenderer.prototype; + + __proto.setYawPitchControl = function (yawPitchControl) { + this._yawPitchControl = yawPitchControl; + }; + + __proto.getContent = function () { + return this._image; + }; + + __proto.setImage = function (_a) { + var image = _a.image, + imageType = _a.imageType, + _b = _a.isVideo, + isVideo = _b === void 0 ? false : _b, + cubemapConfig = _a.cubemapConfig; + this._imageIsReady = false; + this._isVideo = isVideo; + this._imageConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only */ + order: imageType === ImageType.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, cubemapConfig); + + this._setImageType(imageType); + + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._contentLoader = new ImReady().on("ready", this._onContentLoad).on("error", this._onContentError); + + if (isVideo) { + this._image = toVideoElement(image); + + this._contentLoader.check([this._image]); + + this._keepUpdate = true; + } else { + this._image = toImageElement(image); + + this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]); + + this._keepUpdate = false; + } + }; + + __proto.isImageLoaded = function () { + return !!this._image && this._imageIsReady && (!this._isVideo || this._image.readyState >= 2 + /* HAVE_CURRENT_DATA */ + ); + }; + + __proto.bindTexture = function () { + var _this = this; + + return new Promise$1(function (res, rej) { + var contentLoader = _this._contentLoader; + + if (!_this._image) { + return rej("Image is not defined"); + } + + if (!contentLoader) { + return rej("ImageLoader is not initialized"); + } + + if (contentLoader.isReady()) { + _this._bindTexture(); + + res(); + } else { + contentLoader.check(Array.isArray(_this._image) ? _this._image : [_this._image]); + contentLoader.once("ready", function (e) { + if (e.errorCount > 0) { + rej("Failed to load images."); + } else { + _this._bindTexture(); + + res(); + } + }); + } + }); + }; // 부모 엘리먼트에 canvas 를 붙임 + + + __proto.attachTo = function (parentElement) { + if (!this._hasExternalCanvas) { + this.detach(); + parentElement.appendChild(this.canvas); + } + + this._wrapper = parentElement; + }; + + __proto.forceContextLoss = function () { + if (this.hasRenderingContext()) { + var loseContextExtension = this.context.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + }; // 부모 엘리먼트에서 canvas 를 제거 + + + __proto.detach = function () { + if (!this._hasExternalCanvas && this.canvas.parentElement) { + this.canvas.parentElement.removeChild(this.canvas); + } + }; + + __proto.destroy = function () { + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._animator.stop(); + + this.detach(); + this.forceContextLoss(); + this.off(); + this.canvas.removeEventListener("webglcontextlost", this._onWebglcontextlost); + this.canvas.removeEventListener("webglcontextrestored", this._onWebglcontextrestored); + }; + + __proto.hasRenderingContext = function () { + var ctx = this.context; + + if (!ctx || ctx.isContextLost() || !ctx.getProgramParameter(this.shaderProgram, ctx.LINK_STATUS)) { + return false; + } + + return true; + }; + + __proto.updateFieldOfView = function (fieldOfView) { + this.fieldOfView = fieldOfView; + + this._updateViewport(); + }; + + __proto.updateViewportDimensions = function (width, height) { + var viewPortChanged = false; + this.width = width; + this.height = height; + var w = width * DEVICE_PIXEL_RATIO; + var h = height * DEVICE_PIXEL_RATIO; + + if (w !== this.canvas.width) { + this.canvas.width = w; + viewPortChanged = true; + } + + if (h !== this.canvas.height) { + this.canvas.height = h; + viewPortChanged = true; + } + + if (!viewPortChanged) { + return; + } + + this._updateViewport(); + + this._shouldForceDraw = true; + }; + + __proto.keepUpdate = function (doUpdate) { + if (doUpdate && this.isImageLoaded() === false) { + // Force to draw a frame after image is loaded on render() + this._shouldForceDraw = true; + } + + this._keepUpdate = doUpdate; + }; + + __proto.startRender = function () { + this._animator.setCallback(this._render.bind(this)); + + this._animator.start(); + }; + + __proto.stopRender = function () { + this._animator.stop(); + }; + + __proto.renderWithQuaternion = function (quaternion, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastQuaternion && glMatrix.quat.exactEquals(this._lastQuaternion, quaternion) && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // updatefieldOfView only if fieldOfView is changed. + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + this.mvMatrix = glMatrix.mat4.fromQuat(glMatrix.mat4.create(), quaternion); + + this._draw(); + + this._lastQuaternion = glMatrix.quat.clone(quaternion); + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + + __proto.renderWithYawPitch = function (yaw, pitch, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastYaw !== null && this._lastYaw === yaw && this._lastPitch !== null && this._lastPitch === pitch && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출 + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + glMatrix.mat4.identity(this.mvMatrix); + glMatrix.mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.glMatrix.toRadian(pitch)); + glMatrix.mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.glMatrix.toRadian(yaw)); + + this._draw(); + + this._lastYaw = yaw; + this._lastPitch = pitch; + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + /** + * Returns projection renderer by each type + */ + + + __proto.getProjectionRenderer = function () { + return this._renderer; + }; + /** + * @return Promise + */ + + + __proto.enterVR = function (options) { + var vr = this._vr; + + if (!WEBXR_SUPPORTED && !navigator.getVRDisplays) { + return Promise$1.reject("VR is not available on this browser."); + } + + if (vr && vr.isPresenting()) { + return Promise$1.resolve("VR already enabled."); + } + + return this._requestPresent(options); + }; + + __proto._setImageType = function (imageType) { + var _this = this; + + if (!imageType || this._imageType === imageType) { + return; + } + + this._imageType = imageType; + this._isCubeMap = imageType === ImageType.CUBEMAP; + + if (this._renderer) { + this._renderer.off(); + } + + switch (imageType) { + case ImageType.CUBEMAP: + this._renderer = new CubeRenderer(); + break; + + case ImageType.CUBESTRIP: + this._renderer = new CubeStripRenderer(); + break; + + case ImageType.PANORAMA: + this._renderer = new CylinderRenderer(); + break; + + case ImageType.STEREOSCOPIC_EQUI: + this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat); + break; + + default: + this._renderer = new SphereRenderer(STEREO_FORMAT.NONE); + break; + } + + this._renderer.on(Renderer.EVENTS.ERROR, function (e) { + _this.trigger(new Component.ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.RENDERER_ERROR, + message: e.message + })); + }); + + this._initWebGL(); + }; + + __proto._initCanvas = function (container, canvasClass, width, height) { + var canvasInContainer = container.querySelector("." + canvasClass); + + var canvas = canvasInContainer || this._createCanvas(canvasClass); + + this._hasExternalCanvas = !!canvasInContainer; + canvas.width = width; + canvas.height = height; + this._onWebglcontextlost = this._onWebglcontextlost.bind(this); + this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this); + canvas.addEventListener("webglcontextlost", this._onWebglcontextlost); + canvas.addEventListener("webglcontextrestored", this._onWebglcontextrestored); + return canvas; + }; + + __proto._createCanvas = function (className) { + var canvas = document.createElement("canvas"); + canvas.className = className; + return canvas; + }; + + __proto._setDefaultCanvasStyle = function () { + var canvas = this.canvas; + canvas.style.bottom = "0"; + canvas.style.left = "0"; + canvas.style.right = "0"; + canvas.style.top = "0"; + canvas.style.margin = "auto"; + canvas.style.maxHeight = "100%"; + canvas.style.maxWidth = "100%"; + canvas.style.outline = "none"; + canvas.style.position = "absolute"; + }; + + __proto._onContentError = function () { + this._imageIsReady = false; + this._image = null; + this.trigger(new Component.ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.FAIL_IMAGE_LOAD, + message: "failed to load image" + })); + return false; + }; + + __proto._triggerContentLoad = function () { + this.trigger(new Component.ComponentEvent(EVENTS$1.IMAGE_LOADED, { + content: this._image, + isVideo: this._isVideo, + projectionType: this._imageType + })); + }; + + __proto._onContentLoad = function (e) { + if (e.errorCount > 0) return; + this._imageIsReady = true; + + this._triggerContentLoad(); + }; + + __proto._initShaderProgram = function () { + var gl = this.context; + + if (this.shaderProgram) { + gl.deleteProgram(this.shaderProgram); + this.shaderProgram = null; + } + + var renderer = this._renderer; + var vsSource = renderer.getVertexShaderSource(); + var fsSource = renderer.getFragmentShaderSource(); + var vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource); + var fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource); + var shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader); + + if (!shaderProgram) { + throw new Error("Failed to initialize shaders: " + WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())); + } + + gl.useProgram(shaderProgram); + shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); + shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); + shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); + shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); + shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); + shaderProgram.uEye = gl.getUniformLocation(shaderProgram, "uEye"); + gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); + gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); // clear buffer + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); // Use TEXTURE0 + + gl.uniform1i(shaderProgram.samplerUniform, 0); + this.shaderProgram = shaderProgram; + }; + + __proto._onWebglcontextlost = function (e) { + e.preventDefault(); + this.trigger(new Component.ComponentEvent(EVENTS$1.RENDERING_CONTEXT_LOST)); + }; + + __proto._onWebglcontextrestored = function () { + this._initWebGL(); + + this.trigger(new Component.ComponentEvent(EVENTS$1.RENDERING_CONTEXT_RESTORE)); + }; + + __proto._updateViewport = function () { + glMatrix.mat4.perspective(this.pMatrix, glMatrix.glMatrix.toRadian(this.fieldOfView), this.canvas.width / this.canvas.height, 0.1, 100); + this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight); + }; + + __proto._initWebGL = function () { + var gl; // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed. + + try { + this._initRenderingContext(); + + gl = this.context; + this.updateViewportDimensions(this.width, this.height); + + this._initShaderProgram(); + } catch (e) { + this.trigger(new Component.ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.NO_WEBGL, + message: "no webgl support" + })); + this.destroy(); + console.error(e); // eslint-disable-line no-console + + return; + } // 캔버스를 투명으로 채운다. + + + gl.clearColor(0, 0, 0, 0); + var textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D; + + if (this.texture) { + gl.deleteTexture(this.texture); + } + + this.texture = WebGLUtils.createTexture(gl, textureTarget); + + if (this._imageType === ImageType.CUBESTRIP) { + // TODO: Apply following options on other projection type. + gl.enable(gl.CULL_FACE); // gl.enable(gl.DEPTH_TEST); + } + }; + + __proto._initRenderingContext = function () { + if (this.hasRenderingContext()) { + return; + } + + if (!window.WebGLRenderingContext) { + throw new Error("WebGLRenderingContext not available."); + } + + this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes); + + if (!this.context) { + throw new Error("Failed to acquire 3D rendering context"); + } + }; + + __proto._initBuffers = function () { + var image = this._image; + + var vertexPositionData = this._renderer.getVertexPositionData(); + + var indexData = this._renderer.getIndexData(); + + var textureCoordData = this._renderer.getTextureCoordData({ + image: image, + imageConfig: this._imageConfig + }); + + var gl = this.context; + this.vertexBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3, this.shaderProgram.vertexPositionAttribute); + this.indexBuffer = WebGLUtils.initBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1); + this.textureCoordBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2, this.shaderProgram.textureCoordAttribute); + + this._bindBuffers(); + }; + + __proto._bindTexture = function () { + // Detect if it is EAC Format while CUBESTRIP mode. + // We assume it is EAC if image is not 3/2 ratio. + if (this._imageType === ImageType.CUBESTRIP) { + var _a = this._renderer.getDimension(this._image), + width = _a.width, + height = _a.height; + + var isEAC = width && height && width / height !== 1.5 ? 1 : 0; + this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram, "uIsEAC"), isEAC); + } else if (this._imageType === ImageType.PANORAMA) { + var _b = this._renderer.getDimension(this._image), + width = _b.width, + height = _b.height; + + var imageAspectRatio = width && height && width / height; + + this._renderer.updateShaderData({ + imageAspectRatio: imageAspectRatio + }); + } // initialize shader buffers after image is loaded.(by updateShaderData) + // because buffer may be differ by image size.(eg. CylinderRenderer) + + + this._initBuffers(); + + this._renderer.bindTexture(this.context, this.texture, this._image, this._imageConfig); + + this._shouldForceDraw = true; + this.trigger(new Component.ComponentEvent(EVENTS$1.BIND_TEXTURE)); + }; + + __proto._updateTexture = function () { + this._renderer.updateTexture(this.context, this._image, this._imageConfig); + }; + + __proto._render = function () { + var yawPitchControl = this._yawPitchControl; + var fov = yawPitchControl.getFov(); + + if (yawPitchControl.shouldRenderWithQuaternion()) { + var quaternion = yawPitchControl.getQuaternion(); + this.renderWithQuaternion(quaternion, fov); + } else { + var yawPitch = yawPitchControl.getYawPitch(); + this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov); + } + }; + + __proto._bindBuffers = function () { + var gl = this.context; + var program = this.shaderProgram; + var vertexBuffer = this.vertexBuffer; + var textureCoordBuffer = this.textureCoordBuffer; + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.enableVertexAttribArray(program.vertexPositionAttribute); + gl.vertexAttribPointer(program.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); + gl.enableVertexAttribArray(program.textureCoordAttribute); + gl.vertexAttribPointer(program.textureCoordAttribute, textureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); + }; + + __proto._draw = function () { + if (this._isVideo && this._keepUpdate) { + this._updateTexture(); + } + + this._renderer.render({ + gl: this.context, + shaderProgram: this.shaderProgram, + indexBuffer: this.indexBuffer, + mvMatrix: this.mvMatrix, + pMatrix: this.pMatrix + }); + }; + + __proto._requestPresent = function (options) { + var _this = this; + + var gl = this.context; + var canvas = this.canvas; + var animator = this._animator; + this._vr = WEBXR_SUPPORTED ? new XRManager(options) : new VRManager(); + var vr = this._vr; + animator.stop(); + return new Promise$1(function (resolve, reject) { + vr.requestPresent(canvas, gl).then(function () { + vr.addEndCallback(_this.exitVR); + animator.setContext(vr.context); + animator.setCallback(_this._onFirstVRFrame); + + if (IS_IOS) { + _this._setWrapperFullscreen(); + } + + _this._shouldForceDraw = true; + animator.start(); + resolve("success"); + }).catch(function (e) { + vr.destroy(); + _this._vr = null; + animator.start(); + reject(e); + }); + }); + }; + + __proto._setWrapperFullscreen = function () { + var wrapper = this._wrapper; + if (!wrapper) return; + this._wrapperOrigStyle = wrapper.getAttribute("style"); + var wrapperStyle = wrapper.style; + wrapperStyle.width = "100vw"; + wrapperStyle.height = "100vh"; + wrapperStyle.position = "fixed"; + wrapperStyle.left = "0"; + wrapperStyle.top = "0"; + wrapperStyle.zIndex = "9999"; + }; + + __proto._restoreStyle = function () { + var wrapper = this._wrapper; + var canvas = this.canvas; + if (!wrapper) return; + + if (this._wrapperOrigStyle) { + wrapper.setAttribute("style", this._wrapperOrigStyle); + } else { + wrapper.removeAttribute("style"); + } + + this._wrapperOrigStyle = null; // Restore canvas style + + canvas.removeAttribute("style"); + + this._setDefaultCanvasStyle(); + }; + + PanoImageRenderer.EVENTS = EVENTS$1; + PanoImageRenderer.ERROR_TYPE = ERROR_TYPE$1; + return PanoImageRenderer; + }(Component); + + /** + * @memberof eg.view360 + * @extends eg.Component + * PanoViewer + */ + + var PanoViewer = + /*#__PURE__*/ + function (_super) { + __extends(PanoViewer, _super); + /** + * @classdesc 360 media viewer + * @ko 360 미디어 뷰어 + * + * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트 + * @param options + * + * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
+ * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다. + * @param {Object} [options.cubemapConfig.order = "RLUDBF"(ProjectionType === CUBEMAP) | "RLUDFB" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서 + * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다. + * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다. + * @param {String} [options.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
+ * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위) + * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위) + * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위) + * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위) + * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위) + * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다 + * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다. + * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키 + * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE}
+ * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위 + * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위 + * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위 + * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
+ * @param {String} [options.canvasClass="view360-canvas"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * + * @example + * ``` + * // PanoViewer Creation + * // create PanoViewer with option + * var PanoViewer = eg.view360.PanoViewer; + * // Area where the image will be displayed(HTMLElement) + * var container = document.getElementById("myPanoViewer"); + * + * var panoViewer = new PanoViewer(container, { + * // If projectionType is not specified, the default is "equirectangular". + * // Specifies an image of the "equirectangular" type. + * image: "/path/to/image/image.jpg" + * }); + * ``` + * + * @example + * ``` + * // Cubemap Config Setting Example + * // For support Youtube EAC projection, You should set cubemapConfig as follows. + * cubemapConfig: { + * order: "LFRDBU", + * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}] + * } + * ``` + */ + + + function PanoViewer(container, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; // Raises the error event if webgl is not supported. + + + if (!WebGLUtils.isWebGLAvailable()) { + setTimeout(function () { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.NO_WEBGL, + message: "no webgl support" + })); + }, 0); + return _this; + } + + if (!WebGLUtils.isStableWebGL()) { + setTimeout(function () { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_DEVICE, + message: "blacklisted browser" + })); + }, 0); + return _this; + } + + if (!!options.image && !!options.video) { + setTimeout(function () { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_RESOURCE, + message: "Specifying multi resouces(both image and video) is not valid." + })); + }, 0); + return _this; + } // Check XR support at not when imported, but when created. + // This is intended to make polyfills easier to use. + + + checkXRSupport(); + _this._container = container; + _this._image = options.image || options.video; + _this._isVideo = !!options.video; + _this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + _this._cubemapConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/ + order: _this._projectionType === PROJECTION_TYPE.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, options.cubemapConfig); + _this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; // If the width and height are not provided, will use the size of the container. + + _this._width = options.width || parseInt(window.getComputedStyle(container).width, 10); + _this._height = options.height || parseInt(window.getComputedStyle(container).height, 10); + /** + * Cache the direction for the performance in renderLoop + * + * This value should be updated by "change" event of YawPitchControl. + */ + + _this._yaw = options.yaw || 0; + _this._pitch = options.pitch || 0; + _this._fov = options.fov || 65; + _this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH; + _this._quaternion = null; + _this._aspectRatio = _this._height !== 0 ? _this._width / _this._height : 1; + _this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS; + var fovRange = options.fovRange || [30, 110]; + var touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ? options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL; + + var yawPitchConfig = __assign(__assign({}, options), { + element: container, + yaw: _this._yaw, + pitch: _this._pitch, + fov: _this._fov, + gyroMode: _this._gyroMode, + fovRange: fovRange, + aspectRatio: _this._aspectRatio, + touchDirection: touchDirection + }); + + _this._isReady = false; + + _this._initYawPitchControl(yawPitchConfig); + + _this._initRenderer(_this._yaw, _this._pitch, _this._fov, _this._projectionType, _this._cubemapConfig); + + return _this; + } + /** + * Check whether the current environment can execute PanoViewer + * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다. + * @return PanoViewer executable PanoViewer 실행가능 여부 + */ + + + var __proto = PanoViewer.prototype; + + PanoViewer.isSupported = function () { + return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL(); + }; + /** + * Check whether the current environment supports the WebGL + * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다. + * @return WebGL support WebGL 지원여부 + */ + + + PanoViewer.isWebGLAvailable = function () { + return WebGLUtils.isWebGLAvailable(); + }; + /** + * Check whether the current environment supports the gyro sensor. + * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다. + * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수 + */ + + + PanoViewer.isGyroSensorAvailable = function (callback) { + if (!DeviceMotionEvent && callback) { + callback(false); + return; + } + + var onDeviceMotionChange; + + var checkGyro = function () { + return new Promise$1(function (res) { + onDeviceMotionChange = function (deviceMotion) { + var isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null); + res(isGyroSensorAvailable); + }; + + window.addEventListener("devicemotion", onDeviceMotionChange); + }); + }; + + var timeout = function () { + return new Promise$1(function (res) { + setTimeout(function () { + return res(false); + }, 1000); + }); + }; + + Promise$1.race([checkGyro(), timeout()]).then(function (isGyroSensorAvailable) { + window.removeEventListener("devicemotion", onDeviceMotionChange); + + if (callback) { + callback(isGyroSensorAvailable); + } + + PanoViewer.isGyroSensorAvailable = function (fb) { + if (fb) { + fb(isGyroSensorAvailable); + } + + return isGyroSensorAvailable; + }; + }); + }; + + PanoViewer._isValidTouchDirection = function (direction) { + return direction === PanoViewer.TOUCH_DIRECTION.NONE || direction === PanoViewer.TOUCH_DIRECTION.YAW || direction === PanoViewer.TOUCH_DIRECTION.PITCH || direction === PanoViewer.TOUCH_DIRECTION.ALL; + }; + /** + * Get the video element that the viewer is currently playing. You can use this for playback. + * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다. + * @return HTMLVideoElementHTMLVideoElement + * @example + * ``` + * var videoTag = panoViewer.getVideo(); + * videoTag.play(); // play the video! + * ``` + */ + + + __proto.getVideo = function () { + if (!this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the video information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정) + * @param {object} param + * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}("equirectangular")] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setVideo("/path/to/video/video.mp4", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR + * }); + * ``` + */ + + + __proto.setVideo = function (video, param) { + if (param === void 0) { + param = {}; + } + + if (video) { + this.setImage(video, { + projectionType: param.projectionType, + isVideo: true, + cubemapConfig: param.cubemapConfig, + stereoFormat: param.stereoFormat + }); + } + + return this; + }; + /** + * Get the image information that the viewer is currently using. + * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다. + * @return Image Object이미지 객체 + * @example + * var imageObj = panoViewer.getImage(); + */ + + + __proto.getImage = function () { + if (this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the image information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.) + * @param {object} param Additional information이미지 추가 정보 + * @param {string} [param.projectionType="equirectangular"] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부 + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setImage("/path/to/image/image.png", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP + * }); + * ``` + */ + + + __proto.setImage = function (image, param) { + if (param === void 0) { + param = {}; + } + + var cubemapConfig = __assign({ + order: "RLUDBF", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, param.cubemapConfig); + + var stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; + var isVideo = !!param.isVideo; + + if (this._image && this._isVideo !== isVideo) { + /* eslint-disable no-console */ + console.warn("PanoViewer is not currently supporting content type changes. (Image <--> Video)"); + /* eslint-enable no-console */ + + return this; + } + + if (image) { + this._deactivate(); + + this._image = image; + this._isVideo = isVideo; + this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + this._cubemapConfig = cubemapConfig; + this._stereoFormat = stereoFormat; + + this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig); + } + + return this; + }; + /** + * Set whether the renderer always updates the texture and renders. + * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다. + * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.keepUpdate = function (doUpdate) { + this._photoSphereRenderer.keepUpdate(doUpdate); + + return this; + }; + /** + * Get the current projection type (equirectangular/cube) + * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다. + * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE} + */ + + + __proto.getProjectionType = function () { + return this._projectionType; + }; + /** + * Activate the device's motion sensor, and return the Promise whether the sensor is enabled + * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element. + * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다. + * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다. + */ + + + __proto.enableSensor = function () { + return new Promise$1(function (resolve, reject) { + if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === "function") { + DeviceMotionEvent.requestPermission().then(function (permissionState) { + if (permissionState === "granted") { + resolve(); + } else { + reject(new Error("permission denied")); + } + }).catch(function (e) { + // This can happen when this method wasn't triggered by user interaction + reject(e); + }); + } else { + resolve(); + } + }); + }; + /** + * Disable the device's motion sensor. + * @ko 디바이스의 모션 센서를 비활성화합니다. + * @deprecated + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.disableSensor = function () { + return this; + }; + /** + * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred). + * This method must be used in the context of user interaction, like onclick callback on the button element. + * It can be rejected when an enabling device sensor fails or image/video is still loading("ready" event not triggered). + * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다) + * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우("ready"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다. + * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요. + * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error) + */ + + + __proto.enterVR = function (options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + if (!this._isReady) { + return Promise$1.reject(new Error("PanoViewer is not ready to show image.")); + } + + return new Promise$1(function (resolve, reject) { + _this.enableSensor().then(function () { + return _this._photoSphereRenderer.enterVR(options); + }).then(function (res) { + return resolve(res); + }).catch(function (e) { + return reject(e); + }); + }); + }; + /** + * Exit VR stereo rendering mode. + * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.exitVR = function () { + this._photoSphereRenderer.exitVR(); + + return this; + }; + /** + * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}. + * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다. + * @param useZoom + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseZoom = function (useZoom) { + if (typeof useZoom === "boolean") { + this._yawPitchControl.option("useZoom", useZoom); + } + + return this; + }; + /** + * When true, enables the keyboard move key control: awsd, arrow keys + * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키) + * @param useKeyboard + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseKeyboard = function (useKeyboard) { + this._yawPitchControl.option("useKeyboard", useKeyboard); + + return this; + }; + /** + * Enables control through device motion. ("none", "yawPitch", "VR") + * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR") + * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE} + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setGyroMode("yawPitch"); + * //equivalent + * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH); + * ``` + */ + + + __proto.setGyroMode = function (gyroMode) { + this._yawPitchControl.option("gyroMode", gyroMode); + + return this; + }; + /** + * Set the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 설정합니다. + * @param range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setFovRange([50, 90]); + */ + + + __proto.setFovRange = function (range) { + this._yawPitchControl.option("fovRange", range); + + return this; + }; + /** + * Get the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 반환합니다. + * @return FOV range + * @example + * var range = panoViewer.getFovRange(); // [50, 90] + */ + + + __proto.getFovRange = function () { + return this._yawPitchControl.option("fovRange"); + }; + /** + * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size. + * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다. + * @param {object} [size] + * @param {number} [size.width=width of the container] + * @param {number} [size.height=height of the container] + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.updateViewportDimensions = function (size) { + if (size === void 0) { + size = {}; + } + + if (!this._isReady) { + return this; + } + + var containerSize; + + if (size.width === undefined || size.height === undefined) { + containerSize = window.getComputedStyle(this._container); + } + + var width = size.width || parseInt(containerSize.width, 10); + var height = size.height || parseInt(containerSize.height, 10); // Skip if viewport is not changed. + + if (width === this._width && height === this._height) { + return this; + } + + this._width = width; + this._height = height; + this._aspectRatio = width / height; + + this._photoSphereRenderer.updateViewportDimensions(width, height); + + this._yawPitchControl.option("aspectRatio", this._aspectRatio); + + this._yawPitchControl.updatePanScale({ + height: height + }); + + this.lookAt({}, 0); + return this; + }; + /** + * Get the current field of view(FOV) + * @ko 현재 field of view(FOV) 값을 반환합니다. + */ + + + __proto.getFov = function () { + return this._fov; + }; + /** + * Get current yaw value + * @ko 현재 yaw 값을 반환합니다. + */ + + + __proto.getYaw = function () { + return this._yaw; + }; + /** + * Get current pitch value + * @ko 현재 pitch 값을 반환합니다. + */ + + + __proto.getPitch = function () { + return this._pitch; + }; + /** + * Get the range of controllable Yaw values + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + */ + + + __proto.getYawRange = function () { + return this._yawPitchControl.option("yawRange"); + }; + /** + * Get the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다. + */ + + + __proto.getPitchRange = function () { + return this._yawPitchControl.option("pitchRange"); + }; + /** + * Set the range of controllable yaw + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setYawRange([-90, 90]); + */ + + + __proto.setYawRange = function (yawRange) { + this._yawPitchControl.option("yawRange", yawRange); + + return this; + }; + /** + * Set the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 설정합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setPitchRange([-40, 40]); + */ + + + __proto.setPitchRange = function (pitchRange) { + this._yawPitchControl.option("pitchRange", pitchRange); + + return this; + }; + /** + * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed. + * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다. + * @param showPolePoint + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setShowPolePoint = function (showPolePoint) { + this._yawPitchControl.option("showPolePoint", showPolePoint); + + return this; + }; + /** + * Set a new view by setting camera configuration. Any parameters not specified remain the same. + * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다. + * @param {object} orientation + * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위) + * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위) + * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위) + * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초) + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * // Change the yaw angle (absolute angle) to 30 degrees for one second. + * panoViewer.lookAt({yaw: 30}, 1000); + * ``` + */ + + + __proto.lookAt = function (orientation, duration) { + if (duration === void 0) { + duration = 0; + } + + if (!this._isReady) { + return this; + } + + var yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw; + var pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch; + + var pitchRange = this._yawPitchControl.option("pitchRange"); + + var verticalAngleOfImage = pitchRange[1] - pitchRange[0]; + var fov = orientation.fov !== undefined ? orientation.fov : this._fov; + + if (verticalAngleOfImage < fov) { + fov = verticalAngleOfImage; + } + + this._yawPitchControl.lookAt({ + yaw: yaw, + pitch: pitch, + fov: fov + }, duration); + + if (duration === 0) { + this._photoSphereRenderer.renderWithYawPitch(yaw, pitch, fov); + } + + return this; + }; + /** + * Set touch direction by which user can control. + * @ko 사용자가 조작가능한 터치 방향을 지정합니다. + * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @return PanoViewer instance + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Limit the touch direction to the yaw direction only. + * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW); + * ``` + */ + + + __proto.setTouchDirection = function (direction) { + if (PanoViewer._isValidTouchDirection(direction)) { + this._yawPitchControl.option("touchDirection", direction); + } + + return this; + }; + /** + * Returns touch direction by which user can control + * @ko 사용자가 조작가능한 터치 방향을 반환한다. + * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Returns the current touch direction. + * var dir = panoViewer.getTouchDirection(); + * ``` + */ + + + __proto.getTouchDirection = function () { + return this._yawPitchControl.option("touchDirection"); + }; + /** + * Destroy viewer. Remove all registered event listeners and remove viewer canvas. + * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.destroy = function () { + this._deactivate(); + + if (this._yawPitchControl) { + this._yawPitchControl.destroy(); + + this._yawPitchControl = null; + } + + return this; + }; // TODO: Remove parameters as they're just using private values + + + __proto._initRenderer = function (yaw, pitch, fov, projectionType, cubemapConfig) { + var _this = this; + + this._photoSphereRenderer = new PanoImageRenderer(this._image, this._width, this._height, this._isVideo, this._container, this._canvasClass, { + initialYaw: yaw, + initialPitch: pitch, + fieldOfView: fov, + imageType: projectionType, + cubemapConfig: cubemapConfig, + stereoFormat: this._stereoFormat + }); + + this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl); + + this._bindRendererHandler(); + + this._photoSphereRenderer.bindTexture().then(function () { + return _this._activate(); + }).catch(function () { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.FAIL_BIND_TEXTURE, + message: "failed to bind texture" + })); + }); + }; + /** + * @private + * update values of YawPitchControl if needed. + * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image. + * + * This function should be called after isReady status is true. + */ + + + __proto._updateYawPitchIfNeeded = function () { + if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) { + // update fov by aspect ratio + var image = this._photoSphereRenderer.getContent(); + + var imageAspectRatio = image.naturalWidth / image.naturalHeight; + var yawSize = void 0; + var maxFov = void 0; // If height is larger than width, then we assume it's rotated by 90 degree. + + if (imageAspectRatio < 1) { + // So inverse the aspect ratio. + imageAspectRatio = 1 / imageAspectRatio; + } + + if (imageAspectRatio < 6) { + yawSize = util.toDegree(imageAspectRatio); // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5 + + maxFov = util.toDegree(Math.atan(0.5)) * 2; + } else { + yawSize = 360; + maxFov = 360 / imageAspectRatio; // Make it 5 fixed as axes does. + } // console.log("_updateYawPitchIfNeeded", maxFov, "aspectRatio", image.naturalWidth, image.naturalHeight, "yawSize", yawSize); + + + var minFov = this._yawPitchControl.option("fovRange")[0]; // this option should be called after fov is set. + + + this._yawPitchControl.option({ + "fov": maxFov, + "yawRange": [-yawSize / 2, yawSize / 2], + "pitchRange": [-maxFov / 2, maxFov / 2], + "fovRange": [minFov, maxFov] + }); + + this.lookAt({ + fov: maxFov + }); + } + }; + + __proto._bindRendererHandler = function () { + var _this = this; + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.ERROR, function (e) { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, e)); + }); + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, function () { + _this._deactivate(); + + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.RENDERING_CONTEXT_LOST, + message: "webgl rendering context lost" + })); + }); + }; + + __proto._initYawPitchControl = function (yawPitchConfig) { + var _this = this; + + this._yawPitchControl = new YawPitchControl(yawPitchConfig); + + this._yawPitchControl.on(PANOVIEWER_EVENTS.ANIMATION_END, function (e) { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ANIMATION_END, e)); + }); + + this._yawPitchControl.on("change", function (e) { + _this._yaw = e.yaw; + _this._pitch = e.pitch; + _this._fov = e.fov; + _this._quaternion = e.quaternion; + + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.VIEW_CHANGE, { + yaw: e.yaw, + pitch: e.pitch, + fov: e.fov, + quaternion: e.quaternion, + isTrusted: e.isTrusted + })); + }); + }; + + __proto._activate = function () { + this._photoSphereRenderer.attachTo(this._container); + + this._yawPitchControl.enable(); + + this.updateViewportDimensions(); + this._isReady = true; // update yawPitchControl after isReady status is true. + + this._updateYawPitchIfNeeded(); + + this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.READY)); + + this._photoSphereRenderer.startRender(); + }; + /** + * Destroy webgl context and block user interaction and stop rendering + */ + + + __proto._deactivate = function () { + // Turn off the video if it has one + var video = this.getVideo(); + + if (video) { + video.pause(); + } + + if (this._isReady) { + this._photoSphereRenderer.stopRender(); + + this._yawPitchControl.disable(); + + this._isReady = false; + } + + if (this._photoSphereRenderer) { + this._photoSphereRenderer.destroy(); + + this._photoSphereRenderer = null; + } + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @type {String} + * @example + * eg.view360.PanoViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.PanoViewer + */ + + + PanoViewer.VERSION = VERSION; + PanoViewer.ERROR_TYPE = ERROR_TYPE; + PanoViewer.EVENTS = PANOVIEWER_EVENTS; + PanoViewer.PROJECTION_TYPE = PROJECTION_TYPE; + PanoViewer.GYRO_MODE = GYRO_MODE; // This should be deprecated! + // eslint-disable-next-line @typescript-eslint/naming-convention + + PanoViewer.ProjectionType = PROJECTION_TYPE; + PanoViewer.STEREO_FORMAT = STEREO_FORMAT; + /** + * Constant value for touch directions + * @ko 터치 방향에 대한 상수 값. + * @namespace + * @name TOUCH_DIRECTION + */ + + PanoViewer.TOUCH_DIRECTION = { + /** + * Constant value for none direction. + * @ko none 방향에 대한 상수 값. + * @name NONE + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 1 + */ + NONE: YawPitchControl.TOUCH_DIRECTION_NONE, + + /** + * Constant value for horizontal(yaw) direction. + * @ko horizontal(yaw) 방향에 대한 상수 값. + * @name YAW + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 6 + */ + YAW: YawPitchControl.TOUCH_DIRECTION_YAW, + + /** + * Constant value for vertical direction. + * @ko vertical(pitch) 방향에 대한 상수 값. + * @name PITCH + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 24 + */ + PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH, + + /** + * Constant value for all direction. + * @ko all 방향에 대한 상수 값. + * @name ALL + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 30 + */ + ALL: YawPitchControl.TOUCH_DIRECTION_ALL + }; + return PanoViewer; + }(Component); + + /* eslint-disable @typescript-eslint/naming-convention */ + var PanoViewerModule = { + PanoViewer: PanoViewer, + VERSION: VERSION + }; + merge(PanoViewerModule, Constants); + + return PanoViewerModule; + +}))); +//# sourceMappingURL=view360.panoviewer.js.map diff --git a/dist/PanoViewer/view360.panoviewer.js.map b/dist/PanoViewer/view360.panoviewer.js.map new file mode 100644 index 000000000..2ce4fcfb5 --- /dev/null +++ b/dist/PanoViewer/view360.panoviewer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.panoviewer.js","sources":["../../src/version.ts","../../src/utils/utils.ts","../../src/utils/browser.ts","../../src/utils/browserFeature.ts","../../src/utils/math-util.ts","../../src/YawPitchControl/utils.ts","../../src/YawPitchControl/consts.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/math-util.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/util.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/pose-predictor.ts","../../src/YawPitchControl/input/DeviceMotion.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/sensor-sample.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/complementary-filter.ts","../../src/YawPitchControl/input/ComplementaryFilter.ts","../../src/YawPitchControl/input/FusionPoseSensor.ts","../../src/YawPitchControl/input/TiltMotionInput.ts","../../src/YawPitchControl/ScreenRotationAngle.ts","../../src/YawPitchControl/input/RotationPanInput.ts","../../src/YawPitchControl/DeviceQuaternion.ts","../../src/YawPitchControl/YawPitchControl.ts","../../src/PanoViewer/consts.ts","../../src/PanoImageRenderer/WebGLUtils.ts","../../src/PanoImageRenderer/renderer/Renderer.ts","../../src/PanoImageRenderer/renderer/CubeRenderer.ts","../../src/PanoImageRenderer/renderer/CubeStripRenderer.ts","../../src/PanoImageRenderer/renderer/SphereRenderer.ts","../../src/PanoImageRenderer/renderer/CylinderRenderer.ts","../../src/PanoImageRenderer/vr/VRManager.ts","../../src/PanoImageRenderer/vr/XRManager.ts","../../src/PanoImageRenderer/WebGLAnimator.ts","../../src/PanoImageRenderer/PanoImageRenderer.ts","../../src/PanoViewer/PanoViewer.ts","../../src/PanoViewer/index.umd.ts"],"sourcesContent":["const VERSION = \"#__VERSION__#\";\n\nexport {\n VERSION\n};\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","/**\n * Original Code\n * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js\n * Math Util\n * modified by egjs\n */\n/**\n * @fileoverview gl-matrix - High performance matrix and vector operations\n * @author Brandon Jones\n * @author Colin MacKenzie IV\n * @version 2.3.2\n */\n\n/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE. */\n\n// Some minimal math functionality borrowed from gl-Matrix and stripped down\n// for the purposes of this library.\n\nimport { vec2, vec3, quat } from \"gl-matrix\";\n\nimport { ValueOf } from \"../types/internal\";\n\nconst quatToVec3 = (quaternion: quat) => {\n const baseV = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(baseV, baseV, quaternion);\n return baseV;\n};\n\nconst toDegree = (a: number) => a * 180 / Math.PI;\n\nconst util: any = {};\n\nutil.isPowerOfTwo = (n: number) => n && (n & (n - 1)) === 0;\n\nutil.extractPitchFromQuat = (quaternion: quat) => {\n const baseV = quatToVec3(quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n};\n\nutil.hypot = Math.hypot || ((x: number, y: number) => Math.sqrt(x * x + y * y));\n\n// implement reference\n// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식\n// calculating angle between two vectors : http://darkpgmr.tistory.com/121\nconst ROTATE_CONSTANT: {\n PITCH_DELTA: 1;\n YAW_DELTA_BY_ROLL: 2;\n YAW_DELTA_BY_YAW: 3;\n} = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n};\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nconst getRotationDelta = (prevQ: quat, curQ: quat, rotateKind: ValueOf) => {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n // const coefficientD = -1 * vec3.dot(vecN, meshPoint1);\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance =\n coefficientA * crossVec[0] +\n coefficientB * crossVec[1] +\n coefficientC * crossVec[2];\n\n let thetaDirection;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return toDegree(deltaRadian);\n};\n\nconst angleBetweenVec2 = (v1: vec2, v2: vec2) => {\n const det = v1[0] * v2[1] - v2[0] * v1[1];\n const theta = -Math.atan2(det, vec2.dot(v1, v2));\n return theta;\n};\n\nutil.yawOffsetBetween = (viewDir: number, targetDir: number) => {\n const viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]);\n const targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]);\n\n vec2.normalize(viewDirXZ, viewDirXZ);\n vec2.normalize(targetDirXZ, targetDirXZ);\n\n const theta = -angleBetweenVec2(viewDirXZ, targetDirXZ);\n\n return theta;\n};\n\nutil.sign = (x: number) => Math.sign\n ? Math.sign(x)\n : (Number(x > 0) - Number(x < 0)) || +x;\n\nutil.toDegree = toDegree;\nutil.getRotationDelta = getRotationDelta;\nutil.angleBetweenVec2 = angleBetweenVec2;\n\nexport {\n util,\n ROTATE_CONSTANT\n};\n","import { quat } from \"gl-matrix\";\n\nimport {\n util as mathUtil,\n ROTATE_CONSTANT\n} from \"../utils/math-util\";\n\nexport const toAxis = (source, offset) => offset.reduce((acc, v, i) => {\n if (source[i]) {\n acc[source[i]] = v;\n }\n return acc;\n}, {});\n\nexport const getDeltaYaw = (prvQ: quat, curQ: quat) => {\n const yawDeltaByYaw = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(mathUtil.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nexport const getDeltaPitch = (prvQ: quat, curQ: quat) => {\n const pitchDelta = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n","import { userAgent } from \"../utils/browserFeature\";\n/**\n * Returns a number value indiciating the version of Chrome being used,\n * or otherwise `null` if not on Chrome.\n *\n * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19\n */\n/**\n * In Chrome m65, `devicemotion` events are broken but subsequently fixed\n * in 65.0.3325.148. Since many browsers use Chromium, ensure that\n * we scope this detection by branch and build numbers to provide\n * a proper fallback.\n * https://github.com/immersive-web/webvr-polyfill/issues/307\n */\nlet version = -1; // It should not be null because it will be compared with number\nlet branch: string | null = null;\nlet build: string | null = null;\n\nconst match = /Chrome\\/([0-9]+)\\.(?:[0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(userAgent);\n\nif (match) {\n version = parseInt(match[1], 10);\n branch = match[2];\n build = match[3];\n}\n\nconst CHROME_VERSION = version;\nconst IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === \"3325\" && parseInt(build!, 10) < 148;\nconst IS_ANDROID = /Android/i.test(userAgent);\n\nconst CONTROL_MODE_VR = 1;\nconst CONTROL_MODE_YAWPITCH = 2;\n\nconst TOUCH_DIRECTION_NONE = 1;\nconst TOUCH_DIRECTION_YAW = 2;\nconst TOUCH_DIRECTION_PITCH = 4;\nconst TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH;\n\n/* Const for MovableCoord */\nconst MC_DECELERATION = 0.0014;\nconst MC_MAXIMUM_DURATION = 1000;\nconst MC_BIND_SCALE = [0.20, 0.20];\n\nconst MIN_FIELD_OF_VIEW = 20;\nconst MAX_FIELD_OF_VIEW = 110;\nconst PAN_SCALE = 320;\n\n// const DELTA_THRESHOLD = 0.015;\n// const DELTA_THRESHOLD = 0.09; // Note4\n// const DELTA_THRESHOLD = 0.0825;\n// const DELTA_THRESHOLD = 0.075;\n// const DELTA_THRESHOLD = 0.06;\n// const DELTA_THRESHOLD = 0.045;\nconst DELTA_THRESHOLD = 0.0375; // Note2\n\nconst YAW_RANGE_HALF = 180;\nconst PITCH_RANGE_HALF = 90;\nconst CIRCULAR_PITCH_RANGE_HALF = 180;\nconst PINCH_EVENTS = \"pinchstart pinchmove pinchend\";\n\nconst KEYMAP = {\n LEFT_ARROW: 37,\n A: 65,\n UP_ARROW: 38,\n W: 87,\n RIGHT_ARROW: 39,\n D: 68,\n DOWN_ARROW: 40,\n S: 83\n};\n\nconst GYRO_MODE: {\n NONE: \"none\";\n YAWPITCH: \"yawPitch\";\n VR: \"VR\";\n} = {\n NONE: \"none\",\n YAWPITCH: \"yawPitch\",\n VR: \"VR\"\n};\n\nexport {\n GYRO_MODE,\n\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n\n TOUCH_DIRECTION_NONE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MIN_FIELD_OF_VIEW,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n DELTA_THRESHOLD,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n PINCH_EVENTS,\n KEYMAP,\n\n CHROME_VERSION,\n IS_CHROME_WITHOUT_DEVICE_MOTION,\n IS_ANDROID\n};\n","/* eslint-disable */\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { window as win } from \"../../../../utils/browser\";\n\nconst MathUtil = win.MathUtil || {};\n\nMathUtil.degToRad = Math.PI / 180;\nMathUtil.radToDeg = 180 / Math.PI;\n\n// Some minimal math functionality borrowed from THREE.Math and stripped down\n// for the purposes of this library.\n\n\nMathUtil.Vector2 = function( x, y ) {\n this.x = x || 0;\n this.y = y || 0;\n};\n\nMathUtil.Vector2.prototype = {\n constructor: MathUtil.Vector2,\n\n set: function( x, y ) {\n this.x = x;\n this.y = y;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n },\n\n subVectors: function( a, b ) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n\n return this;\n }\n};\n\nMathUtil.Vector3 = function( x, y, z ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n};\n\nMathUtil.Vector3.prototype = {\n constructor: MathUtil.Vector3,\n\n set: function( x, y, z ) {\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n\n return this;\n },\n\n length: function() {\n return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n },\n\n normalize: function() {\n const scalar = this.length();\n\n if ( scalar !== 0 ) {\n const invScalar = 1 / scalar;\n\n this.multiplyScalar(invScalar);\n } else {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n }\n\n return this;\n },\n\n multiplyScalar: function( scalar ) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n },\n\n applyQuaternion: function( q ) {\n const x = this.x;\n const y = this.y;\n const z = this.z;\n\n const qx = q.x;\n const qy = q.y;\n const qz = q.z;\n const qw = q.w;\n\n // calculate quat * vector\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = - qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n return this;\n },\n\n dot: function( v ) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n },\n\n crossVectors: function( a, b ) {\n const ax = a.x;\n const ay = a.y;\n const az = a.z;\n const bx = b.x;\n const by = b.y;\n const bz = b.z;\n\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n\n return this;\n }\n};\n\nMathUtil.Quaternion = function( x, y, z, w ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n this.w = ( w !== undefined ) ? w : 1;\n};\n\nMathUtil.Quaternion.prototype = {\n constructor: MathUtil.Quaternion,\n\n set: function( x, y, z, w ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n\n return this;\n },\n\n copy: function( quaternion ) {\n this.x = quaternion.x;\n this.y = quaternion.y;\n this.z = quaternion.z;\n this.w = quaternion.w;\n\n return this;\n },\n\n setFromEulerXYZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 + s1 * s2 * c3;\n this.w = c1 * c2 * c3 - s1 * s2 * s3;\n\n return this;\n },\n\n setFromEulerYXZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 - s1 * s2 * c3;\n this.w = c1 * c2 * c3 + s1 * s2 * s3;\n\n return this;\n },\n\n setFromAxisAngle: function( axis, angle ) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n // assumes axis is normalized\n\n const halfAngle = angle / 2;\n const s = Math.sin( halfAngle );\n\n this.x = axis.x * s;\n this.y = axis.y * s;\n this.z = axis.z * s;\n this.w = Math.cos( halfAngle );\n\n return this;\n },\n\n multiply: function( q ) {\n return this.multiplyQuaternions( this, q );\n },\n\n multiplyQuaternions: function( a, b ) {\n // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n const qax = a.x;\n const qay = a.y;\n const qaz = a.z;\n const qaw = a.w;\n const qbx = b.x;\n const qby = b.y;\n const qbz = b.z;\n const qbw = b.w;\n\n this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n return this;\n },\n\n inverse: function() {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n\n this.normalize();\n\n return this;\n },\n\n normalize: function() {\n let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n if ( l === 0 ) {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n this.w = 1;\n } else {\n l = 1 / l;\n\n this.x = this.x * l;\n this.y = this.y * l;\n this.z = this.z * l;\n this.w = this.w * l;\n }\n\n return this;\n },\n\n slerp: function( qb, t ) {\n if ( t === 0 ) return this;\n if ( t === 1 ) return this.copy( qb );\n\n const x = this.x;\n const y = this.y;\n const z = this.z;\n const w = this.w;\n\n // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n let cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;\n\n if ( cosHalfTheta < 0 ) {\n this.w = - qb.w;\n this.x = - qb.x;\n this.y = - qb.y;\n this.z = - qb.z;\n\n cosHalfTheta = - cosHalfTheta;\n } else {\n this.copy( qb );\n }\n\n if ( cosHalfTheta >= 1.0 ) {\n this.w = w;\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n }\n\n const halfTheta = Math.acos( cosHalfTheta );\n const sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n if ( Math.abs( sinHalfTheta ) < 0.001 ) {\n this.w = 0.5 * ( w + this.w );\n this.x = 0.5 * ( x + this.x );\n this.y = 0.5 * ( y + this.y );\n this.z = 0.5 * ( z + this.z );\n\n return this;\n }\n\n const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;\n const ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n this.w = ( w * ratioA + this.w * ratioB );\n this.x = ( x * ratioA + this.x * ratioB );\n this.y = ( y * ratioA + this.y * ratioB );\n this.z = ( z * ratioA + this.z * ratioB );\n\n return this;\n },\n\n setFromUnitVectors: function() {\n // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n // assumes direction vectors vFrom and vTo are normalized\n\n let v1;\n let r;\n const EPS = 0.000001;\n\n return function( vFrom, vTo ) {\n if ( v1 === undefined ) v1 = new MathUtil.Vector3();\n\n r = vFrom.dot( vTo ) + 1;\n\n if ( r < EPS ) {\n r = 0;\n\n if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n v1.set( - vFrom.y, vFrom.x, 0 );\n } else {\n v1.set( 0, - vFrom.z, vFrom.y );\n }\n } else {\n v1.crossVectors( vFrom, vTo );\n }\n\n this.x = v1.x;\n this.y = v1.y;\n this.z = v1.z;\n this.w = r;\n\n this.normalize();\n\n return this;\n };\n }()\n};\n\nexport default MathUtil;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tslint:disable: only-arrow-functions\n\nimport { window as win, document as doc, navigator as nav } from \"../../../../utils/browser\";\n\nconst userAgent = nav?.userAgent ?? \"\";\nconst Util = (win ).Util || {};\n\nUtil.MIN_TIMESTEP = 0.001;\nUtil.MAX_TIMESTEP = 1;\n\nUtil.base64 = function(mimeType, base64) {\n return \"data:\" + mimeType + \";base64,\" + base64;\n};\n\nUtil.clamp = function(value, min, max) {\n return Math.min(Math.max(min, value), max);\n};\n\nUtil.lerp = function(a, b, t) {\n return a + ((b - a) * t);\n};\n\nUtil.isIOS = (function() {\n const isIOS = /iPad|iPhone|iPod/.test(nav?.platform);\n return function() {\n return isIOS;\n };\n})();\n\nUtil.isWebViewAndroid = (function() {\n const isWebViewAndroid = userAgent.indexOf(\"Version\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1 &&\n userAgent.indexOf(\"Chrome\") !== -1;\n return function() {\n return isWebViewAndroid;\n };\n})();\n\nUtil.isSafari = (function() {\n const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n return function() {\n return isSafari;\n };\n})();\n\nUtil.isFirefoxAndroid = (function() {\n const isFirefoxAndroid = userAgent.indexOf(\"Firefox\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1;\n return function() {\n return isFirefoxAndroid;\n };\n})();\n\nUtil.isR7 = (function() {\n const isR7 = userAgent.indexOf(\"R7 Build\") !== -1;\n return function() {\n return isR7;\n };\n})();\n\nUtil.isLandscapeMode = function() {\n const rtn = (win.orientation === 90 || win.orientation === -90);\n return Util.isR7() ? !rtn : rtn;\n};\n\n// Helper method to validate the time steps of sensor timestamps.\nUtil.isTimestampDeltaValid = function(timestampDeltaS) {\n if (isNaN(timestampDeltaS)) {\n return false;\n }\n if (timestampDeltaS <= Util.MIN_TIMESTEP) {\n return false;\n }\n if (timestampDeltaS > Util.MAX_TIMESTEP) {\n return false;\n }\n return true;\n};\n\nUtil.getScreenWidth = function() {\n return Math.max(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.getScreenHeight = function() {\n return Math.min(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.requestFullscreen = function(element) {\n if (Util.isWebViewAndroid()) {\n return false;\n }\n if (element.requestFullscreen) {\n element.requestFullscreen();\n } else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n } else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n } else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.exitFullscreen = function() {\n if (doc.exitFullscreen) {\n doc.exitFullscreen();\n } else if (doc.webkitExitFullscreen) {\n doc.webkitExitFullscreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.getFullscreenElement = function() {\n return doc.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n};\n\nUtil.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {\n // No error checking for brevity.\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n const program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n\n for (const attribName in attribLocationMap)\n gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);\n\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n};\n\nUtil.getProgramUniforms = function(gl, program) {\n const uniforms = {};\n const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n let uniformName = \"\";\n for (let i = 0; i < uniformCount; i++) {\n const uniformInfo = gl.getActiveUniform(program, i);\n uniformName = uniformInfo.name.replace(\"[0]\", \"\");\n uniforms[uniformName] = gl.getUniformLocation(program, uniformName);\n }\n return uniforms;\n};\n\nUtil.orthoMatrix = function(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right);\n const bt = 1 / (bottom - top);\n const nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n};\n\nUtil.copyArray = function(source, dest) {\n for (let i = 0, n = source.length; i < n; i++) {\n dest[i] = source[i];\n }\n};\n\nUtil.isMobile = function() {\n let check = false;\n (function(a) {\n if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))check = true;\n })(userAgent || nav?.vendor || win.opera);\n return check;\n};\n\nUtil.extend = function(dest, src) {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n dest[key] = src[key];\n }\n }\n\n return dest;\n};\n\nUtil.safariCssSizeWorkaround = function(canvas) {\n // TODO(smus): Remove this workaround when Safari for iOS is fixed.\n // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).\n //\n // \"To the last I grapple with thee;\n // from hell's heart I stab at thee;\n // for hate's sake I spit my last breath at thee.\"\n // -- Moby Dick, by Herman Melville\n if (Util.isIOS()) {\n const width = canvas.style.width;\n const height = canvas.style.height;\n canvas.style.width = (parseInt(width) + 1) + \"px\";\n canvas.style.height = (parseInt(height)) + \"px\";\n setTimeout(function() {\n canvas.style.width = width;\n canvas.style.height = height;\n }, 100);\n }\n\n // Debug only.\n win.Util = Util;\n win.canvas = canvas;\n};\n\nUtil.isDebug = function() {\n return Util.getQueryParameter(\"debug\");\n};\n\nUtil.getQueryParameter = function(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n const results = regex.exec(location.search);\n return results === null ? \"\" : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n};\n\nUtil.frameDataFromPose = (function() {\n const piOver180 = Math.PI / 180.0;\n const rad45 = Math.PI * 0.25;\n\n // Borrowed from glMatrix.\n function mat4_perspectiveFromFieldOfView(out, fov, near, far) {\n const upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45);\n const downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45);\n const leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45);\n const rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45);\n const xScale = 2.0 / (leftTan + rightTan);\n const yScale = 2.0 / (upTan + downTan);\n\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = ((upTan - downTan) * yScale * 0.5);\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = (far * near) / (near - far);\n out[15] = 0.0;\n return out;\n }\n\n function mat4_fromRotationTranslation(out, q, v) {\n // Quaternion math\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n\n return out;\n }\n\n function mat4_translate(out, a, v) {\n const x = v[0];\n const y = v[1];\n const z = v[2];\n let a00;\n let a01;\n let a02;\n let a03;\n let a10;\n let a11;\n let a12;\n let a13;\n let a20;\n let a21;\n let a22;\n let a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];\n a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];\n a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];\n\n out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;\n out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;\n out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;\n\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n }\n\n function mat4_invert(out, a) {\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n }\n\n const defaultOrientation = new Float32Array([0, 0, 0, 1]);\n const defaultPosition = new Float32Array([0, 0, 0]);\n\n function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {\n mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);\n\n const orientation = pose.orientation || defaultOrientation;\n const position = pose.position || defaultPosition;\n\n mat4_fromRotationTranslation(view, orientation, position);\n if (parameters)\n mat4_translate(view, view, parameters.offset);\n mat4_invert(view, view);\n }\n\n return function(frameData, pose, vrDisplay) {\n if (!frameData || !pose)\n return false;\n\n frameData.pose = pose;\n frameData.timestamp = pose.timestamp;\n\n updateEyeMatrices(\n frameData.leftProjectionMatrix, frameData.leftViewMatrix,\n pose, vrDisplay.getEyeParameters(\"left\"), vrDisplay);\n updateEyeMatrices(\n frameData.rightProjectionMatrix, frameData.rightViewMatrix,\n pose, vrDisplay.getEyeParameters(\"right\"), vrDisplay);\n\n return true;\n };\n})();\n\nUtil.isInsideCrossDomainIFrame = function() {\n const isFramed = (win.self !== win.top);\n const refDomain = Util.getDomainFromUrl(doc.referrer);\n const thisDomain = Util.getDomainFromUrl(win.location.href);\n\n return isFramed && (refDomain !== thisDomain);\n};\n\n// From http://stackoverflow.com/a/23945027.\nUtil.getDomainFromUrl = function(url) {\n let domain;\n // Find & remove protocol (http, ftp, etc.) and get domain.\n if (url.indexOf(\"://\") > -1) {\n domain = url.split(\"/\")[2];\n } else {\n domain = url.split(\"/\")[0];\n }\n\n // find & remove port number\n domain = domain.split(\":\")[0];\n\n return domain;\n};\n\nexport default Util;\n","/* eslint-disable */\n\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * Given an orientation and the gyroscope data, predicts the future orientation\n * of the head. This makes rendering appear faster.\n *\n * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf\n * @param {Number} predictionTimeS time from head movement to the appearance of\n * the corresponding image.\n */\nclass PosePredictor {\n public predictionTimeS;\n public previousQ;\n public previousTimestampS;\n public deltaQ;\n public outQ;\n\n public constructor(predictionTimeS) {\n this.predictionTimeS = predictionTimeS;\n\n // The quaternion corresponding to the previous state.\n this.previousQ = new MathUtil.Quaternion();\n // Previous time a prediction occurred.\n this.previousTimestampS = null;\n\n // The delta quaternion that adjusts the current pose.\n this.deltaQ = new MathUtil.Quaternion();\n // The output quaternion.\n this.outQ = new MathUtil.Quaternion();\n }\n\n public getPrediction(currentQ, gyro, timestampS) {\n if (!this.previousTimestampS) {\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n return currentQ;\n }\n\n // Calculate axis and angle based on gyroscope rotation rate data.\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n\n const angularSpeed = gyro.length();\n\n // If we're rotating slowly, don't do prediction.\n if (angularSpeed < MathUtil.degToRad * 20) {\n if (Util.isDebug()) {\n console.log(\"Moving slowly, at %s deg/s: no prediction\",\n (MathUtil.radToDeg * angularSpeed).toFixed(1));\n }\n this.outQ.copy(currentQ);\n this.previousQ.copy(currentQ);\n return this.outQ;\n }\n\n // Get the predicted angle based on the time delta and latency.\n const deltaT = timestampS - this.previousTimestampS;\n const predictAngle = angularSpeed * this.predictionTimeS;\n\n this.deltaQ.setFromAxisAngle(axis, predictAngle);\n this.outQ.copy(this.previousQ);\n this.outQ.multiply(this.deltaQ);\n\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n\n return this.outQ;\n }\n}\n\nexport default PosePredictor;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3 } from \"gl-matrix\";\n\nimport { Mutable } from \"../../types/internal\";\nimport { window } from \"../../utils/browser\";\nimport { IS_CHROME_WITHOUT_DEVICE_MOTION, IS_ANDROID } from \"../consts\";\n\nconst STILLNESS_THRESHOLD = 200; // millisecond\n\nexport default class DeviceMotion extends Component<{\n devicemotion: {\n inputEvent: DeviceMotionEvent | {\n deviceorientation: {\n alpha: number;\n beta: number;\n gamma: number;\n };\n };\n };\n}> {\n public readonly isWithoutDeviceMotion: boolean;\n public readonly isAndroid: boolean;\n\n public stillGyroVec: vec3;\n public rawGyroVec: vec3;\n public adjustedGyroVec: vec3;\n public lastDevicemotionTimestamp: number;\n\n private _timer: number;\n private _isEnabled: boolean;\n\n public constructor() {\n super();\n this._onDeviceMotion = this._onDeviceMotion.bind(this);\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onChromeWithoutDeviceMotion = this._onChromeWithoutDeviceMotion.bind(this);\n\n this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION;\n this.isAndroid = IS_ANDROID;\n\n this.stillGyroVec = vec3.create();\n this.rawGyroVec = vec3.create();\n this.adjustedGyroVec = vec3.create();\n\n this._timer = -1;\n\n this.lastDevicemotionTimestamp = 0;\n this._isEnabled = false;\n this.enable();\n }\n\n public enable() {\n if (this.isAndroid) {\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n }\n if (this.isWithoutDeviceMotion) {\n window.addEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n } else {\n window.addEventListener(\"devicemotion\", this._onDeviceMotion);\n }\n this._isEnabled = true;\n }\n\n public disable() {\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n window.removeEventListener(\"devicemotion\", this._onDeviceMotion);\n this._isEnabled = false;\n }\n\n private _onChromeWithoutDeviceMotion(e: DeviceOrientationEvent) {\n let {alpha, beta, gamma} = e;\n\n // There is deviceorientation event trigged with empty values\n // on Headless Chrome.\n if (alpha === null) {\n return;\n }\n\n // convert to radian\n alpha = (alpha || 0) * Math.PI / 180;\n beta = (beta || 0) * Math.PI / 180;\n gamma = (gamma || 0) * Math.PI / 180;\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: {\n deviceorientation: {\n alpha,\n beta,\n gamma: -gamma\n }\n }\n }));\n }\n\n private _onDeviceOrientation() {\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timer = window.setTimeout(() => {\n if ((new Date().getTime() - this.lastDevicemotionTimestamp) < STILLNESS_THRESHOLD) {\n vec3.copy(this.stillGyroVec, this.rawGyroVec);\n }\n }, STILLNESS_THRESHOLD);\n }\n\n private _onDeviceMotion(e: DeviceMotionEvent) {\n // desktop chrome triggers devicemotion event with empthy sensor values.\n // Those events should ignored.\n const isGyroSensorAvailable = !(e.rotationRate!.alpha == null);\n const isGravitySensorAvailable = !(e.accelerationIncludingGravity!.x == null);\n\n if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) {\n return;\n }\n\n const devicemotionEvent = {...e} as Mutable;\n\n devicemotionEvent.interval = e.interval;\n devicemotionEvent.timeStamp = e.timeStamp;\n devicemotionEvent.type = e.type;\n devicemotionEvent.rotationRate = {\n alpha: e.rotationRate!.alpha,\n beta: e.rotationRate!.beta,\n gamma: e.rotationRate!.gamma\n };\n devicemotionEvent.accelerationIncludingGravity = {\n x: e.accelerationIncludingGravity!.x,\n y: e.accelerationIncludingGravity!.y,\n z: e.accelerationIncludingGravity!.z\n };\n devicemotionEvent.acceleration = {\n x: e.acceleration!.x,\n y: e.acceleration!.y,\n z: e.acceleration!.z\n };\n\n if (this.isAndroid) {\n vec3.set(\n this.rawGyroVec,\n e.rotationRate!.alpha || 0,\n e.rotationRate!.beta || 0,\n e.rotationRate!.gamma || 0);\n vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec);\n this.lastDevicemotionTimestamp = new Date().getTime();\n\n (devicemotionEvent as any).adjustedRotationRate = {\n alpha: this.adjustedGyroVec[0],\n beta: this.adjustedGyroVec[1],\n gamma: this.adjustedGyroVec[2]};\n }\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: devicemotionEvent\n }));\n }\n}\n","class SensorSample {\n public sample;\n public timestampS;\n\n public constructor(sample?, timestampS?) {\n this.set(sample, timestampS);\n }\n\n public set(sample, timestampS) {\n this.sample = sample;\n this.timestampS = timestampS;\n }\n\n public copy(sensorSample) {\n this.set(sensorSample.sample, sensorSample.timestampS);\n }\n}\n\nexport default SensorSample;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SensorSample from \"./sensor-sample\";\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * An implementation of a simple complementary filter, which fuses gyroscope and\n * accelerometer data from the 'devicemotion' event.\n *\n * Accelerometer data is very noisy, but stable over the long term.\n * Gyroscope data is smooth, but tends to drift over the long term.\n *\n * This fusion is relatively simple:\n * 1. Get orientation estimates from accelerometer by applying a low-pass filter\n * on that data.\n * 2. Get orientation estimates from gyroscope by integrating over time.\n * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the\n * short term.\n */\nclass ComplementaryFilter {\n public kFilter;\n public currentAccelMeasurement;\n public currentGyroMeasurement;\n public previousGyroMeasurement;\n public filterQ;\n public previousFilterQ;\n public accelQ;\n public isOrientationInitialized;\n public estimatedGravity;\n public measuredGravity;\n public gyroIntegralQ;\n\n constructor(kFilter) {\n this.kFilter = kFilter;\n\n // Raw sensor measurements.\n this.currentAccelMeasurement = new SensorSample();\n this.currentGyroMeasurement = new SensorSample();\n this.previousGyroMeasurement = new SensorSample();\n\n // Set default look direction to be in the correct direction.\n if (Util.isIOS()) {\n this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);\n } else {\n this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);\n }\n this.previousFilterQ = new MathUtil.Quaternion();\n this.previousFilterQ.copy(this.filterQ);\n\n // Orientation based on the accelerometer.\n this.accelQ = new MathUtil.Quaternion();\n // Whether or not the orientation has been initialized.\n this.isOrientationInitialized = false;\n // Running estimate of gravity based on the current orientation.\n this.estimatedGravity = new MathUtil.Vector3();\n // Measured gravity based on accelerometer.\n this.measuredGravity = new MathUtil.Vector3();\n\n // Debug only quaternion of gyro-based orientation.\n this.gyroIntegralQ = new MathUtil.Quaternion();\n }\n\n public addAccelMeasurement(vector, timestampS) {\n this.currentAccelMeasurement.set(vector, timestampS);\n }\n\n public addGyroMeasurement = function(vector, timestampS) {\n this.currentGyroMeasurement.set(vector, timestampS);\n\n const deltaT = timestampS - this.previousGyroMeasurement.timestampS;\n if (Util.isTimestampDeltaValid(deltaT)) {\n this.run_();\n }\n\n this.previousGyroMeasurement.copy(this.currentGyroMeasurement);\n };\n\n public getOrientation() {\n return this.filterQ;\n }\n\n public run_() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n if (Util.isDebug()) {\n console.log(\"Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)\",\n MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),\n (this.estimatedGravity.x).toFixed(1),\n (this.estimatedGravity.y).toFixed(1),\n (this.estimatedGravity.z).toFixed(1),\n (this.measuredGravity.x).toFixed(1),\n (this.measuredGravity.y).toFixed(1),\n (this.measuredGravity.z).toFixed(1));\n }\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n }\n\n private accelToQuaternion_(accel) {\n const normAccel = new MathUtil.Vector3();\n normAccel.copy(accel);\n normAccel.normalize();\n const quat = new MathUtil.Quaternion();\n quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);\n quat.inverse();\n return quat;\n }\n\n private gyroToQuaternionDelta_(gyro, dt) {\n // Extract axis and angle from the gyroscope data.\n const quat = new MathUtil.Quaternion();\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n quat.setFromAxisAngle(axis, gyro.length() * dt);\n return quat;\n }\n}\n\nexport default ComplementaryFilter;\n","import MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport ComplementaryFilter from \"./lib/webvr-polyfill/complementary-filter\";\n\nComplementaryFilter.prototype.run_ = function() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n\n if (!this.isFilterQuaternionInitialized) {\n this.isFilterQuaternionInitialized = true;\n }\n};\n\nComplementaryFilter.prototype.getOrientation = function() {\n if (this.isFilterQuaternionInitialized) {\n return this.filterQ;\n } else {\n return null;\n }\n};\n\nexport default ComplementaryFilter;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\n\nimport { window, IS_IOS, IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { CHROME_VERSION } from \"../consts\";\n\nimport PosePredictor from \"./lib/webvr-polyfill/pose-predictor\";\nimport MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport Util from \"./lib/webvr-polyfill/util\";\nimport DeviceMotion from \"./DeviceMotion\";\nimport ComplementaryFilter from \"./ComplementaryFilter\";\n\n\nconst K_FILTER = 0.98;\nconst PREDICTION_TIME_S = 0.040;\n\nexport default class FusionPoseSensor extends Component<{\n change: {\n quaternion: quat;\n };\n}> {\n public deviceMotion: DeviceMotion | null;\n public accelerometer: any;\n public gyroscope: any;\n public filter: ComplementaryFilter;\n public posePredictor: PosePredictor;\n public filterToWorldQ: any;\n public isFirefoxAndroid: boolean;\n public isIOS: boolean;\n public isChromeUsingDegrees: boolean;\n public inverseWorldToScreenQ: any;\n public worldToScreenQ: any;\n public originalPoseAdjustQ: any;\n public resetQ: any;\n public deviceOrientationFixQ: any;\n public predictedQ: any;\n public previousTimestampS: number;\n\n private _isEnabled: boolean;\n private _deviceOrientationQ: any;\n private _prevOrientation: quat;\n private _alpha: number;\n\n public constructor() {\n super();\n\n this.deviceMotion = new DeviceMotion();\n\n this.accelerometer = new MathUtil.Vector3();\n this.gyroscope = new MathUtil.Vector3();\n\n this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);\n this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);\n\n this.filter = new ComplementaryFilter(K_FILTER);\n this.posePredictor = new PosePredictor(PREDICTION_TIME_S);\n\n this.filterToWorldQ = new MathUtil.Quaternion();\n\n this.isFirefoxAndroid = Util.isFirefoxAndroid();\n // This includes iPhone & iPad(both desktop and mobile mode) ref #326\n this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP;\n\n // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18\n this.isChromeUsingDegrees = CHROME_VERSION >= 66;\n\n this._isEnabled = false;\n\n // Set the filter to world transform, depending on OS.\n if (this.isIOS) {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);\n } else {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n this.inverseWorldToScreenQ = new MathUtil.Quaternion();\n this.worldToScreenQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),\n -window.orientation * Math.PI / 180);\n\n this._setScreenTransform();\n // Adjust this filter for being in landscape mode.\n if (Util.isLandscapeMode()) {\n this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);\n }\n\n // Keep track of a reset transform for resetSensor.\n this.resetQ = new MathUtil.Quaternion();\n\n this.deviceMotion.on(\"devicemotion\", this._onDeviceMotionChange);\n this.enable();\n }\n\n public enable() {\n if (this.isEnabled()) {\n return;\n }\n this.deviceMotion!.enable();\n this._isEnabled = true;\n window.addEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public disable() {\n if (!this.isEnabled()) {\n return;\n }\n this.deviceMotion!.disable();\n this._isEnabled = false;\n window.removeEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public isEnabled() {\n return this._isEnabled;\n }\n\n public destroy() {\n this.disable();\n this.deviceMotion = null;\n }\n\n public getOrientation() {\n let orientation;\n\n // Hack around using deviceorientation instead of devicemotion\n if (this.deviceMotion!.isWithoutDeviceMotion && this._deviceOrientationQ) {\n this.deviceOrientationFixQ = this.deviceOrientationFixQ || (() => {\n const y = new MathUtil.Quaternion()\n .setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -this._alpha);\n\n return y;\n })();\n\n orientation = this._deviceOrientationQ;\n const out = new MathUtil.Quaternion();\n\n out.copy(orientation);\n out.multiply(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.worldToScreenQ);\n out.multiplyQuaternions(this.deviceOrientationFixQ, out);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n } else {\n // Convert from filter space to the the same system used by the\n // deviceorientation event.\n orientation = this.filter.getOrientation();\n\n if (!orientation) {\n return null;\n }\n\n const out = this._convertFusionToPredicted(orientation);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n }\n }\n\n private _triggerChange() {\n const orientation = this.getOrientation();\n\n // if orientation is not prepared. don't trigger change event\n if (!orientation) {\n return;\n }\n\n if (!this._prevOrientation) {\n this._prevOrientation = orientation;\n return;\n }\n\n if (quat.equals(this._prevOrientation, orientation)) {\n return;\n }\n\n this.trigger(new ComponentEvent(\"change\", { quaternion: orientation }));\n }\n\n private _convertFusionToPredicted(orientation: quat) {\n // Predict orientation.\n this.predictedQ =\n this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);\n\n // Convert to THREE coordinate system: -Z forward, Y up, X right.\n const out = new MathUtil.Quaternion();\n\n out.copy(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.predictedQ);\n out.multiply(this.worldToScreenQ);\n\n return out;\n }\n\n private _onDeviceMotionChange({ inputEvent }) {\n const deviceorientation = inputEvent.deviceorientation;\n const deviceMotion = inputEvent;\n const accGravity = deviceMotion.accelerationIncludingGravity;\n const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;\n let timestampS = deviceMotion.timeStamp / 1000;\n\n if (deviceorientation) {\n if (!this._alpha) {\n this._alpha = deviceorientation.alpha;\n }\n this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();\n this._deviceOrientationQ.setFromEulerYXZ(\n deviceorientation.beta,\n deviceorientation.alpha,\n deviceorientation.gamma\n );\n\n this._triggerChange();\n } else {\n // Firefox Android timeStamp returns one thousandth of a millisecond.\n if (this.isFirefoxAndroid) {\n timestampS /= 1000;\n }\n\n this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);\n this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);\n\n // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate`\n // is reported in degrees, so we first convert to radians.\n if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) {\n this.gyroscope.multiplyScalar(Math.PI / 180);\n }\n\n this.filter.addAccelMeasurement(this.accelerometer, timestampS);\n this.filter.addGyroMeasurement(this.gyroscope, timestampS);\n\n this._triggerChange();\n\n this.previousTimestampS = timestampS;\n }\n }\n\n private _onScreenOrientationChange() {\n this._setScreenTransform();\n }\n\n private _setScreenTransform() {\n this.worldToScreenQ.set(0, 0, 0, 1);\n\n const orientation = window.orientation;\n\n switch (orientation) {\n case 0:\n break;\n case 90:\n case -90:\n case 180:\n this.worldToScreenQ\n .setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI);\n break;\n default:\n break;\n }\n this.inverseWorldToScreenQ.copy(this.worldToScreenQ);\n this.inverseWorldToScreenQ.inverse();\n }\n}\n","import Component from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\n\nimport { toAxis } from \"../utils\";\nimport { util, ROTATE_CONSTANT } from \"../../utils/math-util\";\n\nimport FusionPoseSensor from \"./FusionPoseSensor\";\n\nconst getDeltaYaw = (prvQ: quat, curQ: quat): number => {\n const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(util.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nconst getDeltaPitch = (prvQ: quat, curQ: quat): number => {\n const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport default class TiltMotionInput extends Component<{}> {\n public element: HTMLElement;\n public options: { scale: number; threshold: number };\n public fusionPoseSensor: FusionPoseSensor | null;\n public axes: string[];\n public observer: InputTypeObserver | null;\n\n private _prevQuaternion: quat | null;\n private _quaternion: quat | null;\n\n public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {\n super();\n this.element = el;\n\n this._prevQuaternion = null;\n this._quaternion = null;\n\n this.fusionPoseSensor = null;\n\n this.options = {\n ...{\n scale: 1,\n threshold: 0\n }, ...options\n };\n\n this._onPoseChange = this._onPoseChange.bind(this);\n }\n\n public mapAxes(axes: string[]) {\n this.axes = axes;\n }\n\n public connect(observer: InputTypeObserver) {\n if (this.observer) {\n return this;\n }\n this.observer = observer;\n this.fusionPoseSensor = new FusionPoseSensor();\n this.fusionPoseSensor.enable();\n this._attachEvent();\n return this;\n }\n\n public disconnect() {\n if (!this.observer) {\n return this;\n }\n\n this._dettachEvent();\n this.fusionPoseSensor!.disable();\n this.fusionPoseSensor!.destroy();\n this.fusionPoseSensor = null;\n this.observer = null;\n return this;\n }\n\n public destroy() {\n this.disconnect();\n (this.element as any) = null;\n (this.options as any) = null;\n (this.axes as any) = null;\n this._prevQuaternion = null;\n this._quaternion = null;\n }\n\n private _onPoseChange(event) {\n if (!this._prevQuaternion) {\n this._prevQuaternion = quat.clone(event.quaternion);\n this._quaternion = quat.clone(event.quaternion);\n return;\n }\n\n quat.copy(this._prevQuaternion, this._quaternion!);\n quat.copy(this._quaternion!, event.quaternion);\n\n this.observer!.change(this, event, toAxis(this.axes, [\n getDeltaYaw(this._prevQuaternion, this._quaternion as quat),\n getDeltaPitch(this._prevQuaternion, this._quaternion as quat)\n ]));\n }\n\n private _attachEvent() {\n this.fusionPoseSensor!.on(\"change\", this._onPoseChange);\n }\n\n private _dettachEvent() {\n this.fusionPoseSensor!.off(\"change\", this._onPoseChange);\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport { window } from \"../utils/browser\";\n\n// Singleton\nlet screenRotationAngleInst: ScreenRotationAngle | null = null;\nlet refCount = 0;\n\nexport default class ScreenRotationAngle {\n private _spinR: number;\n private _screenOrientationAngle: number;\n\n public constructor() {\n refCount++;\n\n if (screenRotationAngleInst) {\n return screenRotationAngleInst;\n }\n /* eslint-disable */\n screenRotationAngleInst = this;\n /* eslint-enable */\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n\n this._spinR = 0;\n\n this._screenOrientationAngle = 0;\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.addEventListener(\"orientationchange\", this._onOrientationChange);\n }\n\n public getRadian() {\n // Join with screen orientation\n // this._testVal = this._spinR + \", \" + this._screenOrientationAngle + \", \" + window.orientation;\n return this._spinR + glMatrix.toRadian(this._screenOrientationAngle);\n }\n\n public unref() {\n if (--refCount > 0) {\n return;\n }\n\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"orientationchange\", this._onOrientationChange);\n\n this._spinR = 0;\n this._screenOrientationAngle = 0;\n /* eslint-disable */\n screenRotationAngleInst = null;\n /* eslint-enable */\n refCount = 0;\n }\n\n private _onDeviceOrientation(e: DeviceOrientationEvent) {\n if (e.beta === null || e.gamma === null) {\n // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it.\n return;\n }\n\n // Radian\n const betaR = glMatrix.toRadian(e.beta);\n const gammaR = glMatrix.toRadian(e.gamma);\n\n /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */\n this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR));\n }\n\n private _onOrientationChange() {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientationAngle = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n /* iOS */\n this._screenOrientationAngle = window.orientation >= 0 ?\n window.orientation : 360 + (window.orientation as number);\n }\n }\n}\n","import Axes, { PanInput } from \"@egjs/axes\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\nimport { PanInputOption } from \"@egjs/axes/declaration/inputType/PanInput\";\n\nimport ScreenRotationAngle from \"../ScreenRotationAngle\";\n\n/**\n * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle.\n *\n * The reason for using this function is that in VR mode,\n * the roll angle is adjusted in the direction opposite to the screen rotation angle.\n *\n * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move.\n * @extends PanInput\n */\nexport default class RotationPanInput extends PanInput {\n private _useRotation: boolean;\n private _screenRotationAngle: ScreenRotationAngle | null;\n private _userDirection: number;\n\n /**\n * Constructor\n * @private\n * @param {HTMLElement} el target element\n * @param {Object} [options] The option object\n * @param {Boolean} [options.useRotation] Whether to use rotation(or VR)\n */\n public constructor(el: HTMLElement, options: Partial<{ useRotation: boolean } & PanInputOption> = {}) {\n super(el, options);\n\n this._useRotation = false;\n this._screenRotationAngle = null;\n\n this.setUseRotation(!!(options && options.useRotation));\n\n this._userDirection = Axes.DIRECTION_ALL;\n }\n\n public setUseRotation(useRotation: boolean) {\n this._useRotation = useRotation;\n\n if (this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n this._screenRotationAngle = null;\n }\n\n if (this._useRotation) {\n this._screenRotationAngle = new ScreenRotationAngle();\n }\n }\n\n public connect(observer: InputTypeObserver) {\n // User intetened direction\n this._userDirection = this._direction;\n\n // In VR Mode, Use ALL direction if direction is not none\n // Because horizontal and vertical is changed dynamically by screen rotation.\n // this._direction is used to initialize hammerjs\n if (this._useRotation && (this._direction & Axes.DIRECTION_ALL)) {\n this._direction = Axes.DIRECTION_HORIZONTAL;\n }\n\n return super.connect(observer);\n }\n\n public destroy() {\n if (this._useRotation && this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n }\n\n super.destroy();\n }\n\n protected _getOffset(properties: number[], useDirection: boolean[]) {\n if (this._useRotation === false) {\n return super._getOffset(properties, useDirection);\n }\n\n const offset = super._getOffset(properties, [true, true]);\n const newOffset = [0, 0];\n\n const theta = this._screenRotationAngle!.getRadian();\n\n const cosTheta = Math.cos(theta);\n const sinTheta = Math.sin(theta);\n\n // RotateZ\n newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta;\n newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta;\n\n // Use only user allowed direction.\n if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) {\n newOffset[0] = 0;\n } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) {\n newOffset[1] = 0;\n }\n\n return newOffset;\n }\n}\n\n/**\n * Override getDirectionByAngle to return DIRECTION_ALL\n * Ref: https://github.com/naver/egjs-axes/issues/99\n *\n * But we obey axes's rule. If axes's rule is problem, let's apply following code.\n */\n// PanInput.getDirectionByAngle = function (angle, thresholdAngle) {\n// \treturn DIRECTION_ALL;\n// };\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3, glMatrix, quat } from \"gl-matrix\";\n\nimport FusionPoseSensor from \"./input/FusionPoseSensor\";\n\nconst Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0);\n\nexport default class DeviceQuaternion extends Component<{\n change: {\n isTrusted: boolean;\n };\n}> {\n private _fusionPoseSensor: FusionPoseSensor | null;\n private _quaternion: quat;\n\n public constructor() {\n super();\n\n this._fusionPoseSensor = new FusionPoseSensor();\n this._quaternion = quat.create();\n\n this._fusionPoseSensor.enable();\n this._fusionPoseSensor.on(\"change\", e => {\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(\"change\", { isTrusted: true }));\n });\n }\n\n public getCombinedQuaternion(yaw: number) {\n const yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw));\n const conj = quat.conjugate(quat.create(), this._quaternion);\n // Multiply pitch quaternion -> device quaternion -> yaw quaternion\n const outQ = quat.multiply(quat.create(), conj, yawQ);\n\n return outQ;\n }\n\n public destroy() {\n // detach all event handler\n this.off();\n\n if (this._fusionPoseSensor) {\n this._fusionPoseSensor.off();\n this._fusionPoseSensor.destroy();\n this._fusionPoseSensor = null;\n }\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PinchInput, MoveKeyInput, WheelInput } from \"@egjs/axes\";\nimport { vec2, quat, glMatrix } from \"gl-matrix\";\n\nimport { SUPPORT_TOUCH, SUPPORT_DEVICEMOTION } from \"../utils/browserFeature\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { ValueOf } from \"../types/internal\";\n\nimport TiltMotionInput from \"./input/TiltMotionInput\";\nimport RotationPanInput from \"./input/RotationPanInput\";\nimport DeviceQuaternion from \"./DeviceQuaternion\";\nimport {\n GYRO_MODE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n TOUCH_DIRECTION_NONE\n} from \"./consts\";\n\n\nconst DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF];\nconst DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF];\nconst CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF];\n\nexport interface YawPitchControlOptions {\n element: HTMLElement | null;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n touchDirection: number;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n aspectRatio: number;\n}\ninterface YawPitchControlEvents {\n change: ComponentEvent<{\n yaw: number;\n pitch: number;\n fov: number;\n quaternion: quat | null;\n targetElement: HTMLElement;\n isTrusted: boolean;\n }>;\n hold: ComponentEvent<{\n isTrusted: boolean;\n }>;\n animationEnd: ComponentEvent<{\n isTrusted: boolean;\n }>;\n}\n\n/**\n * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates.\n * @alias eg.YawPitchControl\n * @extends eg.Component\n *\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass YawPitchControl extends Component {\n public static VERSION = VERSION;\n // Expose DeviceOrientationControls sub module for test purpose\n public static CONTROL_MODE_VR = CONTROL_MODE_VR;\n public static CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH;\n public static TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL;\n public static TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW;\n public static TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH;\n public static TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE;\n\n public options: YawPitchControlOptions;\n\n private _element: HTMLElement | null;\n private _initialFov: number;\n private _enabled: boolean;\n private _isAnimating: boolean;\n private _deviceQuaternion: DeviceQuaternion | null;\n\n private _axes: Axes;\n private _axesPanInput: RotationPanInput;\n private _axesWheelInput: WheelInput;\n private _axesTiltMotionInput: TiltMotionInput | null;\n private _axesPinchInput: PinchInput | null;\n private _axesMoveKeyInput: MoveKeyInput;\n\n /**\n * @param {object} options The option object of the eg.YawPitch module\n * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module\n * @param {number} [options.yaw=0] initial yaw (degree)\n * @param {number} [options.pitch=0] initial pitch (degree)\n * @param {number} [options.fov=65] initial field of view (degree)\n * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown\n * @param {boolean} [options.useZoom=true] Indicates whether zoom is available\n * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled\n * @param {string} [config.gyroMode=yawPitch] Enables control through device motion.\n * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move)\n * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw\n * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch\n * @param {number[]} [options.fovRange=[30, 110] Range of FOV\n * @param {number} [options.aspectRatio=1] Aspect Ratio\n */\n public constructor(options: Partial) {\n super();\n this.options = {} as any;\n\n const opt = {\n ...{\n element: null,\n yaw: 0,\n pitch: 0,\n fov: 65,\n showPolePoint: false,\n useZoom: true,\n useKeyboard: true,\n gyroMode: GYRO_MODE.YAWPITCH,\n touchDirection: TOUCH_DIRECTION_ALL,\n yawRange: DEFAULT_YAW_RANGE,\n pitchRange: DEFAULT_PITCH_RANGE,\n fovRange: [30, 110],\n aspectRatio: 1 /* TODO: Need Mandatory? */\n }, ...options\n };\n\n this._element = opt.element;\n this._initialFov = opt.fov;\n this._enabled = false;\n this._isAnimating = false;\n this._deviceQuaternion = null;\n\n this._initAxes(opt);\n this.option(opt);\n }\n\n /**\n * Update Pan Scale\n *\n * Scale(Sensitivity) values of panning is related with fov and height.\n * If at least one of them is changed, this function need to be called.\n * @param {*} param\n */\n public updatePanScale(param: Partial<{\n height: number;\n }> = {}) {\n const fov = this._axes.get().fov;\n const areaHeight = param.height || parseInt(window.getComputedStyle(this._element!).height, 10);\n const scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight;\n\n this._axesPanInput.options.scale = [scale, scale];\n this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW;\n\n return this;\n }\n\n public option(): YawPitchControlOptions;\n public option(key: K): YawPitchControlOptions[K];\n public option(key: K, newValue: YawPitchControlOptions[K]): YawPitchControl;\n public option(newOptions: Partial): YawPitchControl;\n /*\n * Override component's option method\n * to call method for updating values which is affected by option change.\n *\n * @param {*} args\n */\n public option(key?: K | Partial, newValue?: YawPitchControlOptions[K]) {\n // Getter\n if (!key) {\n return this._getOptions();\n } else if (key && typeof key === \"string\" && typeof newValue === \"undefined\") {\n return this._getOptions(key);\n }\n\n // Setter\n let newOptions: Partial = {};\n let changedKeyList: string[] = []; // TODO: if value is not changed, then do not push on changedKeyList.\n\n if (typeof key === \"string\") {\n changedKeyList.push(key);\n newOptions[key] = newValue;\n } else {\n const options = key; // Retrieving object here\n changedKeyList = Object.keys(options);\n newOptions = {...options};\n }\n\n this._setOptions(this._getValidatedOptions(newOptions));\n this._applyOptions(changedKeyList);\n return this;\n }\n\n /**\n * Enable YawPitch functionality\n * @method eg.YawPitch#enable\n */\n public enable() {\n if (this._enabled) {\n return this;\n }\n\n this._enabled = true;\n\n // touchDirection is decided by parameter is valid string (Ref. Axes.connect)\n this._applyOptions(Object.keys(this.options));\n\n // TODO: Is this code is needed? Check later.\n this.updatePanScale();\n\n return this;\n }\n\n /**\n * Disable YawPitch functionality\n * @method eg.YawPitch#disable\n */\n public disable(persistOrientation: boolean = false) {\n if (!this._enabled) {\n return this;\n }\n\n // TODO: Check peristOrientation is needed!\n if (!persistOrientation) {\n this._resetOrientation();\n }\n this._axes.disconnect();\n this._enabled = false;\n return this;\n }\n\n /**\n * Set one or more of yaw, pitch, fov\n * @param {Object} coordinate yaw, pitch, fov\n * @param {Number} duration Animation duration. if it is above 0 then it's animated.\n */\n public lookAt({yaw, pitch, fov}, duration) {\n const pos = this._axes.get();\n\n const y = yaw === undefined ? 0 : yaw - pos.yaw;\n const p = pitch === undefined ? 0 : pitch - pos.pitch;\n const f = fov === undefined ? 0 : fov - pos.fov;\n\n // Allow duration of animation to have more than MC_MAXIMUM_DURATION.\n this._axes.options.maximumDuration = Infinity;\n\n this._axes.setBy({\n yaw: y,\n pitch: p,\n fov: f\n }, duration);\n }\n\n public getYawPitch() {\n const yawPitch = this._axes.get();\n\n return {\n yaw: yawPitch.yaw,\n pitch: yawPitch.pitch\n };\n }\n\n public getFov() {\n return this._axes.get().fov;\n }\n\n public getQuaternion() {\n const pos = this._axes.get();\n\n return this._deviceQuaternion!.getCombinedQuaternion(pos.yaw);\n }\n\n public shouldRenderWithQuaternion() {\n return this.options.gyroMode === GYRO_MODE.VR;\n }\n\n /**\n * Destroys objects\n */\n public destroy() {\n /* eslint-disable @typescript-eslint/no-unused-expressions */\n this._axes && this._axes.destroy();\n this._axesPanInput && this._axesPanInput.destroy();\n this._axesWheelInput && this._axesWheelInput.destroy();\n this._axesTiltMotionInput && this._axesTiltMotionInput.destroy();\n this._axesPinchInput && this._axesPinchInput.destroy();\n this._axesMoveKeyInput && this._axesMoveKeyInput.destroy();\n this._deviceQuaternion && this._deviceQuaternion.destroy();\n /* eslint-enable @typescript-eslint/no-unused-expressions */\n }\n\n private _initAxes(opt: YawPitchControlOptions) {\n const yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio);\n const pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint);\n const useRotation = opt.gyroMode === GYRO_MODE.VR;\n\n this._axesPanInput = new RotationPanInput(this._element!, {useRotation});\n this._axesWheelInput = new WheelInput(this._element, {scale: -4});\n this._axesTiltMotionInput = null;\n this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, {scale: -1}) : null;\n this._axesMoveKeyInput = new MoveKeyInput(this._element, {scale: [-6, 6]});\n\n this._axes = new Axes({\n yaw: {\n range: yRange,\n circular: this._isCircular(yRange),\n bounce: [0, 0]\n },\n pitch: {\n range: pRange,\n circular: this._isCircular(pRange),\n bounce: [0, 0]\n },\n fov: {\n range: opt.fovRange,\n circular: [false, false],\n bounce: [0, 0]\n }\n }, {\n deceleration: MC_DECELERATION,\n maximumDuration: MC_MAXIMUM_DURATION\n }, {\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }).on({\n // TODO: change event type after Axes event type inference update\n hold: (evt: any) => {\n // Restore maximumDuration not to be spin too mush.\n this._axes.options.maximumDuration = MC_MAXIMUM_DURATION;\n\n this.trigger(new ComponentEvent(\"hold\", { isTrusted: evt.isTrusted }));\n },\n change: (evt: any) => {\n if (evt.delta.fov !== 0) {\n this._updateControlScale(evt);\n this.updatePanScale();\n }\n this._triggerChange(evt);\n },\n release: evt => {\n this._triggerChange(evt);\n },\n animationEnd: (evt: any) => {\n this.trigger(new ComponentEvent(\"animationEnd\", { isTrusted: evt.isTrusted }));\n }\n });\n }\n\n private _getValidatedOptions(newOptions: Partial) {\n if (newOptions.yawRange) {\n newOptions.yawRange =\n this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio);\n }\n if (newOptions.pitchRange) {\n newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov);\n }\n return newOptions;\n }\n\n private _getOptions(): YawPitchControlOptions;\n private _getOptions(key: K): YawPitchControlOptions[K];\n private _getOptions(key?: K) {\n let value;\n\n if (typeof key === \"string\") {\n value = this.options[key];\n } else if (arguments.length === 0) {\n value = this.options;\n }\n return value;\n }\n\n private _setOptions(options: Partial): void {\n for (const key in options) {\n this.options[key] = options[key];\n }\n }\n\n private _applyOptions(keys: string[]) {\n const options = this.options;\n const axes = this._axes;\n const isVR = options.gyroMode === GYRO_MODE.VR;\n const isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH;\n // If it's VR mode, restrict user interaction to yaw direction only\n const touchDirection = isVR ?\n (TOUCH_DIRECTION_YAW & options.touchDirection) :\n options.touchDirection;\n\n // If one of below is changed, call updateControlScale()\n if (keys.some(key =>\n key === \"showPolePoint\" || key === \"fov\" || key === \"aspectRatio\" ||\n key === \"yawRange\" || key === \"pitchRange\"\n )) {\n // If fov is changed, update pan scale\n if (keys.indexOf(\"fov\") >= 0) {\n axes.setTo({\"fov\": options.fov});\n this.updatePanScale();\n }\n\n this._updateControlScale();\n }\n\n if (keys.some(key => key === \"fovRange\")) {\n const fovRange = options.fovRange;\n const prevFov = axes.get().fov;\n let nextFov = axes.get().fov;\n\n vec2.copy(axes.axis.fov.range as vec2, fovRange as vec2);\n\n if (nextFov < fovRange[0]) {\n nextFov = fovRange[0];\n } else if (prevFov > fovRange[1]) {\n nextFov = fovRange[1];\n }\n\n if (prevFov !== nextFov) {\n axes.setTo({\n fov: nextFov\n }, 0);\n this._updateControlScale();\n this.updatePanScale();\n }\n }\n\n if (keys.some(key => key === \"gyroMode\") && SUPPORT_DEVICEMOTION) {\n // Disconnect first\n if (this._axesTiltMotionInput) {\n this._axes.disconnect(this._axesTiltMotionInput);\n this._axesTiltMotionInput.destroy();\n this._axesTiltMotionInput = null;\n }\n\n if (this._deviceQuaternion) {\n this._deviceQuaternion.destroy();\n this._deviceQuaternion = null;\n }\n\n if (isVR) {\n this._initDeviceQuaternion();\n } else if (isYawPitch) {\n this._axesTiltMotionInput = new TiltMotionInput(this._element!);\n this._axes.connect([\"yaw\", \"pitch\"], this._axesTiltMotionInput);\n }\n\n this._axesPanInput.setUseRotation(isVR);\n }\n\n if (keys.some(key => key === \"useKeyboard\")) {\n const useKeyboard = options.useKeyboard;\n\n if (useKeyboard) {\n axes.connect([\"yaw\", \"pitch\"], this._axesMoveKeyInput);\n } else {\n axes.disconnect(this._axesMoveKeyInput);\n }\n }\n\n if (keys.some(key => key === \"useZoom\")) {\n const useZoom = options.useZoom;\n\n // Disconnect first\n axes.disconnect(this._axesWheelInput);\n if (useZoom) {\n axes.connect([\"fov\"], this._axesWheelInput);\n }\n }\n\n this._togglePinchInputByOption(options.touchDirection, options.useZoom);\n\n if (keys.some(key => key === \"touchDirection\") && this._enabled) {\n this._enableTouch(touchDirection);\n }\n }\n\n private _togglePinchInputByOption(touchDirection: YawPitchControlOptions[\"touchDirection\"], useZoom: boolean) {\n if (this._axesPinchInput) {\n // disconnect first\n this._axes.disconnect(this._axesPinchInput);\n\n // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll.\n if (\n useZoom &&\n touchDirection === TOUCH_DIRECTION_ALL &&\n // TODO: Get rid of using private property of axes instance.\n (this._axes as any)._inputs.indexOf(this._axesPinchInput) === -1\n ) {\n this._axes.connect([\"fov\"], this._axesPinchInput);\n }\n }\n }\n\n private _enableTouch(direction: YawPitchControlOptions[\"touchDirection\"]) {\n // Disconnect first\n if (this._axesPanInput) {\n this._axes.disconnect(this._axesPanInput);\n }\n\n const yawEnabled = direction & TOUCH_DIRECTION_YAW ? \"yaw\" : null;\n const pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? \"pitch\" : null;\n\n this._axes.connect([yawEnabled, pitchEnabled] as string[], this._axesPanInput);\n }\n\n private _initDeviceQuaternion() {\n this._deviceQuaternion = new DeviceQuaternion();\n this._deviceQuaternion.on(\"change\", e => {\n this._triggerChange(e);\n });\n }\n\n private _getValidYawRange(newYawRange: number[], newFov?: number, newAspectRatio?: number) {\n const ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1);\n const fov = newFov || this._axes.get().fov;\n const horizontalFov = fov * ratio;\n const isValid = newYawRange[1] - newYawRange[0] >= horizontalFov;\n\n if (isValid) {\n return newYawRange;\n } else {\n return this.options.yawRange || DEFAULT_YAW_RANGE;\n }\n }\n\n private _getValidPitchRange(newPitchRange: number[], newFov?: number) {\n const fov = newFov || this._axes.get().fov;\n const isValid = newPitchRange[1] - newPitchRange[0] >= fov;\n\n if (isValid) {\n return newPitchRange;\n } else {\n return this.options.pitchRange || DEFAULT_PITCH_RANGE;\n }\n }\n\n private _isCircular(range: number[]) {\n return range[1] - range[0] < 360 ? [false, false] : [true, true];\n }\n\n /**\n * Update yaw/pitch min/max by 5 factor\n *\n * 1. showPolePoint\n * 2. fov\n * 3. yawRange\n * 4. pitchRange\n * 5. aspectRatio\n *\n * If one of above is changed, call this function\n */\n private _updateControlScale(changeEvt?: any) { // TODO: Change type after Axes type inference update\n const opt = this.options;\n const fov = this._axes.get().fov;\n\n const pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint);\n const yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio);\n\n // TODO: If not changed!?\n const pos = this._axes.get();\n let y = pos.yaw;\n let p = pos.pitch;\n\n vec2.copy(this._axes.axis.yaw.range as any, yRange as any);\n vec2.copy(this._axes.axis.pitch.range as any, pRange as any);\n this._axes.axis.yaw.circular = this._isCircular(yRange);\n this._axes.axis.pitch.circular = this._isCircular(pRange);\n\n /**\n * update yaw/pitch by it's range.\n */\n if (y < yRange[0]) {\n y = yRange[0];\n } else if (y > yRange[1]) {\n y = yRange[1];\n }\n\n if (p < pRange[0]) {\n p = pRange[0];\n } else if (p > pRange[1]) {\n p = pRange[1];\n }\n\n if (changeEvt) {\n changeEvt.set({\n yaw: y,\n pitch: p\n });\n }\n\n this._axes.setTo({\n yaw: y,\n pitch: p\n }, 0);\n\n return this;\n }\n\n private _updatePitchRange(pitchRange: number[], fov: number, showPolePoint: boolean) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n // Circular pitch on VR\n return CIRCULAR_PITCH_RANGE;\n }\n\n const verticalAngle = pitchRange[1] - pitchRange[0];\n const halfFov = fov / 2;\n const isPanorama = verticalAngle < 180;\n\n if (showPolePoint && !isPanorama) {\n // Use full pinch range\n return pitchRange.concat();\n }\n\n // Round value as movableCood do.\n return [pitchRange[0] + halfFov, pitchRange[1] - halfFov];\n }\n\n private _updateYawRange(yawRange: number[], fov: number, aspectRatio: number) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n return DEFAULT_YAW_RANGE;\n }\n\n const horizontalAngle = yawRange[1] - yawRange[0];\n\n /**\n * Full 360 Mode\n */\n if (horizontalAngle >= 360) {\n // Don't limit yaw range on Full 360 mode.\n return yawRange.concat();\n }\n\n /**\n * Panorama mode\n */\n // Ref : https://github.com/naver/egjs-view360/issues/290\n const halfHorizontalFov =\n mathUtil.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))) as number;\n\n // Round value as movableCood do.\n return [\n yawRange[0] + halfHorizontalFov,\n yawRange[1] - halfHorizontalFov\n ];\n }\n\n // TODO: update param type after Axes event type inference update\n private _triggerChange(evt: any) {\n const pos = this._axes.get();\n const opt = this.options;\n const event: YawPitchControlEvents[\"change\"] extends ComponentEvent ? T : never = {\n targetElement: opt.element as HTMLElement,\n isTrusted: evt.isTrusted,\n yaw: pos.yaw,\n pitch: pos.pitch,\n fov: pos.fov,\n quaternion: null\n };\n\n if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) {\n event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw);\n }\n\n this.trigger(new ComponentEvent(\"change\", event));\n }\n\n // TODO: makes constant to be logic\n private _adjustAspectRatio(input: number) {\n const inputRange = [\n 0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670,\n 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19,\n 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26,\n 2.30, 2.60, 3.00, 5.00, 6.00\n ];\n const outputRange = [\n 0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710,\n 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15,\n 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72,\n 1.82, 1.92, 2.00, 2.24, 2.30\n ];\n\n let rangeIdx = -1;\n\n for (let i = 0; i < inputRange.length - 1; i++) {\n if (inputRange[i] <= input && inputRange[i + 1] >= input) {\n rangeIdx = i;\n break;\n }\n }\n\n if (rangeIdx === -1) {\n if (inputRange[0] > input) {\n return outputRange[0];\n } else {\n // FIXME: this looks definitely wrong\n return outputRange[(outputRange[0] as any).length - 1];\n }\n }\n\n const inputA = inputRange[rangeIdx];\n const inputB = inputRange[rangeIdx + 1];\n const outputA = outputRange[rangeIdx];\n const outputB = outputRange[rangeIdx + 1];\n\n return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA));\n }\n\n private _lerp(a: number, b: number, fraction: number) {\n return a + fraction * (b - a);\n }\n\n private _resetOrientation() {\n const opt = this.options;\n\n this._axes.setTo({\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }, 0);\n\n return this;\n }\n}\n\nexport default YawPitchControl;\n","/**\n * Constant value for gyro mode.
(Reference {@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide})\n * @ko gyro 모드 대한 상수 값.
({@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide} 참고)\n * @namespace\n * @name GYRO_MODE\n * @memberof eg.view360.PanoViewer\n */\n/**\n * Disable gyro\n * @ko gyro 비활성화\n * @name NONE\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"none\"\n */\n/**\n * YawPitch Mode\n * @ko YawPitch Mode\n * @name YAWPITCH\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"yawPitch\"\n */\n/**\n * VR Mode\n * @ko VR Mode\n * @name VR\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"VR\"\n */\nimport { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\nimport { GYRO_MODE } from \"../YawPitchControl/consts\";\n\n/**\n * Constant value for errors\n * @ko 에러에 대한 상수 값\n * @namespace\n * @name ERROR_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst ERROR_TYPE = {\n /**\n * Unsupported device\n * @ko 미지원 기기\n * @name INVALID_DEVICE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 10\n */\n INVALID_DEVICE: 10,\n /**\n * Webgl not support\n * @ko WEBGL 미지원\n * @name NO_WEBGL\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 11\n */\n NO_WEBGL: 11,\n /**\n * Failed to load image\n * @ko 이미지 로드 실패\n * @name FAIL_IMAGE_LOAD\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 12\n */\n FAIL_IMAGE_LOAD: 12,\n /**\n * Failed to bind texture\n * @ko 텍스쳐 바인딩 실패\n * @name FAIL_BIND_TEXTURE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 13\n */\n FAIL_BIND_TEXTURE: 13,\n /**\n * Only one resource(image or video) should be specified\n * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함)\n * @name INVALID_RESOURCE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 14\n */\n INVALID_RESOURCE: 14,\n /**\n * WebGL context lost occurred\n * @ko WebGL context lost 발생\n * @name RENDERING_CONTEXT_LOST\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 15\n */\n RENDERING_CONTEXT_LOST: 15\n};\n\n/**\n * Constant value for events\n * @ko 이벤트에 대한 상수 값\n * @namespace\n * @name EVENTS\n * @memberof eg.view360.PanoViewer\n */\nconst PANOVIEWER_EVENTS: {\n READY: \"ready\";\n VIEW_CHANGE: \"viewChange\";\n ANIMATION_END: \"animationEnd\";\n ERROR: \"error\";\n} = {\n /**\n * Events that is fired when PanoViewer is ready to show image and handle user interaction.\n * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트\n * @name READY\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default ready\n */\n READY: \"ready\",\n /**\n * Events that is fired when direction or fov is changed.\n * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트\n * @name VIEW_CHANGE\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default viewChange\n */\n VIEW_CHANGE: \"viewChange\",\n /**\n * Events that is fired when animation which is triggered by inertia is ended.\n * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트\n * @name ANIMATION_END\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default animationEnd\n */\n ANIMATION_END: \"animationEnd\",\n /**\n * Events that is fired when error occurs\n * @ko 에러 발생 시 발생하는 이벤트\n * @name ERROR\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default error\n */\n ERROR: \"error\"\n};\n\n/**\n * Constant value for projection type\n * @ko 프로젝션 타입 대한 상수 값\n * @namespace\n * @name PROJECTION_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst PROJECTION_TYPE: {\n EQUIRECTANGULAR: \"equirectangular\";\n CUBEMAP: \"cubemap\";\n CUBESTRIP: \"cubestrip\";\n PANORAMA: \"panorama\";\n STEREOSCOPIC_EQUI: \"stereoequi\";\n} = {\n /**\n * Constant value for equirectangular type.\n * @ko equirectangular 에 대한 상수 값.\n * @name EQUIRECTANGULAR\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default equirectangular\n */\n EQUIRECTANGULAR: \"equirectangular\",\n /**\n * Constant value for cubemap type.\n * @ko cubemap 에 대한 상수 값.\n * @name CUBEMAP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubemap\n */\n CUBEMAP: \"cubemap\",\n /**\n * Constant value for cubestrip type.\n * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC.\n * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다.\n * @name CUBESTRIP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubestrip\n */\n CUBESTRIP: \"cubestrip\",\n /**\n * Constant value for PANORAMA type.\n *\n * PANORAMA is a format for a panorma image which is taken from smartphone.\n * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다.\n *\n * @name PANORAMA\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default panorama\n */\n PANORAMA: \"panorama\",\n /**\n * Constant value for EQUI_STEREOSCOPY type.\n *\n * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present.\n * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다.\n *\n * @name STEREOSCOPIC_EQUI\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default stereoequi\n */\n STEREOSCOPIC_EQUI: \"stereoequi\"\n};\n\n/**\n * A constant value for the format of the stereoscopic equirectangular projection type.\n * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값\n * @namespace\n * @name STEREO_FORMAT\n * @memberof eg.view360.PanoViewer\n */\nconst STEREO_FORMAT: {\n TOP_BOTTOM: \"3dv\";\n LEFT_RIGHT: \"3dh\";\n NONE: \"\";\n} = {\n /**\n * A constant value for format of top bottom stereoscopic 360 equirectangular projection.\n * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name TOP_BOTTOM\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dv\"\n */\n TOP_BOTTOM: \"3dv\",\n /**\n * A constant value for format of left right stereoscopic 360 equirectangular projection.\n * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name LEFT_RIGHT\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dh\"\n */\n LEFT_RIGHT: \"3dh\",\n /**\n * A constant value specifying media is not in stereoscopic format.\n * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"\"\n */\n NONE: \"\"\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst PANOVIEWER_OPTIONS: { [key in keyof PanoViewerOptions]: true } = {\n image: true,\n video: true,\n projectionType: true,\n cubemapConfig: true,\n stereoFormat: true,\n width: true,\n height: true,\n yaw: true,\n pitch: true,\n fov: true,\n showPolePoint: true,\n useZoom: true,\n useKeyboard: true,\n gyroMode: true,\n yawRange: true,\n pitchRange: true,\n fovRange: true,\n touchDirection: true,\n canvasClass: true\n};\n\nconst DEFAULT_CANVAS_CLASS = \"view360-canvas\";\n\nexport {\n GYRO_MODE,\n PANOVIEWER_EVENTS,\n ERROR_TYPE,\n PROJECTION_TYPE,\n STEREO_FORMAT,\n PANOVIEWER_OPTIONS,\n DEFAULT_CANVAS_CLASS\n};\n","import agent from \"@egjs/agent\";\n\nimport { TypedArray } from \"../types/internal\";\n\nconst WEBGL_ERROR_CODE = {\n \"0\": \"NO_ERROR\",\n \"1280\": \"INVALID_ENUM\",\n \"1281\": \"INVALID_VALUE\",\n \"1282\": \"INVALID_OPERATION\",\n \"1285\": \"OUT_OF_MEMORY\",\n \"1286\": \"INVALID_FRAMEBUFFER_OPERATION\",\n \"37442\": \"CONTEXT_LOST_WEBGL\"\n};\n\nlet webglAvailability: boolean | null = null;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet MAX_TEXTURE_SIZE_FOR_TEST: number | null = null;\n\nexport default class WebGLUtils {\n public static createShader(gl: WebGLRenderingContext, type: number, source: string) {\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (success) {\n return shader;\n }\n\n // eslint-disable-next-line\n console.error(gl.getShaderInfoLog(shader));\n\n return null;\n }\n\n public static createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = gl.createProgram()!;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (success) {\n return program;\n }\n\n gl.deleteProgram(program);\n return null;\n }\n\n public static initBuffer(gl: WebGLRenderingContext, target: number /* bind point */, data: TypedArray, itemSize: number, attr?: number) {\n const buffer = gl.createBuffer()!;\n\n gl.bindBuffer(target, buffer);\n gl.bufferData(target, data, gl.STATIC_DRAW);\n\n if (buffer) {\n (buffer as any).itemSize = itemSize;\n (buffer as any).numItems = data.length / itemSize;\n }\n\n if (attr !== undefined) {\n gl.enableVertexAttribArray(attr);\n gl.vertexAttribPointer(attr, (buffer as any).itemSize, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n }\n\n public static getWebglContext(canvas: HTMLCanvasElement, userContextAttributes?: WebGLContextAttributes) {\n const webglIdentifiers = [\"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n const contextAttributes = {\n ...{\n preserveDrawingBuffer: false,\n antialias: false\n }, ...userContextAttributes\n };\n\n const onWebglcontextcreationerror = e => e.statusMessage;\n\n canvas.addEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n return context;\n }\n\n public static createTexture(gl: WebGLRenderingContext, textureTarget: number) {\n const texture = gl.createTexture();\n\n gl.bindTexture(textureTarget, texture);\n gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(textureTarget, null);\n\n return texture;\n }\n\n /**\n * Returns the webgl availability of the current browser.\n * @method WebGLUtils#isWebGLAvailable\n * @retuen {Boolean} isWebGLAvailable\n */\n public static isWebGLAvailable(): boolean {\n if (webglAvailability === null) {\n const canvas = document.createElement(\"canvas\");\n const webglContext = WebGLUtils.getWebglContext(canvas);\n\n webglAvailability = !!webglContext;\n\n // webglContext Resource forced collection\n if (webglContext) {\n const loseContextExtension = webglContext.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n return !!webglAvailability;\n }\n\n /**\n * Returns whether webgl is stable in the current browser.\n * @method WebGLUtils#isStableWebGL\n * @retuen {Boolean} isStableWebGL\n */\n public static isStableWebGL() {\n const agentInfo = agent();\n let isStableWebgl = true;\n\n if (agentInfo.os.name === \"android\") {\n const version = parseFloat(agentInfo.os.version);\n\n if (version <= 4.3 && version >= 1) {\n isStableWebgl = false;\n } else if (version === 4.4) {\n if (agentInfo.browser.name !== \"chrome\") {\n isStableWebgl = false;\n }\n }\n }\n return isStableWebgl;\n }\n\n public static getErrorNameFromWebGLErrorCode(code: number | string) {\n if (!(code in WEBGL_ERROR_CODE)) {\n return \"UNKNOWN_ERROR\";\n }\n\n return WEBGL_ERROR_CODE[code];\n }\n\n\n /**\n * This function is wrapper for texImage2D to handle exceptions on texImage2D.\n * Purpose is to prevent service from being stopped by script error.\n */\n public static texImage2D(gl: WebGLRenderingContext, target: number, pixels: TexImageSource) {\n try {\n gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n } catch (error) {\n /* eslint-disable no-console */\n console.error(\"WebGLUtils.texImage2D error:\", error);\n /* eslint-enable no-console */\n }\n }\n\n public static getMaxTextureSize(gl: WebGLRenderingContext) {\n // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test\n return MAX_TEXTURE_SIZE_FOR_TEST || gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n}\n\n/**\n * This function should not be used in service code. It's provided only for test purpose.\n * It should be set to null or 0 when test is done.\n * @param {Number} size\n */\nconst setMaxTextureSizeForTestOnlyPurpose = (size: number) => {\n MAX_TEXTURE_SIZE_FOR_TEST = size;\n};\n\nexport {\n setMaxTextureSizeForTestOnlyPurpose\n};\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport agent from \"@egjs/agent\";\nimport { mat4 } from \"gl-matrix\";\n\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nconst agentInfo = agent();\nconst isIE11 = agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11;\n\nconst EVENTS: {\n ERROR: \"error\";\n} = {\n ERROR: \"error\"\n};\n\n/**\n *\n * Extends Component for firing errors occurs internally.\n */\nabstract class Renderer extends Component<{\n [EVENTS.ERROR]: {\n message: string;\n };\n}> {\n public static EVENTS = EVENTS;\n\n private _forceDimension: { width: number; height: number } | null;\n private _pixelCanvas: HTMLCanvasElement | null;\n private _pixelContext: CanvasRenderingContext2D | null;\n\n public constructor() {\n super();\n\n this._forceDimension = null;\n this._pixelCanvas = null;\n this._pixelContext = null;\n }\n\n public abstract getVertexPositionData(): number[];\n public abstract getIndexData(): number[];\n public abstract getTextureCoordData(textureData: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }): number[];\n\n public abstract getVertexShaderSource(): string;\n public abstract getFragmentShaderSource(): string;\n public abstract bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n public abstract updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n\n public render({ gl, shaderProgram, indexBuffer, mvMatrix, pMatrix }: {\n gl: WebGLRenderingContext;\n shaderProgram: WebGLProgram;\n indexBuffer: WebGLBuffer;\n mvMatrix: mat4;\n pMatrix: mat4;\n }) {\n gl.uniformMatrix4fv((shaderProgram as any).pMatrixUniform, false, pMatrix);\n gl.uniformMatrix4fv((shaderProgram as any).mvMatrixUniform, false, mvMatrix);\n\n if (indexBuffer) {\n gl.drawElements(gl.TRIANGLES, (indexBuffer as any).numItems, gl.UNSIGNED_SHORT, 0);\n }\n }\n\n // Define interface for Renderers\n /**\n * Following MUST BE DEFINED on Child of Renderer\n *\n * DATA\n *\n * - getVertexPositionData\n * - getIndexData\n * - getTextureCoordData\n *\n * SOURCE\n *\n * - getVertexShaderSource\n * - getFragmentShaderSource\n *\n * TEXTURE\n *\n * - bindTexture\n */\n public getDimension(pixelSource: HTMLImageElement | HTMLVideoElement) {\n const width = (pixelSource as HTMLImageElement).naturalWidth\n || (pixelSource as HTMLVideoElement).videoWidth;\n const height = (pixelSource as HTMLImageElement).naturalHeight\n || (pixelSource as HTMLVideoElement).videoHeight;\n\n return { width, height };\n }\n\n /**\n * Update data used by shader\n */\n public updateShaderData(param) { // eslint-disable-line @typescript-eslint/no-unused-vars\n /*\n * Update following data in implementation layer.\n * If the data is not changed, it does not need to implement this function.\n *\n * - _VERTEX_POSITION_DATA\n * - _TEXTURE_COORD_DATA\n * - _INDEX_DATA\n */\n }\n\n /**\n *\n * @param {HTMLImageElement | HTMLVideoElement} image\n * @param {Object = {width, height}} forceDimension Forced dimension to resize\n */\n protected _initPixelSource(image: HTMLImageElement | HTMLVideoElement, forceDimension: Renderer[\"_forceDimension\"] = null) {\n const isIE11Video = isIE11 && (image instanceof HTMLVideoElement);\n\n if (isIE11Video || forceDimension) {\n const {width, height} = forceDimension || this.getDimension(image);\n\n this._pixelCanvas = document.createElement(\"canvas\");\n this._pixelCanvas.width = width;\n this._pixelCanvas.height = height;\n this._pixelContext = this._pixelCanvas.getContext(\"2d\");\n }\n this._forceDimension = forceDimension;\n }\n\n protected _getPixelSource(image: HTMLImageElement | HTMLVideoElement) {\n if (!this._pixelCanvas) {\n return image;\n }\n\n /**\n * IE11 && Video\n * or\n * Dimension is forced (Image is larger than texture size.)\n */\n const contentDimension = this.getDimension(image);\n const textureDimension = this._forceDimension || contentDimension;\n\n if (this._pixelCanvas.width !== textureDimension.width) {\n this._pixelCanvas.width = textureDimension.width;\n }\n\n if (this._pixelCanvas.height !== textureDimension.height) {\n this._pixelCanvas.height = textureDimension.height;\n }\n\n if (this._forceDimension) {\n this._pixelContext!.drawImage(image,\n 0, 0, contentDimension.width, contentDimension.height,\n 0, 0, textureDimension.width, textureDimension.height);\n } else {\n this._pixelContext!.drawImage(image, 0, 0);\n }\n\n return this._pixelCanvas;\n }\n\n protected _extractTileConfig(imageConfig: CubemapConfig) {\n let tileConfig: TileConfig[] =\n Array.isArray(imageConfig.tileConfig) ?\n imageConfig.tileConfig : Array(...Array(6)).map(() => imageConfig.tileConfig) as TileConfig[];\n\n tileConfig = tileConfig.map(\n config => ({\n ...{\n flipHorizontal: false,\n rotation: 0\n }, ...config\n })\n );\n\n return tileConfig;\n }\n\n protected _triggerError(error) {\n /* eslint-disable no-console */\n console.error(\"Renderer Error:\", error);\n /* eslint-enable no-console */\n\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n message: typeof error === \"string\" ? error : error.message\n }));\n }\n}\n\nexport default Renderer;\n","import agent from \"@egjs/agent\";\n\nimport WebGLUtils from \"../WebGLUtils\";\nimport { util as mathUtil } from \"../../utils/math-util\";\nimport { CubemapConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nclass CubeRenderer extends Renderer {\n public static extractOrder(imageConfig: CubemapConfig) {\n return imageConfig.order || \"RLUDBF\";\n }\n\n private static _VERTEX_POSITION_DATA: number[] | null = null;\n private static _INDEX_DATA: number[] | null = null;\n\n public getVertexPositionData() {\n CubeRenderer._VERTEX_POSITION_DATA =\n CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // top\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // bottom\n 1, -1, -1,\n -1, -1, -1,\n -1, -1, 1,\n 1, -1, 1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n return CubeRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n if (CubeRenderer._INDEX_DATA) {\n return CubeRenderer._INDEX_DATA;\n }\n\n const indexData: number[] = [];\n const vertexPositionData = this.getVertexPositionData();\n\n for (let i = 0; i < (vertexPositionData.length / 3); i += 4) {\n indexData.push(\n i,\n i + 2,\n i + 1,\n i,\n i + 3,\n i + 2\n );\n }\n\n CubeRenderer._INDEX_DATA = indexData;\n return indexData;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n const vertexOrder = \"BFUDRL\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const base = this.getVertexPositionData();\n const tileConfig = this._extractTileConfig(imageConfig);\n const elemSize = 3;\n const vertexPerTile = 4;\n const { trim } = imageConfig;\n\n const texCoords = vertexOrder.split(\"\")\n .map(face => tileConfig[order.indexOf(face)])\n .map((config, i) => {\n const rotation = Math.floor(config.rotation / 90);\n const ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2];\n\n for (let r = 0; r < Math.abs(rotation); r++) {\n if ((config.flipHorizontal && rotation > 0) ||\n (!config.flipHorizontal && rotation < 0)) {\n ordermap.push(ordermap.shift()!);\n } else {\n ordermap.unshift(ordermap.pop()!);\n }\n }\n\n const elemPerTile = elemSize * vertexPerTile;\n const tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile);\n const tileTemp: number[][] = [];\n\n for (let j = 0; j < vertexPerTile; j++) {\n tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize);\n }\n return tileTemp;\n })\n .map(coord => this._shrinkCoord({ image, faceCoords: coord, trim }))\n .reduce((acc: number[], val: number[][]) => [\n ...acc,\n ...val.reduce((coords, coord) => [...coords, ...coord], [])\n ], []);\n\n return texCoords;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n const baseOrder = \"RLUDBF\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const orderMap = {};\n\n order.split(\"\").forEach((v, i) => {\n orderMap[v] = i;\n });\n\n try {\n if (image instanceof Array) {\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]);\n }\n } else {\n const maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image);\n\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n const tile = this.extractTileFromImage(\n image, tileIdx, maxCubeMapTextureSize\n );\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile);\n }\n }\n } catch (e) {\n this._triggerError(e);\n }\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n this.updateTexture(gl, image, imageConfig);\n }\n\n public getSourceTileSize(image: HTMLImageElement | HTMLVideoElement) {\n const {width, height} = this.getDimension(image);\n const aspectRatio = width / height;\n let inputTextureSize;\n\n if (aspectRatio === 1 / 6) {\n inputTextureSize = width;\n } else if (aspectRatio === 6) {\n inputTextureSize = height;\n } else if (aspectRatio === 2 / 3) {\n inputTextureSize = width / 2;\n } else {\n inputTextureSize = width / 3;\n }\n return inputTextureSize;\n }\n\n public extractTileFromImage(image: HTMLImageElement | HTMLVideoElement, tileIdx: number, outputTextureSize: number) {\n const {width} = this.getDimension(image);\n const inputTextureSize = this.getSourceTileSize(image);\n\n const canvas = document.createElement(\"canvas\");\n\n canvas.width = outputTextureSize;\n canvas.height = outputTextureSize;\n const context = canvas.getContext(\"2d\");\n const tilePerRow = width / inputTextureSize;\n\n const x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow);\n const y = Math.floor(tileIdx / tilePerRow) * (inputTextureSize);\n\n context!.drawImage(\n image, x, y,\n inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize\n );\n return canvas;\n }\n\n public getMaxCubeMapTextureSize(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n const agentInfo = agent();\n const maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n let imageWidth = this.getSourceTileSize(image);\n\n if (agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11) {\n if (!mathUtil.isPowerOfTwo(imageWidth)) {\n for (let i = 1; i < maxCubeMapTextureSize; i *= 2) {\n if (i < imageWidth) {\n continue;\n } else {\n imageWidth = i;\n break;\n }\n }\n }\n }\n if (agentInfo.os.name === \"ios\") {\n const majorVersion = agentInfo.os.majorVersion;\n\n // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다.\n if (majorVersion === 9) {\n imageWidth = 1024;\n }\n // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다.\n if (majorVersion === 8) {\n imageWidth = 512;\n }\n }\n // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수\n return Math.min(maxCubeMapTextureSize, imageWidth);\n }\n\n private _shrinkCoord(coordData: {\n image: HTMLImageElement | HTMLVideoElement;\n faceCoords: number[][];\n trim: number;\n }) {\n const { image, faceCoords, trim } = coordData;\n\n const inputTextureSize = Array.isArray(image)\n ? this.getDimension(image[0]).width\n : this.getSourceTileSize(image);\n\n // Shrink by \"trim\" px\n const SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize);\n\n const axisMultipliers = [0, 1, 2].map(axisIndex => {\n const axisDir = mathUtil.sign(faceCoords[0][axisIndex]);\n const notSameDir = faceCoords.some(coord => mathUtil.sign(coord[axisIndex]) !== axisDir);\n\n return notSameDir;\n }).map(notSameDir => notSameDir ? SHRINK_MULTIPLIER : 1);\n\n return faceCoords.map(coords => coords.map((coord, axisIndex) => coord * axisMultipliers[axisIndex]));\n }\n}\n\nexport default CubeRenderer;\n","\nimport WebGLUtils from \"../WebGLUtils\";\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nexport default class CubeStripRenderer extends Renderer {\n private _vertices: number[];\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}`;\n }\n\n public getVertexPositionData() {\n if (!this._vertices) {\n this._vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n }\n\n return this._vertices;\n }\n\n public getIndexData() {\n // TODO: 한번만 계산하도록 수정하기\n const indices = (() => {\n const indexData: number[] = [];\n\n for (let i = 0; i < (this._vertices.length / 3); i += 4) {\n indexData.push(\n i,\n i + 1,\n i + 2,\n i,\n i + 2,\n i + 3\n );\n }\n return indexData;\n })();\n\n return indices;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n // TODO: make it cols, rows as config.\n const cols = 3;\n const rows = 2;\n\n const textureSize = this.getDimension(image);\n const { trim } = imageConfig;\n\n const order = imageConfig.order || \"RLUDFB\";\n let coords: number[][] = [];\n\n // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다.\n for (let r = rows - 1; r >= 0; r--) {\n for (let c = 0; c < cols; c++) {\n const coord = [\n c / cols, r / rows,\n (c + 1) / cols, r / rows,\n (c + 1) / cols, (r + 1) / rows,\n c / cols, (r + 1) / rows\n ];\n\n coords.push(coord);\n }\n }\n\n const tileConfigs = this._extractTileConfig(imageConfig);\n\n // Transform Coord By Flip & Rotation\n coords = coords\n // shrink coord to avoid pixel bleeding\n .map(coord => this._shrinkCoord(coord, textureSize, trim))\n .map((coord, i) => this._transformCoord(coord, tileConfigs[i]));\n\n // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치\n return \"BFUDRL\".split(\"\")\n .map(face => order.indexOf(face))\n .map(index => coords[index])\n .reduce((acc, val) => acc.concat(val), []);\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n private _transformCoord(coord: number[], tileConfig: TileConfig) {\n let newCoord = coord.slice();\n\n if (tileConfig.flipHorizontal) {\n newCoord = this._flipHorizontalCoord(newCoord);\n }\n\n if (tileConfig.rotation) {\n newCoord = this._rotateCoord(newCoord, tileConfig.rotation);\n }\n\n return newCoord;\n }\n\n private _shrinkCoord(coord: number[], textureSize: { width: number; height: number }, trim: number) {\n const { width, height } = textureSize;\n\n // Shrink by \"trim\" px\n const SHRINK_Y = trim * (1 / height);\n const SHRINK_X = trim * (1 / width);\n\n return [\n coord[0] + SHRINK_X, coord[1] + SHRINK_Y,\n coord[2] - SHRINK_X, coord[3] + SHRINK_Y,\n coord[4] - SHRINK_X, coord[5] - SHRINK_Y,\n coord[6] + SHRINK_X, coord[7] - SHRINK_Y\n ];\n }\n\n private _rotateCoord(coord: number[], rotationAngle: number) {\n const SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord.\n const shiftCount = Math.floor(rotationAngle / 90) % 4;\n\n if (shiftCount === 0) {\n return coord;\n }\n\n let moved;\n let rotatedCoord: number[] = [];\n\n if (shiftCount > 0) {\n moved = coord.splice(0, shiftCount * SIZE);\n rotatedCoord = coord.concat(moved);\n } else {\n moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE);\n rotatedCoord = moved.concat(coord);\n }\n\n return rotatedCoord;\n }\n\n private _flipHorizontalCoord(coord: number[]) {\n return [\n coord[2], coord[3],\n coord[0], coord[1],\n coord[6], coord[7],\n coord[4], coord[5]\n ];\n }\n}\n","import WebGLUtils from \"../WebGLUtils\";\nimport { STEREO_FORMAT } from \"../../PanoViewer/consts\";\nimport { ValueOf } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nconst latitudeBands = 60;\nconst longitudeBands = 60;\nconst radius = 2;\nconst ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\nlet latIdx: number;\nlet lngIdx: number;\n\nfor (latIdx = 0; latIdx <= latitudeBands; latIdx++) {\n const theta = (latIdx / latitudeBands - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / longitudeBands;\n const v = latIdx / latitudeBands;\n\n textureCoordData.push(u, v);\n vertexPositionData.push(radius * x, radius * y, radius * z);\n\n if (lngIdx !== longitudeBands && latIdx !== latitudeBands) {\n const a = latIdx * (longitudeBands + 1) + lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n}\n\nclass SphereRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n private _stereoFormat: ValueOf;\n\n public constructor(format: SphereRenderer[\"_stereoFormat\"]) {\n super();\n\n this._stereoFormat = format;\n }\n\n public render(ctx: Parameters[0]) {\n const {gl, shaderProgram} = ctx;\n\n let leftEyeScaleOffset: number[];\n let rightEyeScaleOffset: number[];\n\n switch (this._stereoFormat) {\n case STEREO_FORMAT.TOP_BOTTOM:\n leftEyeScaleOffset = [1, 0.5, 0, 0];\n rightEyeScaleOffset = [1, 0.5, 0, 0.5];\n break;\n case STEREO_FORMAT.LEFT_RIGHT:\n leftEyeScaleOffset = [0.5, 1, 0, 0];\n rightEyeScaleOffset = [0.5, 1, 0.5, 0];\n break;\n default:\n leftEyeScaleOffset = [1, 1, 0, 0];\n rightEyeScaleOffset = [1, 1, 0, 0];\n }\n\n const uTexScaleOffset = gl.getUniformLocation(shaderProgram, \"uTexScaleOffset\");\n\n gl.uniform4fv(uTexScaleOffset, [...leftEyeScaleOffset, ...rightEyeScaleOffset]);\n\n super.render(ctx);\n }\n\n public getVertexPositionData() {\n return SphereRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return SphereRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return SphereRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const { width, height } = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n}\n\nexport default SphereRenderer;\n","import { glMatrix } from \"gl-matrix\";\n\nimport WebGLUtils from \"../WebGLUtils\";\n\nimport Renderer from \"./Renderer\";\n\n// const latitudeBands = 60;\nconst MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6;\nconst longitudeBands = 60;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\n\nclass CylinderRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n public getVertexPositionData() {\n return CylinderRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return CylinderRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return CylinderRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n let resizeDimension: { width: number; height: number } | undefined;\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device texture limit(${maxSize}))`);\n\n // Request resizing texture.\n /**\n * TODO: Is it need to apply on another projection type?\n */\n resizeDimension = width > height ?\n {width: maxSize, height: maxSize * height / width} :\n {width: maxSize * width / height, height: maxSize};\n }\n\n // Pixel Source for IE11 & Video or resizing needed\n this._initPixelSource(image, resizeDimension);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n public updateShaderData({ imageAspectRatio = MIN_ASPECT_RATIO_FOR_FULL_PANORAMA }) {\n let lngIdx: number;\n let cylinderMaxRadian: number;\n let halfCylinderY: number;\n let rotated: boolean;\n let aspectRatio: number;\n\n // Exception case: orientation is rotated.\n if (imageAspectRatio < 1) {\n /**\n * If rotated is true, we assume that image is rotated counter clockwise.\n * TODO: If there's other rotation, it is need to implement by each rotation.\n */\n rotated = true;\n aspectRatio = 1 / imageAspectRatio;\n } else {\n rotated = false;\n aspectRatio = imageAspectRatio;\n }\n\n if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) {\n const fov = 360 / aspectRatio;\n\n cylinderMaxRadian = 2 * Math.PI; // 360 deg\n halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2));\n } else {\n cylinderMaxRadian = aspectRatio;\n halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1.\n }\n\n // initialize shader data before update\n textureCoordData.length = 0;\n vertexPositionData.length = 0;\n indexData.length = 0;\n\n const CYLIDER_Y = [-halfCylinderY, halfCylinderY];\n const startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360)\n\n // console.log(\"cylinderMaxRadian:\", glMatrix.toDegree(cylinderMaxRadian), \"CYLIDER_Y\", CYLIDER_Y, \"start angle\", glMatrix.toDegree(startAngleForCenterAlign));\n for (let yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength/* bottom & top */; yIdx++) {\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const angle = startAngleForCenterAlign + (lngIdx / longitudeBands * cylinderMaxRadian);\n const x = Math.cos(angle);\n const y = CYLIDER_Y[yIdx];\n const z = Math.sin(angle);\n let u: number;\n let v: number;\n\n if (rotated) {\n // Rotated 90 degree (counter clock wise)\n u = 1 - yIdx; // yLength - yIdx;\n v = lngIdx / longitudeBands;\n } else {\n // \t// Normal case (Not rotated)\n u = lngIdx / longitudeBands;\n v = yIdx;\n }\n\n textureCoordData.push(u, v);\n vertexPositionData.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < longitudeBands) {\n const a = lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n }\n}\n\nexport default CylinderRenderer;\n","import Promise from \"promise-polyfill\";\nimport { mat4 } from \"gl-matrix\";\n\nconst VR_DISPLAY_PRESENT_CHANGE = \"vrdisplaypresentchange\";\nconst DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1];\nconst DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1];\nconst EYES = {\n LEFT: \"left\",\n RIGHT: \"right\"\n} as const;\n\nclass VRManager {\n private _vrDisplay: VRDisplay | null;\n private _frameData: VRFrameData;\n private _yawOffset: number;\n private _leftBounds: number[];\n private _rightBounds: number[];\n\n public constructor() {\n this._frameData = new window.VRFrameData();\n this._clear();\n }\n\n public get context() { return this._vrDisplay; }\n\n public destroy = () => {\n const vrDisplay = this._vrDisplay;\n\n this.removeEndCallback(this.destroy);\n\n if (vrDisplay && vrDisplay.isPresenting) {\n void vrDisplay.exitPresent();\n }\n\n this._clear();\n };\n\n public canRender() {\n return Boolean(this._vrDisplay);\n }\n\n public beforeRender(gl: WebGLRenderingContext) {\n // Render to the default backbuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public afterRender() {\n this._vrDisplay!.submitFrame();\n }\n\n public getEyeParams(gl: WebGLRenderingContext) {\n const display = this._vrDisplay!;\n const halfWidth = gl.drawingBufferWidth * 0.5;\n const height = gl.drawingBufferHeight;\n const frameData = this._frameData;\n\n display.getFrameData(frameData);\n\n const leftMVMatrix = frameData.leftViewMatrix;\n const rightMVMatrix = frameData.rightViewMatrix;\n\n mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset);\n mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset);\n\n return [\n {\n viewport: [0, 0, halfWidth, height],\n mvMatrix: leftMVMatrix,\n pMatrix: frameData.leftProjectionMatrix\n },\n {\n viewport: [halfWidth, 0, halfWidth, height],\n mvMatrix: rightMVMatrix,\n pMatrix: frameData.rightProjectionMatrix\n }\n ];\n }\n\n public isPresenting() {\n return Boolean(this._vrDisplay && this._vrDisplay.isPresenting);\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public requestPresent(canvas: HTMLCanvasElement) {\n return navigator.getVRDisplays().then(displays => {\n const vrDisplay = displays.length && displays[0];\n\n if (!vrDisplay) {\n return Promise.reject(new Error(\"No displays available.\"));\n }\n if (!vrDisplay.capabilities.canPresent) {\n return Promise.reject(new Error(\"Display lacking capability to present.\"));\n }\n\n return vrDisplay.requestPresent([{source: canvas}]).then(() => {\n const leftEye = vrDisplay.getEyeParameters(EYES.LEFT);\n const rightEye = vrDisplay.getEyeParameters(EYES.RIGHT);\n\n canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;\n canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);\n\n this._setDisplay(vrDisplay);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setDisplay(vrDisplay: VRDisplay) {\n this._vrDisplay = vrDisplay;\n\n const layers = vrDisplay.getLayers();\n\n if (layers.length) {\n const layer = layers[0];\n\n this._leftBounds = layer.leftBounds as number[];\n this._rightBounds = layer.rightBounds as number[];\n }\n\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._vrDisplay = null;\n this._leftBounds = DEFAULT_LEFT_BOUNDS;\n this._rightBounds = DEFAULT_RIGHT_BOUNDS;\n this._yawOffset = 0;\n }\n}\n\nexport default VRManager;\n","import { mat4, glMatrix } from \"gl-matrix\";\nimport { XRFrame, XRLayer, XRReferenceSpace, XRSession, XRSessionInit } from \"webxr\";\n\nimport { IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { merge } from \"../../utils/utils\";\n\nconst XR_REFERENCE_SPACE = \"local\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\nclass XRManager {\n private _xrSession: XRSession | null;\n private _xrLayer: XRLayer | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n private _yawOffset: number;\n private _presenting: boolean;\n\n public constructor(options: XRSessionOptions = {}) {\n this._clear();\n this._options = options;\n }\n\n public get context() { return this._xrSession; }\n\n public destroy = () => {\n const xrSession = this._xrSession;\n\n this.removeEndCallback(this.destroy);\n\n if (xrSession) {\n // Capture to avoid errors\n xrSession.end().then(() => void 0, () => void 0);\n }\n this._clear();\n };\n\n public canRender(frame: XRFrame) {\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n return Boolean(pose);\n }\n\n public beforeRender(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer!.framebuffer);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n public afterRender() {}\n\n public getEyeParams(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) {\n // Can't render\n return null;\n }\n\n const glLayer = session.renderState.baseLayer;\n\n return pose.views.map(view => {\n const viewport = glLayer!.getViewport(view);\n const mvMatrix = view.transform.inverse.matrix;\n\n if (IS_SAFARI_ON_DESKTOP) {\n mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180));\n }\n\n mat4.rotateY(mvMatrix, mvMatrix, this._yawOffset);\n\n return {\n viewport: [viewport.x, viewport.y, viewport.width, viewport.height],\n mvMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n public isPresenting() {\n return this._presenting;\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.addEventListener(\"end\", callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.removeEventListener(\"end\", callback);\n }\n\n public async requestPresent(canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {\n const options = merge({\n requiredFeatures: [XR_REFERENCE_SPACE]\n }, this._options);\n\n const attributes = gl.getContextAttributes();\n if (attributes && (attributes as any).xrCompatible !== true) {\n await (gl as any).makeXRCompatible();\n }\n\n return (navigator as any).xr.requestSession(\"immersive-vr\", options).then(session => {\n const xrLayer = new (window as any).XRWebGLLayer(session, gl);\n\n session.updateRenderState({baseLayer: xrLayer});\n return session.requestReferenceSpace(XR_REFERENCE_SPACE)\n .then(refSpace => {\n this._setSession(session, xrLayer, refSpace);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setSession(session: XRSession, xrLayer: XRLayer, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrLayer = xrLayer;\n this._xrRefSpace = refSpace;\n this._presenting = true;\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._xrSession = null;\n this._xrLayer = null;\n this._xrRefSpace = null;\n this._presenting = false;\n this._yawOffset = 0;\n this._options = {};\n }\n}\n\nexport default XRManager;\n","import { IS_SAFARI_ON_DESKTOP } from \"../utils/browser\";\n\nclass WebGLAnimator {\n private _callback: ((...args: any[]) => any) | null;\n private _context: any;\n private _rafId: number;\n private _rafTimer: number;\n\n public constructor() {\n this._callback = null;\n this._context = window;\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public setCallback(callback: (...args: any[]) => any) {\n this._callback = callback;\n }\n\n public setContext(context: any) {\n this._context = context;\n }\n\n public start() {\n const context = this._context;\n const callback = this._callback;\n\n // No context / callback set\n if (!context || !callback) return;\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n if (IS_SAFARI_ON_DESKTOP) {\n this._rafId = context.requestAnimationFrame(this._onLoopNextTick);\n } else {\n this._rafId = context.requestAnimationFrame(this._onLoop);\n }\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n /**\n * There can be more than 1 argument when we use XRSession's raf\n */\n private _onLoop = (...args: any[]) => {\n this._callback!(...args);\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n };\n\n /**\n * MacOS X Safari Bug Fix\n * This code guarantees that rendering should be occurred.\n *\n * In MacOS X(10.14.2), Safari (12.0.2)\n * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term\n * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms)\n * So browser cannot render the frame and may be freezing.\n */\n private _onLoopNextTick = (...args: any[]) => {\n const before = performance.now();\n\n this._callback!(...args);\n\n const diff = performance.now() - before;\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n this._rafTimer = -1;\n }\n\n /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */\n if (diff < 16) {\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n } else {\n /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */\n this._rafTimer = window.setTimeout(this._onLoop, 0);\n }\n };\n}\n\nexport default WebGLAnimator;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { XRFrame } from \"webxr\";\nimport Promise from \"promise-polyfill\";\nimport { glMatrix, vec3, mat3, mat4, quat } from \"gl-matrix\";\nimport ImReady, { OnReady } from \"@egjs/imready\";\n\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { devicePixelRatio, WEBXR_SUPPORTED } from \"../utils/browserFeature\";\nimport { PROJECTION_TYPE, STEREO_FORMAT } from \"../PanoViewer/consts\";\nimport { IS_IOS } from \"../utils/browser\";\nimport { CubemapConfig, ImageCandidate, ValueOf, VideoCandidate } from \"../types/internal\";\nimport YawPitchControl from \"../YawPitchControl/YawPitchControl\";\nimport { toImageElement, toVideoElement } from \"../utils/utils\";\n\nimport WebGLUtils from \"./WebGLUtils\";\nimport Renderer from \"./renderer/Renderer\";\nimport CubeRenderer from \"./renderer/CubeRenderer\";\nimport CubeStripRenderer from \"./renderer/CubeStripRenderer\";\nimport SphereRenderer from \"./renderer/SphereRenderer\";\nimport CylinderRenderer from \"./renderer/CylinderRenderer\";\nimport VRManager from \"./vr/VRManager\";\nimport XRManager from \"./vr/XRManager\";\nimport WebGLAnimator from \"./WebGLAnimator\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ImageType = PROJECTION_TYPE;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet DEVICE_PIXEL_RATIO = devicePixelRatio || 1;\n\n// DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다.\nif (DEVICE_PIXEL_RATIO > 2) {\n DEVICE_PIXEL_RATIO = 2;\n}\n\n// define custom events name\n/**\n * TODO: how to manage events/errortype with PanoViewer\n *\n * I think renderer events should be seperated from viewer events although it has same name.\n */\nconst EVENTS: {\n BIND_TEXTURE: \"bindTexture\";\n IMAGE_LOADED: \"imageLoaded\";\n ERROR: \"error\";\n RENDERING_CONTEXT_LOST: \"renderingContextLost\";\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\";\n} = {\n BIND_TEXTURE: \"bindTexture\",\n IMAGE_LOADED: \"imageLoaded\",\n ERROR: \"error\",\n RENDERING_CONTEXT_LOST: \"renderingContextLost\",\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\"\n};\n\nconst ERROR_TYPE = {\n INVALID_DEVICE: 10,\n NO_WEBGL: 11,\n FAIL_IMAGE_LOAD: 12,\n RENDERER_ERROR: 13\n};\n\nclass PanoImageRenderer extends Component<{\n [EVENTS.ERROR]: {\n type: number;\n message: string;\n };\n [EVENTS.IMAGE_LOADED]: {\n content: HTMLElement;\n isVideo: boolean;\n projectionType: ValueOf;\n };\n [EVENTS.BIND_TEXTURE]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_LOST]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_RESTORE]: ComponentEvent;\n}> {\n public static EVENTS = EVENTS;\n public static ERROR_TYPE = ERROR_TYPE;\n\n public sphericalConfig: {\n initialYaw: number;\n initialPitch: number;\n fieldOfView: number;\n imageType: ValueOf;\n stereoFormat: ValueOf;\n cubemapConfig: Partial;\n };\n\n public fieldOfView: number;\n public width: number;\n public height: number;\n\n public canvas: HTMLCanvasElement;\n public context: WebGLRenderingContext;\n public shaderProgram: WebGLProgram | null;\n public texture: WebGLTexture;\n\n public pMatrix: mat4;\n public mvMatrix: mat4;\n\n public textureCoordBuffer: WebGLBuffer | null = null;\n public vertexBuffer: WebGLBuffer | null = null;\n public indexBuffer: WebGLBuffer | null = null;\n\n private _wrapper: HTMLElement | null;\n private _wrapperOrigStyle: string | null;\n private _lastQuaternion: quat | null;\n private _lastYaw: number | null;\n private _lastPitch: number | null;\n private _lastFieldOfView: number | null;\n private _renderingContextAttributes?: WebGLContextAttributes;\n\n private _renderer: Renderer;\n private _contentLoader: ImReady | null;\n private _image: HTMLImageElement | HTMLImageElement[] | HTMLVideoElement | null;\n private _imageConfig: CubemapConfig | null;\n private _imageType: ValueOf;\n private _imageIsReady: boolean;\n private _isVideo: boolean;\n private _isCubeMap: boolean;\n private _shouldForceDraw: boolean;\n private _keepUpdate: boolean;\n private _hasExternalCanvas: boolean;\n\n private _yawPitchControl: YawPitchControl;\n private _animator: WebGLAnimator;\n private _vr: VRManager | XRManager | null;\n\n public constructor(\n image: ImageCandidate | VideoCandidate,\n width: number,\n height: number,\n isVideo: boolean,\n container: HTMLElement,\n canvasClass: string,\n sphericalConfig: PanoImageRenderer[\"sphericalConfig\"],\n renderingContextAttributes?: WebGLContextAttributes\n ) {\n // Super constructor\n super();\n\n this.sphericalConfig = sphericalConfig;\n this.fieldOfView = sphericalConfig.fieldOfView;\n\n this.width = width;\n this.height = height;\n\n this._lastQuaternion = null;\n this._lastYaw = null;\n this._lastPitch = null;\n this._lastFieldOfView = null;\n\n this.pMatrix = mat4.create();\n this.mvMatrix = mat4.create();\n\n // initialzie pMatrix\n mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), width / height, 0.1, 100);\n\n this.textureCoordBuffer = null;\n this.vertexBuffer = null;\n this.indexBuffer = null;\n\n this.canvas = this._initCanvas(container, canvasClass, width, height);\n\n this._setDefaultCanvasStyle();\n this._wrapper = null; // canvas wrapper\n this._wrapperOrigStyle = null;\n\n this._renderingContextAttributes = renderingContextAttributes;\n this._image = null;\n this._imageConfig = null;\n this._imageIsReady = false;\n this._shouldForceDraw = false;\n this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still.\n\n this._onContentLoad = this._onContentLoad.bind(this);\n this._onContentError = \tthis._onContentError.bind(this);\n\n this._animator = new WebGLAnimator();\n\n // VR/XR manager\n this._vr = null;\n\n if (image) {\n this.setImage({\n image,\n imageType: sphericalConfig.imageType,\n isVideo,\n cubemapConfig: sphericalConfig.cubemapConfig\n });\n }\n }\n\n // FIXME: Please refactor me to have more loose connection to yawpitchcontrol\n public setYawPitchControl(yawPitchControl: YawPitchControl) {\n this._yawPitchControl = yawPitchControl;\n }\n\n public getContent() {\n return this._image;\n }\n\n public setImage({\n image,\n imageType,\n isVideo = false,\n cubemapConfig\n }: {\n image: ImageCandidate | VideoCandidate;\n imageType: PanoImageRenderer[\"_imageType\"];\n isVideo: boolean;\n cubemapConfig: Partial;\n }) {\n this._imageIsReady = false;\n this._isVideo = isVideo;\n this._imageConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only */\n order: (imageType === ImageType.CUBEMAP) ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n },\n ...cubemapConfig\n };\n this._setImageType(imageType);\n\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._contentLoader = new ImReady()\n .on(\"ready\", this._onContentLoad)\n .on(\"error\", this._onContentError);\n\n if (isVideo) {\n this._image = toVideoElement(image as VideoCandidate);\n this._contentLoader.check([this._image]);\n this._keepUpdate = true;\n } else {\n this._image = toImageElement(image as ImageCandidate);\n this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n this._keepUpdate = false;\n }\n }\n\n public isImageLoaded() {\n return !!this._image && this._imageIsReady &&\n (!this._isVideo || (this._image as HTMLVideoElement).readyState >= 2 /* HAVE_CURRENT_DATA */);\n }\n\n public bindTexture() {\n return new Promise((res, rej) => {\n const contentLoader = this._contentLoader;\n\n if (!this._image) {\n return rej(\"Image is not defined\");\n }\n\n if (!contentLoader) {\n return rej(\"ImageLoader is not initialized\");\n }\n\n if (contentLoader.isReady()) {\n this._bindTexture();\n res();\n } else {\n contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n contentLoader.once(\"ready\", e => {\n if (e.errorCount > 0) {\n rej(\"Failed to load images.\");\n } else {\n this._bindTexture();\n res();\n }\n });\n }\n });\n }\n\n // 부모 엘리먼트에 canvas 를 붙임\n public attachTo(parentElement) {\n if (!this._hasExternalCanvas) {\n this.detach();\n parentElement.appendChild(this.canvas);\n }\n this._wrapper = parentElement;\n }\n\n public forceContextLoss() {\n if (this.hasRenderingContext()) {\n const loseContextExtension = this.context.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n\n // 부모 엘리먼트에서 canvas 를 제거\n public detach() {\n if (!this._hasExternalCanvas && this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n\n public destroy() {\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._animator.stop();\n this.detach();\n this.forceContextLoss();\n\n this.off();\n\n this.canvas.removeEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n this.canvas.removeEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n }\n\n public hasRenderingContext() {\n const ctx = this.context;\n if (\n !ctx\n || ctx.isContextLost()\n || !ctx.getProgramParameter(this.shaderProgram!, ctx.LINK_STATUS)) {\n return false;\n }\n return true;\n }\n\n public updateFieldOfView(fieldOfView) {\n this.fieldOfView = fieldOfView;\n this._updateViewport();\n }\n\n public updateViewportDimensions(width, height) {\n let viewPortChanged = false;\n\n this.width = width;\n this.height = height;\n\n const w = width * DEVICE_PIXEL_RATIO;\n const h = height * DEVICE_PIXEL_RATIO;\n\n if (w !== this.canvas.width) {\n this.canvas.width = w;\n viewPortChanged = true;\n }\n\n if (h !== this.canvas.height) {\n this.canvas.height = h;\n viewPortChanged = true;\n }\n\n if (!viewPortChanged) {\n return;\n }\n\n this._updateViewport();\n this._shouldForceDraw = true;\n }\n\n public keepUpdate(doUpdate) {\n if (doUpdate && this.isImageLoaded() === false) {\n // Force to draw a frame after image is loaded on render()\n this._shouldForceDraw = true;\n }\n\n this._keepUpdate = doUpdate;\n }\n\n public startRender() {\n this._animator.setCallback(this._render.bind(this));\n this._animator.start();\n }\n\n public stopRender() {\n this._animator.stop();\n }\n\n public renderWithQuaternion(quaternion, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // updatefieldOfView only if fieldOfView is changed.\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion);\n\n this._draw();\n\n this._lastQuaternion = quat.clone(quaternion);\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n public renderWithYawPitch(yaw, pitch, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastYaw !== null && this._lastYaw === yaw &&\n this._lastPitch !== null && this._lastPitch === pitch &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n mat4.identity(this.mvMatrix);\n mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch));\n mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw));\n\n this._draw();\n\n this._lastYaw = yaw;\n this._lastPitch = pitch;\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n /**\n * Returns projection renderer by each type\n */\n public getProjectionRenderer() {\n return this._renderer;\n }\n\n /**\n * @return Promise\n */\n public enterVR(options) {\n const vr = this._vr;\n\n if (!WEBXR_SUPPORTED && !(navigator as any).getVRDisplays) {\n return Promise.reject(\"VR is not available on this browser.\");\n }\n if (vr && vr.isPresenting()) {\n return Promise.resolve(\"VR already enabled.\");\n }\n\n return this._requestPresent(options);\n }\n\n public exitVR = () => {\n const vr = this._vr;\n const gl = this.context;\n const animator = this._animator;\n\n if (!vr) return;\n\n vr.removeEndCallback(this.exitVR);\n vr.destroy();\n this._vr = null;\n\n // Restore canvas & context on iOS\n if (IS_IOS) {\n this._restoreStyle();\n }\n this.updateViewportDimensions(this.width, this.height);\n this._updateViewport();\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._bindBuffers();\n this._shouldForceDraw = true;\n\n animator.stop();\n animator.setContext(window);\n animator.setCallback(this._render.bind(this));\n animator.start();\n };\n\n private _setImageType(imageType) {\n if (!imageType || this._imageType === imageType) {\n return;\n }\n\n this._imageType = imageType;\n this._isCubeMap = imageType === ImageType.CUBEMAP;\n\n if (this._renderer) {\n this._renderer.off();\n }\n\n switch (imageType) {\n case ImageType.CUBEMAP:\n this._renderer = new CubeRenderer();\n break;\n case ImageType.CUBESTRIP:\n this._renderer = new CubeStripRenderer();\n break;\n case ImageType.PANORAMA:\n this._renderer = new CylinderRenderer();\n break;\n case ImageType.STEREOSCOPIC_EQUI:\n this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat);\n break;\n default:\n this._renderer = new SphereRenderer(STEREO_FORMAT.NONE);\n break;\n }\n\n this._renderer.on(Renderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERER_ERROR,\n message: e.message\n }));\n });\n\n this._initWebGL();\n }\n\n private _initCanvas(container: HTMLElement, canvasClass: string, width: number, height: number) {\n const canvasInContainer = container.querySelector(`.${canvasClass}`);\n const canvas = canvasInContainer || this._createCanvas(canvasClass);\n\n this._hasExternalCanvas = !!canvasInContainer;\n\n canvas.width = width;\n canvas.height = height;\n\n this._onWebglcontextlost = this._onWebglcontextlost.bind(this);\n this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this);\n\n canvas.addEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n canvas.addEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n\n return canvas;\n }\n\n private _createCanvas(className: string) {\n const canvas = document.createElement(\"canvas\");\n\n canvas.className = className;\n\n return canvas;\n }\n\n private _setDefaultCanvasStyle() {\n const canvas = this.canvas;\n\n canvas.style.bottom = \"0\";\n canvas.style.left = \"0\";\n canvas.style.right = \"0\";\n canvas.style.top = \"0\";\n canvas.style.margin = \"auto\";\n canvas.style.maxHeight = \"100%\";\n canvas.style.maxWidth = \"100%\";\n canvas.style.outline = \"none\";\n canvas.style.position = \"absolute\";\n }\n\n private _onContentError() {\n this._imageIsReady = false;\n this._image = null;\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_IMAGE_LOAD,\n message: \"failed to load image\"\n }));\n\n return false;\n }\n\n private _triggerContentLoad() {\n this.trigger(new ComponentEvent(EVENTS.IMAGE_LOADED, {\n content: this._image as HTMLElement,\n isVideo: this._isVideo,\n projectionType: this._imageType\n }));\n }\n\n private _onContentLoad(e: OnReady) {\n if (e.errorCount > 0) return;\n\n this._imageIsReady = true;\n\n this._triggerContentLoad();\n }\n\n private _initShaderProgram() {\n const gl = this.context;\n\n if (this.shaderProgram) {\n gl.deleteProgram(this.shaderProgram);\n this.shaderProgram = null;\n }\n\n const renderer = this._renderer;\n\n const vsSource = renderer.getVertexShaderSource();\n const fsSource = renderer.getFragmentShaderSource();\n\n const vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource)!;\n const fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource)!;\n\n const shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader);\n\n if (!shaderProgram) {\n throw new Error(`Failed to initialize shaders: ${WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())}`);\n }\n\n gl.useProgram(shaderProgram);\n (shaderProgram as any).vertexPositionAttribute = gl.getAttribLocation(shaderProgram, \"aVertexPosition\");\n (shaderProgram as any).pMatrixUniform = gl.getUniformLocation(shaderProgram, \"uPMatrix\");\n (shaderProgram as any).mvMatrixUniform = gl.getUniformLocation(shaderProgram, \"uMVMatrix\");\n (shaderProgram as any).samplerUniform = gl.getUniformLocation(shaderProgram, \"uSampler\");\n (shaderProgram as any).textureCoordAttribute = gl.getAttribLocation(shaderProgram, \"aTextureCoord\");\n (shaderProgram as any).uEye = gl.getUniformLocation(shaderProgram, \"uEye\");\n\n gl.enableVertexAttribArray((shaderProgram as any).vertexPositionAttribute);\n gl.enableVertexAttribArray((shaderProgram as any).textureCoordAttribute);\n\n // clear buffer\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\n // Use TEXTURE0\n gl.uniform1i((shaderProgram as any).samplerUniform, 0);\n\n this.shaderProgram = shaderProgram;\n }\n\n private _onWebglcontextlost(e) {\n e.preventDefault();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_LOST));\n }\n\n private _onWebglcontextrestored() {\n this._initWebGL();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_RESTORE));\n }\n\n private _updateViewport() {\n mat4.perspective(\n this.pMatrix,\n glMatrix.toRadian(this.fieldOfView),\n this.canvas.width / this.canvas.height,\n 0.1,\n 100);\n\n this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight);\n }\n\n private _initWebGL() {\n let gl: WebGLRenderingContext;\n\n // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed.\n try {\n this._initRenderingContext();\n gl = this.context;\n\n this.updateViewportDimensions(this.width, this.height);\n this._initShaderProgram();\n } catch (e) {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n this.destroy();\n console.error(e); // eslint-disable-line no-console\n return;\n }\n // 캔버스를 투명으로 채운다.\n gl.clearColor(0, 0, 0, 0);\n const textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\n\n if (this.texture) {\n gl.deleteTexture(this.texture);\n }\n\n this.texture = WebGLUtils.createTexture(gl, textureTarget)!;\n\n if (this._imageType === ImageType.CUBESTRIP) {\n // TODO: Apply following options on other projection type.\n gl.enable(gl.CULL_FACE);\n // gl.enable(gl.DEPTH_TEST);\n }\n }\n\n private _initRenderingContext() {\n if (this.hasRenderingContext()) {\n return;\n }\n\n if (!window.WebGLRenderingContext) {\n throw new Error(\"WebGLRenderingContext not available.\");\n }\n\n this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes)!;\n\n if (!this.context) {\n throw new Error(\"Failed to acquire 3D rendering context\");\n }\n }\n\n private _initBuffers() {\n const image = this._image as HTMLImageElement | HTMLVideoElement;\n\n const vertexPositionData = this._renderer.getVertexPositionData();\n const indexData = this._renderer.getIndexData();\n const textureCoordData = this._renderer.getTextureCoordData({\n image,\n imageConfig: this._imageConfig!\n });\n const gl = this.context;\n\n this.vertexBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3,\n (this.shaderProgram as any).vertexPositionAttribute);\n\n this.indexBuffer = WebGLUtils.initBuffer(\n gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1);\n\n this.textureCoordBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2,\n (this.shaderProgram as any).textureCoordAttribute);\n\n this._bindBuffers();\n }\n\n private _bindTexture() {\n // Detect if it is EAC Format while CUBESTRIP mode.\n // We assume it is EAC if image is not 3/2 ratio.\n if (this._imageType === ImageType.CUBESTRIP) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const isEAC = width && height && width / height !== 1.5 ? 1 : 0;\n\n this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram!, \"uIsEAC\"), isEAC);\n } else if (this._imageType === ImageType.PANORAMA) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const imageAspectRatio = width && height && width / height;\n\n this._renderer.updateShaderData({imageAspectRatio});\n }\n\n // initialize shader buffers after image is loaded.(by updateShaderData)\n // because buffer may be differ by image size.(eg. CylinderRenderer)\n this._initBuffers();\n\n this._renderer.bindTexture(\n this.context,\n this.texture,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n this._shouldForceDraw = true;\n\n this.trigger(new ComponentEvent(EVENTS.BIND_TEXTURE));\n }\n\n private _updateTexture() {\n this._renderer.updateTexture(\n this.context,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n }\n\n private _render() {\n const yawPitchControl = this._yawPitchControl;\n const fov = yawPitchControl.getFov();\n\n if (yawPitchControl.shouldRenderWithQuaternion()) {\n const quaternion = yawPitchControl.getQuaternion();\n\n this.renderWithQuaternion(quaternion, fov);\n } else {\n const yawPitch = yawPitchControl.getYawPitch();\n\n this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov);\n }\n }\n\n private _renderStereo = (time: number, frame: XRFrame) => {\n const vr = this._vr;\n const gl = this.context;\n\n const eyeParams = vr!.getEyeParams(gl, frame);\n\n if (!eyeParams) return;\n\n vr!.beforeRender(gl, frame);\n\n // Render both eyes\n for (const eyeIndex of [0, 1]) {\n const eyeParam = eyeParams[eyeIndex];\n\n this.mvMatrix = eyeParam.mvMatrix;\n this.pMatrix = eyeParam.pMatrix;\n\n gl.viewport(...eyeParam.viewport as [number, number, number, number]);\n gl.uniform1f((this.shaderProgram as any).uEye, eyeIndex);\n\n this._bindBuffers();\n this._draw();\n }\n\n vr!.afterRender();\n };\n\n private _bindBuffers() {\n const gl = this.context;\n const program = this.shaderProgram;\n\n const vertexBuffer = this.vertexBuffer;\n const textureCoordBuffer = this.textureCoordBuffer;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray((program as any).vertexPositionAttribute);\n gl.vertexAttribPointer(\n (program as any).vertexPositionAttribute, (vertexBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);\n gl.enableVertexAttribArray((program as any).textureCoordAttribute);\n gl.vertexAttribPointer(\n (program as any).textureCoordAttribute, (textureCoordBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n }\n\n private _draw() {\n if (this._isVideo && this._keepUpdate) {\n this._updateTexture();\n }\n\n this._renderer.render({\n gl: this.context,\n shaderProgram: this.shaderProgram!,\n indexBuffer: this.indexBuffer!,\n mvMatrix: this.mvMatrix,\n pMatrix: this.pMatrix\n });\n }\n\n private _requestPresent(options) {\n const gl = this.context;\n const canvas = this.canvas;\n const animator = this._animator;\n\n this._vr = WEBXR_SUPPORTED ?\n new XRManager(options) :\n new VRManager();\n\n const vr = this._vr;\n\n animator.stop();\n return new Promise((resolve, reject) => {\n vr.requestPresent(canvas, gl)\n .then(() => {\n vr.addEndCallback(this.exitVR);\n animator.setContext(vr.context);\n animator.setCallback(this._onFirstVRFrame);\n\n if (IS_IOS) {\n this._setWrapperFullscreen();\n }\n\n this._shouldForceDraw = true;\n animator.start();\n\n resolve(\"success\");\n })\n .catch(e => {\n vr.destroy();\n this._vr = null;\n animator.start();\n\n reject(e);\n });\n });\n }\n\n private _onFirstVRFrame = (time, frame) => {\n const vr = this._vr!;\n const gl = this.context;\n const animator = this._animator;\n\n // If rendering is not ready, wait for next frame\n if (!vr.canRender(frame)) return;\n\n const minusZDir = vec3.fromValues(0, 0, -1);\n const eyeParam = vr.getEyeParams(gl, frame)![0];\n // Extract only rotation\n const mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix);\n const pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix);\n\n const mvInv = mat3.invert(mat3.create(), mvMatrix);\n const pInv = mat3.invert(mat3.create(), pMatrix);\n const viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv);\n\n vec3.transformMat3(viewDir, viewDir, mvInv);\n\n const yawOffset = mathUtil.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1));\n\n if (yawOffset === 0) {\n // If the yawOffset is exactly 0, then device sensor is not ready\n // So read it again until it has any value in it\n return;\n }\n\n vr.setYawOffset(yawOffset);\n animator.setCallback(this._renderStereo);\n };\n\n private _setWrapperFullscreen() {\n const wrapper = this._wrapper;\n\n if (!wrapper) return;\n\n this._wrapperOrigStyle = wrapper.getAttribute(\"style\");\n const wrapperStyle = wrapper.style;\n\n wrapperStyle.width = \"100vw\";\n wrapperStyle.height = \"100vh\";\n wrapperStyle.position = \"fixed\";\n wrapperStyle.left = \"0\";\n wrapperStyle.top = \"0\";\n wrapperStyle.zIndex = \"9999\";\n }\n\n private _restoreStyle() {\n const wrapper = this._wrapper;\n const canvas = this.canvas;\n\n if (!wrapper) return;\n\n if (this._wrapperOrigStyle) {\n wrapper.setAttribute(\"style\", this._wrapperOrigStyle);\n } else {\n wrapper.removeAttribute(\"style\");\n }\n\n this._wrapperOrigStyle = null;\n\n // Restore canvas style\n canvas.removeAttribute(\"style\");\n this._setDefaultCanvasStyle();\n }\n}\n\nexport default PanoImageRenderer;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Promise from \"promise-polyfill\";\nimport { quat } from \"gl-matrix\";\n\nimport { DeviceMotionEvent, checkXRSupport } from \"../utils/browserFeature\";\nimport YawPitchControl, { YawPitchControlOptions } from \"../YawPitchControl/YawPitchControl\";\nimport PanoImageRenderer from \"../PanoImageRenderer/PanoImageRenderer\";\nimport WebGLUtils from \"../PanoImageRenderer/WebGLUtils\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { CubemapConfig, ValueOf } from \"../types/internal\";\nimport { AnimationEndEvent, ReadyEvent, ViewChangeEvent, ErrorEvent } from \"../types/event\";\n\nimport { ERROR_TYPE, PANOVIEWER_EVENTS as EVENTS, GYRO_MODE, PROJECTION_TYPE, STEREO_FORMAT, DEFAULT_CANVAS_CLASS } from \"./consts\";\n\nexport interface PanoViewerOptions {\n image: string | HTMLElement;\n video: string | HTMLElement;\n projectionType: ValueOf;\n cubemapConfig: Partial;\n stereoFormat: ValueOf;\n width: number;\n height: number;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n touchDirection: ValueOf;\n canvasClass: string;\n}\n\nexport interface PanoViewerEvent {\n ready: ReadyEvent;\n viewChange: ViewChangeEvent;\n animationEnd: AnimationEndEvent;\n error: ErrorEvent;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * PanoViewer\n */\nclass PanoViewer extends Component {\n /**\n * Check whether the current environment can execute PanoViewer\n * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다.\n * @return PanoViewer executable PanoViewer 실행가능 여부\n */\n public static isSupported(): boolean {\n return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL();\n }\n\n /**\n * Check whether the current environment supports the WebGL\n * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다.\n * @return WebGL support WebGL 지원여부\n */\n public static isWebGLAvailable(): boolean {\n return WebGLUtils.isWebGLAvailable();\n }\n\n /**\n * Check whether the current environment supports the gyro sensor.\n * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다.\n * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수\n */\n public static isGyroSensorAvailable(callback: (isAvailable: boolean) => any) {\n if (!DeviceMotionEvent && callback) {\n callback(false);\n return;\n }\n\n let onDeviceMotionChange;\n\n const checkGyro = () => new Promise(res => {\n onDeviceMotionChange = deviceMotion => {\n const isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null);\n\n res(isGyroSensorAvailable);\n };\n\n window.addEventListener(\"devicemotion\", onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n Promise.race([checkGyro(), timeout()]).then((isGyroSensorAvailable: boolean) => {\n window.removeEventListener(\"devicemotion\", onDeviceMotionChange);\n\n if (callback) {\n callback(isGyroSensorAvailable);\n }\n\n PanoViewer.isGyroSensorAvailable = fb => {\n if (fb) {\n fb(isGyroSensorAvailable);\n }\n return isGyroSensorAvailable;\n };\n });\n }\n\n private static _isValidTouchDirection(direction) {\n return direction === PanoViewer.TOUCH_DIRECTION.NONE ||\n direction === PanoViewer.TOUCH_DIRECTION.YAW ||\n direction === PanoViewer.TOUCH_DIRECTION.PITCH ||\n direction === PanoViewer.TOUCH_DIRECTION.ALL;\n }\n\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @name VERSION\n * @static\n * @type {String}\n * @example\n * eg.view360.PanoViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.PanoViewer\n */\n public static VERSION = VERSION;\n public static ERROR_TYPE = ERROR_TYPE;\n public static EVENTS = EVENTS;\n public static PROJECTION_TYPE = PROJECTION_TYPE;\n public static GYRO_MODE = GYRO_MODE;\n // This should be deprecated!\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static ProjectionType = PROJECTION_TYPE;\n public static STEREO_FORMAT = STEREO_FORMAT;\n\n /**\n * Constant value for touch directions\n * @ko 터치 방향에 대한 상수 값.\n * @namespace\n * @name TOUCH_DIRECTION\n */\n public static TOUCH_DIRECTION = {\n /**\n * Constant value for none direction.\n * @ko none 방향에 대한 상수 값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 1\n */\n NONE: YawPitchControl.TOUCH_DIRECTION_NONE,\n /**\n * Constant value for horizontal(yaw) direction.\n * @ko horizontal(yaw) 방향에 대한 상수 값.\n * @name YAW\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 6\n */\n YAW: YawPitchControl.TOUCH_DIRECTION_YAW,\n /**\n * Constant value for vertical direction.\n * @ko vertical(pitch) 방향에 대한 상수 값.\n * @name PITCH\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 24\n */\n PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH,\n /**\n * Constant value for all direction.\n * @ko all 방향에 대한 상수 값.\n * @name ALL\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 30\n */\n ALL: YawPitchControl.TOUCH_DIRECTION_ALL\n };\n\n private _container: HTMLElement;\n // Options\n private _image: ConstructorParameters[0];\n private _isVideo: boolean;\n private _projectionType: ValueOf;\n private _cubemapConfig: Partial;\n private _stereoFormat: ValueOf;\n private _width: number;\n private _height: number;\n private _yaw: number;\n private _pitch: number;\n private _fov: number;\n private _gyroMode: ValueOf;\n private _quaternion: quat | null;\n private _aspectRatio: number;\n private _isReady: boolean;\n private _canvasClass: string;\n\n // Internal Values\n private _photoSphereRenderer: PanoImageRenderer | null;\n private _yawPitchControl: YawPitchControl | null;\n\n /**\n * @classdesc 360 media viewer\n * @ko 360 미디어 뷰어\n *\n * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트\n * @param options\n *\n * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
\n * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다.\n * @param {Object} [options.cubemapConfig.order = \"RLUDBF\"(ProjectionType === CUBEMAP) | \"RLUDFB\" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서\n * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다.\n * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다.\n * @param {String} [options.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
\n * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위)\n * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위)\n * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위)\n * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위)\n * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위)\n * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다\n * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다.\n * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키\n * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE}
\n * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위\n * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위\n * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위\n * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
\n * @param {String} [options.canvasClass=\"view360-canvas\"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n *\n * @example\n * ```\n * // PanoViewer Creation\n * // create PanoViewer with option\n * var PanoViewer = eg.view360.PanoViewer;\n * // Area where the image will be displayed(HTMLElement)\n * var container = document.getElementById(\"myPanoViewer\");\n *\n * var panoViewer = new PanoViewer(container, {\n * // If projectionType is not specified, the default is \"equirectangular\".\n * // Specifies an image of the \"equirectangular\" type.\n * image: \"/path/to/image/image.jpg\"\n * });\n * ```\n *\n * @example\n * ```\n * // Cubemap Config Setting Example\n * // For support Youtube EAC projection, You should set cubemapConfig as follows.\n * cubemapConfig: {\n * order: \"LFRDBU\",\n * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}]\n * }\n * ```\n */\n public constructor(container: HTMLElement, options: Partial = {}) {\n super();\n\n // Raises the error event if webgl is not supported.\n if (!WebGLUtils.isWebGLAvailable()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n }, 0);\n return this;\n }\n\n if (!WebGLUtils.isStableWebGL()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_DEVICE,\n message: \"blacklisted browser\"\n }));\n }, 0);\n\n return this;\n }\n\n if (!!options.image && !!options.video) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_RESOURCE,\n message: \"Specifying multi resouces(both image and video) is not valid.\"\n }));\n }, 0);\n return this;\n }\n\n // Check XR support at not when imported, but when created.\n // This is intended to make polyfills easier to use.\n checkXRSupport();\n\n this._container = container;\n this._image = options.image! as HTMLImageElement || options.video! as HTMLVideoElement;\n this._isVideo = !!options.video;\n this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/\n order: this._projectionType === PROJECTION_TYPE.CUBEMAP ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...options.cubemapConfig\n };\n this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n\n // If the width and height are not provided, will use the size of the container.\n this._width = options.width || parseInt(window.getComputedStyle(container).width, 10);\n this._height = options.height || parseInt(window.getComputedStyle(container).height, 10);\n\n /**\n * Cache the direction for the performance in renderLoop\n *\n * This value should be updated by \"change\" event of YawPitchControl.\n */\n this._yaw = options.yaw || 0;\n this._pitch = options.pitch || 0;\n this._fov = options.fov || 65;\n\n this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH;\n this._quaternion = null;\n\n this._aspectRatio = this._height !== 0 ? this._width / this._height : 1;\n\n this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS;\n\n const fovRange = options.fovRange || [30, 110];\n const touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ?\n options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL;\n const yawPitchConfig = {\n ...options,\n ...{\n element: container,\n yaw: this._yaw,\n pitch: this._pitch,\n fov: this._fov,\n gyroMode: this._gyroMode,\n fovRange,\n aspectRatio: this._aspectRatio,\n touchDirection\n }\n };\n\n this._isReady = false;\n\n this._initYawPitchControl(yawPitchConfig);\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n /**\n * Get the video element that the viewer is currently playing. You can use this for playback.\n * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다.\n * @return HTMLVideoElementHTMLVideoElement\n * @example\n * ```\n * var videoTag = panoViewer.getVideo();\n * videoTag.play(); // play the video!\n * ```\n */\n public getVideo() {\n if (!this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent() as HTMLVideoElement;\n }\n\n /**\n * Set the video information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정)\n * @param {object} param\n * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}(\"equirectangular\")] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setVideo(\"/path/to/video/video.mp4\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR\n * });\n * ```\n */\n public setVideo(video: string | HTMLElement | { type: string; src: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n }> = {}) {\n if (video) {\n this.setImage(video, {\n projectionType: param.projectionType,\n isVideo: true,\n cubemapConfig: param.cubemapConfig,\n stereoFormat: param.stereoFormat\n });\n }\n\n return this;\n }\n\n /**\n * Get the image information that the viewer is currently using.\n * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다.\n * @return Image Object이미지 객체\n * @example\n * var imageObj = panoViewer.getImage();\n */\n public getImage() {\n if (this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent();\n }\n\n /**\n * Set the image information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.)\n * @param {object} param Additional information이미지 추가 정보\n * @param {string} [param.projectionType=\"equirectangular\"] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setImage(\"/path/to/image/image.png\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP\n * });\n * ```\n */\n public setImage(image: string | HTMLElement | { src: string; type: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n isVideo: boolean;\n }> = {}) {\n const cubemapConfig = {\n ...{\n order: \"RLUDBF\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...param.cubemapConfig\n };\n const stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n const isVideo = !!(param.isVideo);\n\n if (this._image && this._isVideo !== isVideo) {\n /* eslint-disable no-console */\n console.warn(\"PanoViewer is not currently supporting content type changes. (Image <--> Video)\");\n /* eslint-enable no-console */\n return this;\n }\n\n if (image) {\n this._deactivate();\n\n this._image = image as HTMLImageElement;\n this._isVideo = isVideo;\n this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = cubemapConfig;\n this._stereoFormat = stereoFormat;\n\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n return this;\n }\n\n /**\n * Set whether the renderer always updates the texture and renders.\n * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다.\n * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public keepUpdate(doUpdate: boolean) {\n this._photoSphereRenderer!.keepUpdate(doUpdate);\n return this;\n }\n\n /**\n * Get the current projection type (equirectangular/cube)\n * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다.\n * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE}\n */\n public getProjectionType() {\n return this._projectionType;\n }\n\n /**\n * Activate the device's motion sensor, and return the Promise whether the sensor is enabled\n * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element.\n * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다.\n * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다.\n */\n public enableSensor() {\n return new Promise((resolve, reject) => {\n if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\") {\n DeviceMotionEvent.requestPermission().then(permissionState => {\n if (permissionState === \"granted\") {\n resolve();\n } else {\n reject(new Error(\"permission denied\"));\n }\n }).catch(e => {\n // This can happen when this method wasn't triggered by user interaction\n reject(e);\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Disable the device's motion sensor.\n * @ko 디바이스의 모션 센서를 비활성화합니다.\n * @deprecated\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public disableSensor() {\n return this;\n }\n\n /**\n * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred).\n * This method must be used in the context of user interaction, like onclick callback on the button element.\n * It can be rejected when an enabling device sensor fails or image/video is still loading(\"ready\" event not triggered).\n * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다)\n * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우(\"ready\"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다.\n * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요.\n * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error)\n */\n public enterVR(options: {\n requiredFeatures?: any[];\n optionalFeatures?: any[];\n [key: string]: any;\n } = {}): globalThis.Promise {\n if (!this._isReady) {\n return Promise.reject(new Error(\"PanoViewer is not ready to show image.\")) as any;\n }\n\n return new Promise((resolve, reject) => {\n this.enableSensor()\n .then(() => this._photoSphereRenderer!.enterVR(options))\n .then((res: string) => resolve(res))\n .catch(e => reject(e));\n }) as any;\n }\n\n /**\n * Exit VR stereo rendering mode.\n * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public exitVR() {\n this._photoSphereRenderer!.exitVR();\n return this;\n }\n\n /**\n * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}.\n * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다.\n * @param useZoom\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseZoom(useZoom: boolean): this {\n if (typeof useZoom === \"boolean\") {\n this._yawPitchControl!.option(\"useZoom\", useZoom);\n }\n\n return this;\n }\n\n /**\n * When true, enables the keyboard move key control: awsd, arrow keys\n * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키)\n * @param useKeyboard\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseKeyboard(useKeyboard: boolean): this {\n this._yawPitchControl!.option(\"useKeyboard\", useKeyboard);\n return this;\n }\n\n /**\n * Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")\n * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")\n * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE}\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setGyroMode(\"yawPitch\");\n * //equivalent\n * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH);\n * ```\n */\n public setGyroMode(gyroMode: PanoViewer[\"_gyroMode\"]) {\n this._yawPitchControl!.option(\"gyroMode\", gyroMode);\n return this;\n }\n\n /**\n * Set the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 설정합니다.\n * @param range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setFovRange([50, 90]);\n */\n public setFovRange(range: number[]) {\n this._yawPitchControl!.option(\"fovRange\", range);\n return this;\n }\n\n /**\n * Get the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 반환합니다.\n * @return FOV range\n * @example\n * var range = panoViewer.getFovRange(); // [50, 90]\n */\n public getFovRange(): [number, number] {\n return this._yawPitchControl!.option(\"fovRange\") as [number, number];\n }\n\n /**\n * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size.\n * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다.\n * @param {object} [size]\n * @param {number} [size.width=width of the container]\n * @param {number} [size.height=height of the container]\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public updateViewportDimensions(size: Partial<{\n width: number;\n height: number;\n }> = {}): this {\n if (!this._isReady) {\n return this;\n }\n\n let containerSize;\n\n if (size.width === undefined || size.height === undefined) {\n containerSize = window.getComputedStyle(this._container);\n }\n\n const width = size.width || parseInt(containerSize.width, 10);\n const height = size.height || parseInt(containerSize.height, 10);\n\n // Skip if viewport is not changed.\n if (width === this._width && height === this._height) {\n return this;\n }\n\n this._width = width;\n this._height = height;\n\n this._aspectRatio = width / height;\n this._photoSphereRenderer!.updateViewportDimensions(width, height);\n this._yawPitchControl!.option(\"aspectRatio\", this._aspectRatio);\n this._yawPitchControl!.updatePanScale({height});\n\n this.lookAt({}, 0);\n return this;\n }\n\n /**\n * Get the current field of view(FOV)\n * @ko 현재 field of view(FOV) 값을 반환합니다.\n */\n public getFov(): number {\n return this._fov;\n }\n\n /**\n * Get current yaw value\n * @ko 현재 yaw 값을 반환합니다.\n */\n public getYaw() {\n return this._yaw;\n }\n\n /**\n * Get current pitch value\n * @ko 현재 pitch 값을 반환합니다.\n */\n public getPitch() {\n return this._pitch;\n }\n\n /**\n * Get the range of controllable Yaw values\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n */\n public getYawRange(): [number, number] {\n return this._yawPitchControl!.option(\"yawRange\") as [number, number];\n }\n\n /**\n * Get the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다.\n */\n public getPitchRange(): [number, number] {\n return this._yawPitchControl!.option(\"pitchRange\") as [number, number];\n }\n\n /**\n * Set the range of controllable yaw\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setYawRange([-90, 90]);\n */\n public setYawRange(yawRange: number[]) {\n this._yawPitchControl!.option(\"yawRange\", yawRange);\n return this;\n }\n\n /**\n * Set the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 설정합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setPitchRange([-40, 40]);\n */\n public setPitchRange(pitchRange: number[]) {\n this._yawPitchControl!.option(\"pitchRange\", pitchRange);\n return this;\n }\n\n /**\n * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed.\n * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다.\n * @param showPolePoint\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setShowPolePoint(showPolePoint: boolean) {\n this._yawPitchControl!.option(\"showPolePoint\", showPolePoint);\n return this;\n }\n\n /**\n * Set a new view by setting camera configuration. Any parameters not specified remain the same.\n * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다.\n * @param {object} orientation\n * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위)\n * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위)\n * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위)\n * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초)\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * // Change the yaw angle (absolute angle) to 30 degrees for one second.\n * panoViewer.lookAt({yaw: 30}, 1000);\n * ```\n */\n public lookAt(orientation: Partial<{\n yaw: number;\n pitch: number;\n fov: number;\n }>, duration: number = 0) {\n if (!this._isReady) {\n return this;\n }\n\n const yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw;\n const pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch;\n const pitchRange = this._yawPitchControl!.option(\"pitchRange\");\n const verticalAngleOfImage = pitchRange[1] - pitchRange[0];\n let fov = orientation.fov !== undefined ? orientation.fov : this._fov;\n\n if (verticalAngleOfImage < fov) {\n fov = verticalAngleOfImage;\n }\n\n this._yawPitchControl!.lookAt({yaw, pitch, fov}, duration);\n\n if (duration === 0) {\n this._photoSphereRenderer!.renderWithYawPitch(yaw, pitch, fov);\n }\n return this;\n }\n\n /**\n * Set touch direction by which user can control.\n * @ko 사용자가 조작가능한 터치 방향을 지정합니다.\n * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @return PanoViewer instance\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Limit the touch direction to the yaw direction only.\n * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW);\n * ```\n */\n public setTouchDirection(direction: number): this {\n if (PanoViewer._isValidTouchDirection(direction)) {\n this._yawPitchControl!.option(\"touchDirection\", direction);\n }\n\n return this;\n }\n\n /**\n * Returns touch direction by which user can control\n * @ko 사용자가 조작가능한 터치 방향을 반환한다.\n * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Returns the current touch direction.\n * var dir = panoViewer.getTouchDirection();\n * ```\n */\n public getTouchDirection(): number {\n return this._yawPitchControl!.option(\"touchDirection\") ;\n }\n\n /**\n * Destroy viewer. Remove all registered event listeners and remove viewer canvas.\n * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public destroy(): this {\n this._deactivate();\n\n if (this._yawPitchControl) {\n this._yawPitchControl.destroy();\n this._yawPitchControl = null;\n }\n\n return this;\n }\n\n // TODO: Remove parameters as they're just using private values\n private _initRenderer(\n yaw: number,\n pitch: number,\n fov: number,\n projectionType: PanoViewer[\"_projectionType\"],\n cubemapConfig: PanoViewer[\"_cubemapConfig\"]\n ) {\n this._photoSphereRenderer = new PanoImageRenderer(\n this._image,\n this._width,\n this._height,\n this._isVideo,\n this._container,\n this._canvasClass,\n {\n initialYaw: yaw,\n initialPitch: pitch,\n fieldOfView: fov,\n imageType: projectionType,\n cubemapConfig,\n stereoFormat: this._stereoFormat\n },\n );\n this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl!);\n\n this._bindRendererHandler();\n\n this._photoSphereRenderer\n .bindTexture()\n .then(() => this._activate())\n .catch(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_BIND_TEXTURE,\n message: \"failed to bind texture\"\n }));\n });\n }\n\n /**\n * @private\n * update values of YawPitchControl if needed.\n * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image.\n *\n * This function should be called after isReady status is true.\n */\n private _updateYawPitchIfNeeded() {\n if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) {\n // update fov by aspect ratio\n const image = this._photoSphereRenderer!.getContent()! as HTMLImageElement;\n let imageAspectRatio = image.naturalWidth / image.naturalHeight;\n let yawSize;\n let maxFov;\n\n // If height is larger than width, then we assume it's rotated by 90 degree.\n if (imageAspectRatio < 1) {\n // So inverse the aspect ratio.\n imageAspectRatio = 1 / imageAspectRatio;\n }\n\n if (imageAspectRatio < 6) {\n yawSize = mathUtil.toDegree(imageAspectRatio);\n // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5\n maxFov = mathUtil.toDegree(Math.atan(0.5)) * 2;\n } else {\n yawSize = 360;\n maxFov = (360 / imageAspectRatio); // Make it 5 fixed as axes does.\n }\n\n // console.log(\"_updateYawPitchIfNeeded\", maxFov, \"aspectRatio\", image.naturalWidth, image.naturalHeight, \"yawSize\", yawSize);\n const minFov = (this._yawPitchControl!.option(\"fovRange\"))[0];\n\n // this option should be called after fov is set.\n this._yawPitchControl!.option({\n \"fov\": maxFov, /* parameter for internal validation for pitchrange */\n \"yawRange\": [-yawSize / 2, yawSize / 2],\n \"pitchRange\": [-maxFov / 2, maxFov / 2],\n \"fovRange\": [minFov, maxFov]\n });\n this.lookAt({fov: maxFov});\n }\n }\n\n private\t_bindRendererHandler() {\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, e));\n });\n\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, () => {\n this._deactivate();\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERING_CONTEXT_LOST,\n message: \"webgl rendering context lost\"\n }));\n });\n }\n\n private _initYawPitchControl(yawPitchConfig: Partial) {\n this._yawPitchControl = new YawPitchControl(yawPitchConfig);\n\n this._yawPitchControl.on(EVENTS.ANIMATION_END, e => {\n this.trigger(new ComponentEvent(EVENTS.ANIMATION_END, e));\n });\n\n this._yawPitchControl.on(\"change\", e => {\n this._yaw = e.yaw;\n this._pitch = e.pitch;\n this._fov = e.fov;\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(EVENTS.VIEW_CHANGE, {\n yaw: e.yaw,\n pitch: e.pitch,\n fov: e.fov,\n quaternion: e.quaternion,\n isTrusted: e.isTrusted\n }));\n });\n }\n\n private _activate() {\n this._photoSphereRenderer!.attachTo(this._container);\n this._yawPitchControl!.enable();\n\n this.updateViewportDimensions();\n\n this._isReady = true;\n\n // update yawPitchControl after isReady status is true.\n this._updateYawPitchIfNeeded();\n\n this.trigger(new ComponentEvent(EVENTS.READY));\n this._photoSphereRenderer!.startRender();\n }\n\n /**\n * Destroy webgl context and block user interaction and stop rendering\n */\n private _deactivate() {\n // Turn off the video if it has one\n const video = this.getVideo();\n if (video) {\n video.pause();\n }\n\n if (this._isReady) {\n this._photoSphereRenderer!.stopRender();\n this._yawPitchControl!.disable();\n this._isReady = false;\n }\n\n if (this._photoSphereRenderer) {\n this._photoSphereRenderer.destroy();\n this._photoSphereRenderer = null;\n }\n }\n}\n\nexport default PanoViewer;\n\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { VERSION } from \"../version\";\nimport { merge } from \"../utils/utils\";\n\nimport PanoViewer from \"./PanoViewer\";\nimport * as Constants from \"./consts\";\n\nconst PanoViewerModule = {\n PanoViewer,\n VERSION\n};\n\nmerge(PanoViewerModule, Constants);\n\nexport default PanoViewerModule;\n"],"names":["VERSION","merge","target","_i","srcs","forEach","source","Object","keys","key","value","Array","isArray","toImageElement","image","images","parsedImages","map","img","imgEl","Image","crossOrigin","src","length","toVideoElement","videoCandidate","HTMLVideoElement","video_1","document","createElement","setAttribute","v","appendSourceElement","sourceCount","querySelectorAll","readyState","load","video","videoUrl","videoSrc","videoType","type","sourceElement","appendChild","win","window","Math","self","Function","doc","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","IS_IOS","IS_SAFARI_ON_DESKTOP","Float32Array","getComputedStyle","userAgent","SUPPORT_TOUCH","SUPPORT_DEVICEMOTION","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","i","len","SUPPORT_WILLCHANGE","CSS","supports","WEBXR_SUPPORTED","checkXRSupport","xr","isSessionSupported","then","res","catch","supportsSession","quatToVec3","quaternion","baseV","vec3","fromValues","transformQuat","toDegree","a","PI","util","isPowerOfTwo","n","extractPitchFromQuat","atan2","sqrt","pow","hypot","x","y","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","getRotationDelta","prevQ","curQ","rotateKind","prevQuaternion","quat","clone","curQuaternion","normalize","prevPoint","curPoint","rotateDistance","dot","cross","create","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","distance","abs","projectedPrevPoint","subtract","scale","trigonometricRatio","theta","acos","crossVec","thetaDirection","deltaRadian","angleBetweenVec2","v1","v2","det","vec2","yawOffsetBetween","viewDir","targetDir","viewDirXZ","targetDirXZ","sign","Number","toAxis","offset","reduce","acc","version","branch","build","match","exec","parseInt","CHROME_VERSION","IS_CHROME_WITHOUT_DEVICE_MOTION","IS_ANDROID","test","CONTROL_MODE_VR","CONTROL_MODE_YAWPITCH","TOUCH_DIRECTION_NONE","TOUCH_DIRECTION_YAW","TOUCH_DIRECTION_PITCH","TOUCH_DIRECTION_ALL","MC_DECELERATION","MC_MAXIMUM_DURATION","MC_BIND_SCALE","MAX_FIELD_OF_VIEW","PAN_SCALE","YAW_RANGE_HALF","PITCH_RANGE_HALF","CIRCULAR_PITCH_RANGE_HALF","GYRO_MODE","NONE","YAWPITCH","VR","MathUtil","degToRad","radToDeg","Vector2","prototype","constructor","set","copy","subVectors","b","Vector3","z","scalar","invScalar","multiplyScalar","applyQuaternion","q","qx","qy","qz","qw","w","ix","iy","iz","iw","crossVectors","ax","ay","az","bx","by","bz","Quaternion","undefined","setFromEulerXYZ","c1","cos","c2","c3","s1","sin","s2","s3","setFromEulerYXZ","setFromAxisAngle","axis","angle","halfAngle","s","multiply","multiplyQuaternions","qax","qay","qaz","qaw","qbx","qby","qbz","qbw","inverse","l","slerp","qb","t","cosHalfTheta","halfTheta","sinHalfTheta","ratioA","ratioB","setFromUnitVectors","r","EPS","vFrom","vTo","Util","MIN_TIMESTEP","MAX_TIMESTEP","base64","mimeType","clamp","min","max","lerp","isIOS","platform","isWebViewAndroid","indexOf","isSafari","isFirefoxAndroid","isR7","isLandscapeMode","rtn","orientation","isTimestampDeltaValid","timestampDeltaS","isNaN","getScreenWidth","screen","width","height","getScreenHeight","requestFullscreen","element","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","exitFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","getFullscreenElement","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","linkProgram","gl","vertexSource","fragmentSource","attribLocationMap","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","program","createProgram","attachShader","attribName","bindAttribLocation","deleteShader","getProgramUniforms","uniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","uniformName","uniformInfo","getActiveUniform","replace","getUniformLocation","orthoMatrix","out","left","right","bottom","top","near","far","lr","bt","nf","copyArray","dest","isMobile","check","substr","vendor","opera","extend","hasOwnProperty","safariCssSizeWorkaround","canvas","width_1","height_1","setTimeout","isDebug","getQueryParameter","regex","RegExp","results","location","search","decodeURIComponent","frameDataFromPose","piOver180","rad45","mat4_perspectiveFromFieldOfView","fov","upTan","tan","upDegrees","downTan","downDegrees","leftTan","leftDegrees","rightTan","rightDegrees","xScale","yScale","mat4_fromRotationTranslation","x2","y2","z2","xx","xy","xz","yy","yz","zz","wx","wy","wz","mat4_translate","a00","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","mat4_invert","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b06","b07","b08","b09","b10","b11","defaultOrientation","defaultPosition","updateEyeMatrices","projection","view","pose","parameters","vrDisplay","fieldOfView","depthNear","depthFar","position","frameData","timestamp","leftProjectionMatrix","leftViewMatrix","getEyeParameters","rightProjectionMatrix","rightViewMatrix","isInsideCrossDomainIFrame","isFramed","refDomain","getDomainFromUrl","referrer","thisDomain","href","url","domain","split","predictionTimeS","previousQ","previousTimestampS","deltaQ","outQ","currentQ","gyro","timestampS","angularSpeed","console","log","toFixed","deltaT","predictAngle","STILLNESS_THRESHOLD","__extends","_super","_this","_onDeviceMotion","bind","_onDeviceOrientation","_onChromeWithoutDeviceMotion","isWithoutDeviceMotion","isAndroid","stillGyroVec","rawGyroVec","adjustedGyroVec","_timer","lastDevicemotionTimestamp","_isEnabled","enable","addEventListener","removeEventListener","e","alpha","beta","gamma","trigger","ComponentEvent","inputEvent","deviceorientation","clearTimeout","Date","getTime","isGyroSensorAvailable","rotationRate","isGravitySensorAvailable","accelerationIncludingGravity","interval","devicemotionEvent","__assign","timeStamp","acceleration","adjustedRotationRate","Component","sample","sensorSample","kFilter","vector","currentGyroMeasurement","previousGyroMeasurement","run_","currentAccelMeasurement","SensorSample","filterQ","previousFilterQ","accelQ","isOrientationInitialized","estimatedGravity","measuredGravity","gyroIntegralQ","accelToQuaternion_","gyroDeltaQ","gyroToQuaternionDelta_","invFilterQ","getQuaternionAngle","targetQ","accel","normAccel","dt","ComplementaryFilter","isFilterQuaternionInitialized","getOrientation","K_FILTER","PREDICTION_TIME_S","deviceMotion","DeviceMotion","accelerometer","gyroscope","_onDeviceMotionChange","_onScreenOrientationChange","filter","posePredictor","PosePredictor","filterToWorldQ","isChromeUsingDegrees","inverseWorldToScreenQ","worldToScreenQ","originalPoseAdjustQ","_setScreenTransform","resetQ","on","isEnabled","disable","_deviceOrientationQ","deviceOrientationFixQ","_alpha","outQuat","_convertFusionToPredicted","_prevOrientation","equals","predictedQ","getPrediction","_a","accGravity","rotRate","_triggerChange","addAccelMeasurement","addGyroMeasurement","getDeltaYaw","prvQ","yawDeltaByYaw","yawDeltaByRoll","getDeltaPitch","pitchDelta","el","options","_prevQuaternion","_quaternion","fusionPoseSensor","threshold","_onPoseChange","axes","observer","FusionPoseSensor","_attachEvent","_dettachEvent","destroy","disconnect","event","change","off","screenRotationAngleInst","refCount","_onOrientationChange","_spinR","_screenOrientationAngle","glMatrix","toRadian","betaR","gammaR","_useRotation","_screenRotationAngle","setUseRotation","useRotation","_userDirection","Axes","DIRECTION_ALL","unref","ScreenRotationAngle","_direction","DIRECTION_HORIZONTAL","connect","properties","useDirection","_getOffset","newOffset","getRadian","cosTheta","sinTheta","DIRECTION_VERTICAL","PanInput","Y_AXIS_VECTOR","_fusionPoseSensor","isTrusted","yaw","yawQ","setAxisAngle","conj","conjugate","DEFAULT_YAW_RANGE","DEFAULT_PITCH_RANGE","CIRCULAR_PITCH_RANGE","opt","pitch","showPolePoint","useZoom","useKeyboard","gyroMode","touchDirection","yawRange","pitchRange","fovRange","aspectRatio","_element","_initialFov","_enabled","_isAnimating","_deviceQuaternion","_initAxes","option","param","_axes","get","areaHeight","_axesPanInput","deceleration","newValue","_getOptions","newOptions","changedKeyList","push","_setOptions","_getValidatedOptions","_applyOptions","updatePanScale","persistOrientation","_resetOrientation","duration","pos","p","f","maximumDuration","Infinity","setBy","yawPitch","getCombinedQuaternion","_axesWheelInput","_axesTiltMotionInput","_axesPinchInput","_axesMoveKeyInput","yRange","_updateYawRange","pRange","_updatePitchRange","RotationPanInput","WheelInput","PinchInput","MoveKeyInput","range","circular","_isCircular","bounce","hold","evt","delta","_updateControlScale","release","animationEnd","_getValidYawRange","_getValidPitchRange","arguments","isVR","isYawPitch","some","setTo","prevFov","nextFov","_initDeviceQuaternion","TiltMotionInput","_togglePinchInputByOption","_enableTouch","_inputs","direction","yawEnabled","pitchEnabled","DeviceQuaternion","newYawRange","newFov","newAspectRatio","ratio","_adjustAspectRatio","horizontalFov","isValid","newPitchRange","changeEvt","verticalAngle","halfFov","isPanorama","concat","horizontalAngle","halfHorizontalFov","mathUtil","targetElement","input","inputRange","outputRange","rangeIdx","inputA","inputB","outputA","outputB","_lerp","fraction","YawPitchControl","ERROR_TYPE","INVALID_DEVICE","NO_WEBGL","FAIL_IMAGE_LOAD","FAIL_BIND_TEXTURE","INVALID_RESOURCE","RENDERING_CONTEXT_LOST","PANOVIEWER_EVENTS","READY","VIEW_CHANGE","ANIMATION_END","ERROR","PROJECTION_TYPE","EQUIRECTANGULAR","CUBEMAP","CUBESTRIP","PANORAMA","STEREOSCOPIC_EQUI","STEREO_FORMAT","TOP_BOTTOM","LEFT_RIGHT","PANOVIEWER_OPTIONS","projectionType","cubemapConfig","stereoFormat","canvasClass","DEFAULT_CANVAS_CLASS","WEBGL_ERROR_CODE","webglAvailability","WebGLUtils","shader","success","getShaderParameter","COMPILE_STATUS","error","getShaderInfoLog","LINK_STATUS","deleteProgram","data","itemSize","attr","buffer","createBuffer","bindBuffer","bufferData","STATIC_DRAW","numItems","enableVertexAttribArray","vertexAttribPointer","FLOAT","userContextAttributes","webglIdentifiers","context","contextAttributes","preserveDrawingBuffer","antialias","onWebglcontextcreationerror","statusMessage","webglIdentifiers_1","__values","identifier","getContext","textureTarget","texture","createTexture","bindTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","webglContext","getWebglContext","loseContextExtension","getExtension","loseContext","agentInfo","isStableWebgl","parseFloat","code","pixels","texImage2D","RGBA","UNSIGNED_BYTE","getParameter","MAX_TEXTURE_SIZE","isIE11","majorVersion","EVENTS","_forceDimension","_pixelCanvas","_pixelContext","shaderProgram","indexBuffer","mvMatrix","pMatrix","uniformMatrix4fv","pMatrixUniform","mvMatrixUniform","drawElements","TRIANGLES","UNSIGNED_SHORT","pixelSource","naturalWidth","videoWidth","naturalHeight","videoHeight","forceDimension","isIE11Video","getDimension","contentDimension","textureDimension","drawImage","imageConfig","tileConfig","config","flipHorizontal","rotation","message","Renderer","CubeRenderer","order","_VERTEX_POSITION_DATA","_INDEX_DATA","indexData","vertexPositionData","getVertexPositionData","vertexOrder","extractOrder","base","_extractTileConfig","elemSize","vertexPerTile","trim","texCoords","face","floor","ordermap","shift","unshift","pop","elemPerTile","tileVertex","slice","tileTemp","j","splice","coord","_shrinkCoord","faceCoords","val","coords","baseOrder","orderMap","surfaceIdx","tileIdx","TEXTURE_CUBE_MAP_POSITIVE_X","maxCubeMapTextureSize","getMaxCubeMapTextureSize","tile","extractTileFromImage","_triggerError","TEXTURE_CUBE_MAP","updateTexture","inputTextureSize","outputTextureSize","getSourceTileSize","tilePerRow","MAX_CUBE_MAP_TEXTURE_SIZE","imageWidth","coordData","SHRINK_MULTIPLIER","axisMultipliers","axisIndex","axisDir","notSameDir","_vertices","indices","cols","rows","textureSize","c","tileConfigs","_transformCoord","index","TEXTURE_2D","_getPixelSource","size","maxSize","getMaxTextureSize","_initPixelSource","activeTexture","TEXTURE0","pixelStorei","UNPACK_FLIP_Y_WEBGL","newCoord","_flipHorizontalCoord","_rotateCoord","SHRINK_Y","SHRINK_X","rotationAngle","SIZE","shiftCount","moved","rotatedCoord","latitudeBands","longitudeBands","radius","ANGLE_CORRECTION_FOR_CENTER_ALIGN","textureCoordData","latIdx","lngIdx","phi","sinPhi","cosPhi","u","format","_stereoFormat","ctx","leftEyeScaleOffset","rightEyeScaleOffset","uTexScaleOffset","uniform4fv","render","SphereRenderer","_TEXTURE_COORD_DATA","MIN_ASPECT_RATIO_FOR_FULL_PANORAMA","CylinderRenderer","resizeDimension","_b","imageAspectRatio","cylinderMaxRadian","halfCylinderY","rotated","CYLIDER_Y","startAngleForCenterAlign","yIdx","yLength","VR_DISPLAY_PRESENT_CHANGE","DEFAULT_LEFT_BOUNDS","DEFAULT_RIGHT_BOUNDS","EYES","LEFT","RIGHT","_vrDisplay","removeEndCallback","isPresenting","exitPresent","_clear","_frameData","VRFrameData","Boolean","bindFramebuffer","FRAMEBUFFER","submitFrame","display","halfWidth","drawingBufferWidth","drawingBufferHeight","getFrameData","leftMVMatrix","rightMVMatrix","mat4","rotateY","_yawOffset","viewport","callback","getVRDisplays","displays","Promise","reject","Error","capabilities","canPresent","requestPresent","leftEye","rightEye","renderWidth","renderHeight","_setDisplay","layers","getLayers","layer","_leftBounds","leftBounds","_rightBounds","rightBounds","addEndCallback","XR_REFERENCE_SPACE","xrSession","_xrSession","end","_options","frame","getViewerPose","_xrRefSpace","session","baseLayer","renderState","framebuffer","glLayer","views","getViewport","transform","matrix","rotateX","projectionMatrix","_presenting","requiredFeatures","attributes","getContextAttributes","xrCompatible","makeXRCompatible","requestSession","xrLayer","XRWebGLLayer","updateRenderState","requestReferenceSpace","refSpace","_setSession","_xrLayer","args","_callback","_rafId","_context","requestAnimationFrame","_onLoop","before","performance","now","diff","_rafTimer","_onLoopNextTick","cancelAnimationFrame","ImageType","DEVICE_PIXEL_RATIO","BIND_TEXTURE","IMAGE_LOADED","RENDERING_CONTEXT_RESTORE","RENDERER_ERROR","isVideo","container","sphericalConfig","renderingContextAttributes","vr","_vr","animator","_animator","exitVR","_restoreStyle","updateViewportDimensions","_updateViewport","_bindBuffers","_shouldForceDraw","stop","setContext","setCallback","_render","start","time","eyeParams","getEyeParams","beforeRender","eyeIndex","eyeParam","uniform1f","uEye","_draw","afterRender","canRender","minusZDir","mat3","fromMat4","mvInv","invert","pInv","transformMat3","yawOffset","setYawOffset","_renderStereo","_lastQuaternion","_lastYaw","_lastPitch","_lastFieldOfView","perspective","textureCoordBuffer","vertexBuffer","_initCanvas","_setDefaultCanvasStyle","_wrapper","_wrapperOrigStyle","_renderingContextAttributes","_image","_imageConfig","_imageIsReady","_keepUpdate","_onContentLoad","_onContentError","WebGLAnimator","setImage","imageType","yawPitchControl","_yawPitchControl","_isVideo","_setImageType","_contentLoader","ImReady","rej","contentLoader","isReady","_bindTexture","once","errorCount","parentElement","_hasExternalCanvas","detach","hasRenderingContext","removeChild","forceContextLoss","_onWebglcontextlost","_onWebglcontextrestored","isContextLost","viewPortChanged","h","doUpdate","isImageLoaded","exactEquals","updateFieldOfView","fromQuat","identity","_renderer","resolve","_requestPresent","_imageType","_isCubeMap","CubeStripRenderer","_initWebGL","canvasInContainer","querySelector","_createCanvas","className","margin","maxHeight","maxWidth","outline","content","_triggerContentLoad","renderer","vsSource","getVertexShaderSource","fsSource","getFragmentShaderSource","getErrorNameFromWebGLErrorCode","getError","useProgram","vertexPositionAttribute","getAttribLocation","samplerUniform","textureCoordAttribute","clear","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","STENCIL_BUFFER_BIT","uniform1i","preventDefault","_initRenderingContext","_initShaderProgram","clearColor","deleteTexture","CULL_FACE","WebGLRenderingContext","getIndexData","getTextureCoordData","initBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","Uint16Array","isEAC","updateShaderData","_initBuffers","getFov","shouldRenderWithQuaternion","getQuaternion","renderWithQuaternion","getYawPitch","renderWithYawPitch","_updateTexture","XRManager","VRManager","_onFirstVRFrame","_setWrapperFullscreen","wrapper","getAttribute","wrapperStyle","zIndex","removeAttribute","PanoImageRenderer","isWebGLAvailable","isStableWebGL","_container","_projectionType","_cubemapConfig","_width","_height","_yaw","_pitch","_fov","_gyroMode","_aspectRatio","_canvasClass","PanoViewer","_isValidTouchDirection","yawPitchConfig","_isReady","_initYawPitchControl","_initRenderer","onDeviceMotionChange","checkGyro","timeout","race","fb","TOUCH_DIRECTION","YAW","PITCH","ALL","_photoSphereRenderer","getContent","warn","_deactivate","keepUpdate","requestPermission","permissionState","enableSensor","enterVR","containerSize","lookAt","verticalAngleOfImage","initialYaw","initialPitch","setYawPitchControl","_bindRendererHandler","_activate","ProjectionType","yawSize","maxFov","atan","minFov","attachTo","_updateYawPitchIfNeeded","startRender","getVideo","pause","stopRender","PanoViewerModule","Constants"],"mappings":"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"} \ No newline at end of file diff --git a/dist/PanoViewer/view360.panoviewer.min.js b/dist/PanoViewer/view360.panoviewer.min.js new file mode 100644 index 000000000..cfd767524 --- /dev/null +++ b/dist/PanoViewer/view360.panoviewer.min.js @@ -0,0 +1,10 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@egjs/component"),require("promise-polyfill"),require("@egjs/agent"),require("@egjs/axes"),require("gl-matrix"),require("@egjs/imready")):"function"==typeof define&&define.amd?define(["@egjs/component","promise-polyfill","@egjs/agent","@egjs/axes","gl-matrix","@egjs/imready"],e):((t="undefined"!=typeof globalThis?globalThis:t||self).eg=t.eg||{},t.eg.view360=e(t.eg.Component,t.Promise,t.eg.agent,t.eg.Axes,t.glMatrix,t.eg.ImReady))}(this,function(s,u,a,o,_,r){"use strict";var n="3.6.3",h=function(t,e){return(h=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)};function c(t,e){function i(){this.constructor=t}h(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)}var l=function(){return(l=Object.assign||function(t){for(var e,i=1,n=arguments.length;ia[0]&&e[1]=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function p(){for(var t=[],e=0;eMath.abs(t.z)?L.set(-t.y,t.x,0):L.set(0,-t.z,t.y)):L.crossVectors(t,e),this.x=L.x,this.y=L.y,this.z=L.z,this.w=N,this.normalize(),this}};var k,X,Y,q,j,H,K,Z,J,$=null!==(e=null==x?void 0:x.userAgent)&&void 0!==e?e:"",tt=v.Util||{};function et(t,e,i,n,r){c=t,a=n?n.fieldOfView:null,o=r.depthNear,u=r.depthFar,l=Math.tan(a?a.upDegrees*H:K),h=Math.tan(a?a.downDegrees*H:K),f=Math.tan(a?a.leftDegrees*H:K),d=Math.tan(a?a.rightDegrees*H:K),s=2/(f+d),a=2/(l+h),c[0]=s,c[1]=0,c[2]=0,c[3]=0,c[4]=0,c[5]=a,c[6]=0,c[7]=0,c[8]=-(f-d)*s*.5,c[9]=(l-h)*a*.5,c[10]=u/(o-u),c[11]=-1,c[12]=0,c[13]=0,c[14]=u*o/(o-u),c[15]=0;var o,a,s,h,u,c,l,d,f,_,p,g,m,v,y,x,w,E,T,R,C,b,I,A,P,O,t=i.orientation||Z,r=i.position||J;f=e,d=r,l=(s=t)[0],h=s[1],a=s[2],o=s[3],c=l*(u=l+l),r=l*(i=h+h),s=l*(t=a+a),l=h*i,h*=t,a*=t,u*=o,i*=o,t*=o,f[0]=1-(l+a),f[1]=r+t,f[2]=s-i,f[3]=0,f[4]=r-t,f[5]=1-(c+a),f[6]=h+u,f[7]=0,f[8]=s+i,f[9]=h-u,f[10]=1-(c+l),f[11]=0,f[12]=d[0],f[13]=d[1],f[14]=d[2],f[15]=1,n&&(C=P=e,R=n.offset,A=R[0],I=R[1],b=R[2],C===P?(P[12]=C[0]*A+C[4]*I+C[8]*b+C[12],P[13]=C[1]*A+C[5]*I+C[9]*b+C[13],P[14]=C[2]*A+C[6]*I+C[10]*b+C[14],P[15]=C[3]*A+C[7]*I+C[11]*b+C[15]):(_=C[0],m=C[1],x=C[2],E=C[3],p=C[4],v=C[5],O=C[6],T=C[7],g=C[8],y=C[9],w=C[10],R=C[11],P[0]=_,P[1]=m,P[2]=x,P[3]=E,P[4]=p,P[5]=v,P[6]=O,P[7]=T,P[8]=g,P[9]=y,P[10]=w,P[11]=R,P[12]=_*A+p*I+g*b+C[12],P[13]=m*A+v*I+y*b+C[13],P[14]=x*A+O*I+w*b+C[14],P[15]=E*A+T*I+R*b+C[15])),a=(t=r=e)[0],s=t[1],i=t[2],h=t[3],u=t[4],c=t[5],l=t[6],d=t[7],f=t[8],n=t[9],_=t[10],p=t[11],g=t[12],m=t[13],v=t[14],y=t[15],(t=(x=a*c-s*u)*(O=_*y-p*v)-(w=a*l-i*u)*(P=n*y-p*m)+(E=a*d-h*u)*(A=n*v-_*m)+(T=s*l-i*c)*(I=f*y-p*g)-(R=s*d-h*c)*(b=f*v-_*g)+(C=i*d-h*l)*(e=f*m-n*g))&&(t=1/t,r[0]=(c*O-l*P+d*A)*t,r[1]=(i*P-s*O-h*A)*t,r[2]=(m*C-v*R+y*T)*t,r[3]=(_*R-n*C-p*T)*t,r[4]=(l*I-u*O-d*b)*t,r[5]=(a*O-i*I+h*b)*t,r[6]=(v*E-g*C-y*w)*t,r[7]=(f*C-_*E+p*w)*t,r[8]=(u*P-c*I+d*e)*t,r[9]=(s*I-a*P-h*e)*t,r[10]=(g*R-m*E+y*x)*t,r[11]=(n*E-f*R-p*x)*t,r[12]=(c*b-u*A-l*e)*t,r[13]=(a*A-s*b+i*e)*t,r[14]=(m*w-g*T-v*x)*t,r[15]=(f*T-n*w+_*x)*t)}tt.MIN_TIMESTEP=.001,tt.MAX_TIMESTEP=1,tt.base64=function(t,e){return"data:"+t+";base64,"+e},tt.clamp=function(t,e,i){return Math.min(Math.max(e,t),i)},tt.lerp=function(t,e,i){return t+(e-t)*i},tt.isIOS=(k=/iPad|iPhone|iPod/.test(null==x?void 0:x.platform),function(){return k}),tt.isWebViewAndroid=(X=-1!==$.indexOf("Version")&&-1!==$.indexOf("Android")&&-1!==$.indexOf("Chrome"),function(){return X}),tt.isSafari=(Y=/^((?!chrome|android).)*safari/i.test($),function(){return Y}),tt.isFirefoxAndroid=(q=-1!==$.indexOf("Firefox")&&-1!==$.indexOf("Android"),function(){return q}),tt.isR7=(j=-1!==$.indexOf("R7 Build"),function(){return j}),tt.isLandscapeMode=function(){var t=90===v.orientation||-90===v.orientation;return tt.isR7()?!t:t},tt.isTimestampDeltaValid=function(t){return!isNaN(t)&&(!(t<=tt.MIN_TIMESTEP)&&!(t>tt.MAX_TIMESTEP))},tt.getScreenWidth=function(){return Math.max(v.screen.width,v.screen.height)*v.devicePixelRatio},tt.getScreenHeight=function(){return Math.min(v.screen.width,v.screen.height)*v.devicePixelRatio},tt.requestFullscreen=function(t){if(tt.isWebViewAndroid())return!1;if(t.requestFullscreen)t.requestFullscreen();else if(t.webkitRequestFullscreen)t.webkitRequestFullscreen();else if(t.mozRequestFullScreen)t.mozRequestFullScreen();else{if(!t.msRequestFullscreen)return!1;t.msRequestFullscreen()}return!0},tt.exitFullscreen=function(){if(y.exitFullscreen)y.exitFullscreen();else if(y.webkitExitFullscreen)y.webkitExitFullscreen();else if(y.mozCancelFullScreen)y.mozCancelFullScreen();else{if(!y.msExitFullscreen)return!1;y.msExitFullscreen()}return!0},tt.getFullscreenElement=function(){return y.fullscreenElement||y.webkitFullscreenElement||y.mozFullScreenElement||y.msFullscreenElement},tt.linkProgram=function(t,e,i,n){var r=t.createShader(t.VERTEX_SHADER);t.shaderSource(r,e),t.compileShader(r);e=t.createShader(t.FRAGMENT_SHADER);t.shaderSource(e,i),t.compileShader(e);var o,a=t.createProgram();for(o in t.attachShader(a,r),t.attachShader(a,e),n)t.bindAttribLocation(a,n[o],o);return t.linkProgram(a),t.deleteShader(r),t.deleteShader(e),a},tt.getProgramUniforms=function(t,e){for(var i={},n=t.getProgramParameter(e,t.ACTIVE_UNIFORMS),r="",o=0;oe[1]&&(n=e[1]),i!==n&&(o.setTo({fov:n},0),this._updateControlScale(),this.updatePanScale())),t.some(function(t){return"gyroMode"===t})&&I&&(this._axesTiltMotionInput&&(this._axes.disconnect(this._axesTiltMotionInput),this._axesTiltMotionInput.destroy(),this._axesTiltMotionInput=null),this._deviceQuaternion&&(this._deviceQuaternion.destroy(),this._deviceQuaternion=null),a?this._initDeviceQuaternion():s&&(this._axesTiltMotionInput=new st(this._element),this._axes.connect(["yaw","pitch"],this._axesTiltMotionInput)),this._axesPanInput.setUseRotation(a)),t.some(function(t){return"useKeyboard"===t})&&(r.useKeyboard?o.connect(["yaw","pitch"],this._axesMoveKeyInput):o.disconnect(this._axesMoveKeyInput)),t.some(function(t){return"useZoom"===t})&&(a=r.useZoom,o.disconnect(this._axesWheelInput),a&&o.connect(["fov"],this._axesWheelInput)),this._togglePinchInputByOption(r.touchDirection,r.useZoom),t.some(function(t){return"touchDirection"===t})&&this._enabled&&this._enableTouch(h)},e._togglePinchInputByOption=function(t,e){this._axesPinchInput&&(this._axes.disconnect(this._axesPinchInput),e&&6===t&&-1===this._axes._inputs.indexOf(this._axesPinchInput)&&this._axes.connect(["fov"],this._axesPinchInput))},e._enableTouch=function(t){this._axesPanInput&&this._axes.disconnect(this._axesPanInput);var e=2&t?"yaw":null,t=4&t?"pitch":null;this._axes.connect([e,t],this._axesPanInput)},e._initDeviceQuaternion=function(){var e=this;this._deviceQuaternion=new ft,this._deviceQuaternion.on("change",function(t){e._triggerChange(t)})},e._getValidYawRange=function(t,e,i){i=this._adjustAspectRatio(i||this.options.aspectRatio||1),i=(e||this._axes.get().fov)*i;return t[1]-t[0]>=i?t:this.options.yawRange||_t},e._getValidPitchRange=function(t,e){e=e||this._axes.get().fov;return t[1]-t[0]>=e?t:this.options.pitchRange||pt},e._isCircular=function(t){return t[1]-t[0]<360?[!1,!1]:[!0,!0]},e._updateControlScale=function(t){var e=this.options,i=this._axes.get().fov,n=this._updatePitchRange(e.pitchRange,i,e.showPolePoint),r=this._updateYawRange(e.yawRange,i,e.aspectRatio),i=this._axes.get(),e=i.yaw,i=i.pitch;return _.vec2.copy(this._axes.axis.yaw.range,r),_.vec2.copy(this._axes.axis.pitch.range,n),this._axes.axis.yaw.circular=this._isCircular(r),this._axes.axis.pitch.circular=this._isCircular(n),er[1]&&(e=r[1]),in[1]&&(i=n[1]),t&&t.set({yaw:e,pitch:i}),this._axes.setTo({yaw:e,pitch:i},0),this},e._updatePitchRange=function(t,e,i){if(this.options.gyroMode===B.VR)return gt;var n=t[1]-t[0],e=e/2;return!i||n<180?[t[0]+e,t[1]-e]:t.concat()},e._updateYawRange=function(t,e,i){if(this.options.gyroMode===B.VR)return _t;if(360<=t[1]-t[0])return t.concat();e=D.toDegree(Math.atan2(i,1/Math.tan(_.glMatrix.toRadian(e/2))));return[t[0]+e,t[1]-e]},e._triggerChange=function(t){var e=this._axes.get(),i=this.options,t={targetElement:i.element,isTrusted:t.isTrusted,yaw:e.yaw,pitch:e.pitch,fov:e.fov,quaternion:null};i.gyroMode===B.VR&&this._deviceQuaternion&&(t.quaternion=this._deviceQuaternion.getCombinedQuaternion(e.yaw)),this.trigger(new s.ComponentEvent("change",t))},e._adjustAspectRatio=function(t){for(var e=[.52,.54,.563,.57,.584,.59,.609,.67,.702,.72,.76,.78,.82,.92,.97,1,1.07,1.14,1.19,1.25,1.32,1.38,1.4,1.43,1.53,1.62,1.76,1.77,1.86,1.96,2.26,2.3,2.6,3,5,6],i=[.51,.54,.606,.56,.628,.63,.647,.71,.736,.757,.78,.77,.8,.89,.975,1,1.07,1.1,1.15,1.18,1.22,1.27,1.3,1.33,1.39,1.45,1.54,1.55,1.58,1.62,1.72,1.82,1.92,2,2.24,2.3],n=-1,r=0;r= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"},i.getVertexPositionData=function(){return this._vertices||(this._vertices=[1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1]),this._vertices},i.getIndexData=function(){var i=this;return function(){for(var t=[],e=0;e(target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","/**\n * Original Code\n * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js\n * Math Util\n * modified by egjs\n */\n/**\n * @fileoverview gl-matrix - High performance matrix and vector operations\n * @author Brandon Jones\n * @author Colin MacKenzie IV\n * @version 2.3.2\n */\n\n/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE. */\n\n// Some minimal math functionality borrowed from gl-Matrix and stripped down\n// for the purposes of this library.\n\nimport { vec2, vec3, quat } from \"gl-matrix\";\n\nimport { ValueOf } from \"../types/internal\";\n\nconst quatToVec3 = (quaternion: quat) => {\n const baseV = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(baseV, baseV, quaternion);\n return baseV;\n};\n\nconst toDegree = (a: number) => a * 180 / Math.PI;\n\nconst util: any = {};\n\nutil.isPowerOfTwo = (n: number) => n && (n & (n - 1)) === 0;\n\nutil.extractPitchFromQuat = (quaternion: quat) => {\n const baseV = quatToVec3(quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n};\n\nutil.hypot = Math.hypot || ((x: number, y: number) => Math.sqrt(x * x + y * y));\n\n// implement reference\n// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식\n// calculating angle between two vectors : http://darkpgmr.tistory.com/121\nconst ROTATE_CONSTANT: {\n PITCH_DELTA: 1;\n YAW_DELTA_BY_ROLL: 2;\n YAW_DELTA_BY_YAW: 3;\n} = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n};\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nconst getRotationDelta = (prevQ: quat, curQ: quat, rotateKind: ValueOf) => {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n // const coefficientD = -1 * vec3.dot(vecN, meshPoint1);\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance =\n coefficientA * crossVec[0] +\n coefficientB * crossVec[1] +\n coefficientC * crossVec[2];\n\n let thetaDirection;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return toDegree(deltaRadian);\n};\n\nconst angleBetweenVec2 = (v1: vec2, v2: vec2) => {\n const det = v1[0] * v2[1] - v2[0] * v1[1];\n const theta = -Math.atan2(det, vec2.dot(v1, v2));\n return theta;\n};\n\nutil.yawOffsetBetween = (viewDir: number, targetDir: number) => {\n const viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]);\n const targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]);\n\n vec2.normalize(viewDirXZ, viewDirXZ);\n vec2.normalize(targetDirXZ, targetDirXZ);\n\n const theta = -angleBetweenVec2(viewDirXZ, targetDirXZ);\n\n return theta;\n};\n\nutil.sign = (x: number) => Math.sign\n ? Math.sign(x)\n : (Number(x > 0) - Number(x < 0)) || +x;\n\nutil.toDegree = toDegree;\nutil.getRotationDelta = getRotationDelta;\nutil.angleBetweenVec2 = angleBetweenVec2;\n\nexport {\n util,\n ROTATE_CONSTANT\n};\n","import { quat } from \"gl-matrix\";\n\nimport {\n util as mathUtil,\n ROTATE_CONSTANT\n} from \"../utils/math-util\";\n\nexport const toAxis = (source, offset) => offset.reduce((acc, v, i) => {\n if (source[i]) {\n acc[source[i]] = v;\n }\n return acc;\n}, {});\n\nexport const getDeltaYaw = (prvQ: quat, curQ: quat) => {\n const yawDeltaByYaw = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(mathUtil.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nexport const getDeltaPitch = (prvQ: quat, curQ: quat) => {\n const pitchDelta = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n","import { userAgent } from \"../utils/browserFeature\";\n/**\n * Returns a number value indiciating the version of Chrome being used,\n * or otherwise `null` if not on Chrome.\n *\n * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19\n */\n/**\n * In Chrome m65, `devicemotion` events are broken but subsequently fixed\n * in 65.0.3325.148. Since many browsers use Chromium, ensure that\n * we scope this detection by branch and build numbers to provide\n * a proper fallback.\n * https://github.com/immersive-web/webvr-polyfill/issues/307\n */\nlet version = -1; // It should not be null because it will be compared with number\nlet branch: string | null = null;\nlet build: string | null = null;\n\nconst match = /Chrome\\/([0-9]+)\\.(?:[0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(userAgent);\n\nif (match) {\n version = parseInt(match[1], 10);\n branch = match[2];\n build = match[3];\n}\n\nconst CHROME_VERSION = version;\nconst IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === \"3325\" && parseInt(build!, 10) < 148;\nconst IS_ANDROID = /Android/i.test(userAgent);\n\nconst CONTROL_MODE_VR = 1;\nconst CONTROL_MODE_YAWPITCH = 2;\n\nconst TOUCH_DIRECTION_NONE = 1;\nconst TOUCH_DIRECTION_YAW = 2;\nconst TOUCH_DIRECTION_PITCH = 4;\nconst TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH;\n\n/* Const for MovableCoord */\nconst MC_DECELERATION = 0.0014;\nconst MC_MAXIMUM_DURATION = 1000;\nconst MC_BIND_SCALE = [0.20, 0.20];\n\nconst MIN_FIELD_OF_VIEW = 20;\nconst MAX_FIELD_OF_VIEW = 110;\nconst PAN_SCALE = 320;\n\n// const DELTA_THRESHOLD = 0.015;\n// const DELTA_THRESHOLD = 0.09; // Note4\n// const DELTA_THRESHOLD = 0.0825;\n// const DELTA_THRESHOLD = 0.075;\n// const DELTA_THRESHOLD = 0.06;\n// const DELTA_THRESHOLD = 0.045;\nconst DELTA_THRESHOLD = 0.0375; // Note2\n\nconst YAW_RANGE_HALF = 180;\nconst PITCH_RANGE_HALF = 90;\nconst CIRCULAR_PITCH_RANGE_HALF = 180;\nconst PINCH_EVENTS = \"pinchstart pinchmove pinchend\";\n\nconst KEYMAP = {\n LEFT_ARROW: 37,\n A: 65,\n UP_ARROW: 38,\n W: 87,\n RIGHT_ARROW: 39,\n D: 68,\n DOWN_ARROW: 40,\n S: 83\n};\n\nconst GYRO_MODE: {\n NONE: \"none\";\n YAWPITCH: \"yawPitch\";\n VR: \"VR\";\n} = {\n NONE: \"none\",\n YAWPITCH: \"yawPitch\",\n VR: \"VR\"\n};\n\nexport {\n GYRO_MODE,\n\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n\n TOUCH_DIRECTION_NONE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MIN_FIELD_OF_VIEW,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n DELTA_THRESHOLD,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n PINCH_EVENTS,\n KEYMAP,\n\n CHROME_VERSION,\n IS_CHROME_WITHOUT_DEVICE_MOTION,\n IS_ANDROID\n};\n","/* eslint-disable */\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { window as win } from \"../../../../utils/browser\";\n\nconst MathUtil = win.MathUtil || {};\n\nMathUtil.degToRad = Math.PI / 180;\nMathUtil.radToDeg = 180 / Math.PI;\n\n// Some minimal math functionality borrowed from THREE.Math and stripped down\n// for the purposes of this library.\n\n\nMathUtil.Vector2 = function( x, y ) {\n this.x = x || 0;\n this.y = y || 0;\n};\n\nMathUtil.Vector2.prototype = {\n constructor: MathUtil.Vector2,\n\n set: function( x, y ) {\n this.x = x;\n this.y = y;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n },\n\n subVectors: function( a, b ) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n\n return this;\n }\n};\n\nMathUtil.Vector3 = function( x, y, z ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n};\n\nMathUtil.Vector3.prototype = {\n constructor: MathUtil.Vector3,\n\n set: function( x, y, z ) {\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n\n return this;\n },\n\n length: function() {\n return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n },\n\n normalize: function() {\n const scalar = this.length();\n\n if ( scalar !== 0 ) {\n const invScalar = 1 / scalar;\n\n this.multiplyScalar(invScalar);\n } else {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n }\n\n return this;\n },\n\n multiplyScalar: function( scalar ) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n },\n\n applyQuaternion: function( q ) {\n const x = this.x;\n const y = this.y;\n const z = this.z;\n\n const qx = q.x;\n const qy = q.y;\n const qz = q.z;\n const qw = q.w;\n\n // calculate quat * vector\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = - qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n return this;\n },\n\n dot: function( v ) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n },\n\n crossVectors: function( a, b ) {\n const ax = a.x;\n const ay = a.y;\n const az = a.z;\n const bx = b.x;\n const by = b.y;\n const bz = b.z;\n\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n\n return this;\n }\n};\n\nMathUtil.Quaternion = function( x, y, z, w ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n this.w = ( w !== undefined ) ? w : 1;\n};\n\nMathUtil.Quaternion.prototype = {\n constructor: MathUtil.Quaternion,\n\n set: function( x, y, z, w ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n\n return this;\n },\n\n copy: function( quaternion ) {\n this.x = quaternion.x;\n this.y = quaternion.y;\n this.z = quaternion.z;\n this.w = quaternion.w;\n\n return this;\n },\n\n setFromEulerXYZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 + s1 * s2 * c3;\n this.w = c1 * c2 * c3 - s1 * s2 * s3;\n\n return this;\n },\n\n setFromEulerYXZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 - s1 * s2 * c3;\n this.w = c1 * c2 * c3 + s1 * s2 * s3;\n\n return this;\n },\n\n setFromAxisAngle: function( axis, angle ) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n // assumes axis is normalized\n\n const halfAngle = angle / 2;\n const s = Math.sin( halfAngle );\n\n this.x = axis.x * s;\n this.y = axis.y * s;\n this.z = axis.z * s;\n this.w = Math.cos( halfAngle );\n\n return this;\n },\n\n multiply: function( q ) {\n return this.multiplyQuaternions( this, q );\n },\n\n multiplyQuaternions: function( a, b ) {\n // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n const qax = a.x;\n const qay = a.y;\n const qaz = a.z;\n const qaw = a.w;\n const qbx = b.x;\n const qby = b.y;\n const qbz = b.z;\n const qbw = b.w;\n\n this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n return this;\n },\n\n inverse: function() {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n\n this.normalize();\n\n return this;\n },\n\n normalize: function() {\n let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n if ( l === 0 ) {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n this.w = 1;\n } else {\n l = 1 / l;\n\n this.x = this.x * l;\n this.y = this.y * l;\n this.z = this.z * l;\n this.w = this.w * l;\n }\n\n return this;\n },\n\n slerp: function( qb, t ) {\n if ( t === 0 ) return this;\n if ( t === 1 ) return this.copy( qb );\n\n const x = this.x;\n const y = this.y;\n const z = this.z;\n const w = this.w;\n\n // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n let cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;\n\n if ( cosHalfTheta < 0 ) {\n this.w = - qb.w;\n this.x = - qb.x;\n this.y = - qb.y;\n this.z = - qb.z;\n\n cosHalfTheta = - cosHalfTheta;\n } else {\n this.copy( qb );\n }\n\n if ( cosHalfTheta >= 1.0 ) {\n this.w = w;\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n }\n\n const halfTheta = Math.acos( cosHalfTheta );\n const sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n if ( Math.abs( sinHalfTheta ) < 0.001 ) {\n this.w = 0.5 * ( w + this.w );\n this.x = 0.5 * ( x + this.x );\n this.y = 0.5 * ( y + this.y );\n this.z = 0.5 * ( z + this.z );\n\n return this;\n }\n\n const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;\n const ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n this.w = ( w * ratioA + this.w * ratioB );\n this.x = ( x * ratioA + this.x * ratioB );\n this.y = ( y * ratioA + this.y * ratioB );\n this.z = ( z * ratioA + this.z * ratioB );\n\n return this;\n },\n\n setFromUnitVectors: function() {\n // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n // assumes direction vectors vFrom and vTo are normalized\n\n let v1;\n let r;\n const EPS = 0.000001;\n\n return function( vFrom, vTo ) {\n if ( v1 === undefined ) v1 = new MathUtil.Vector3();\n\n r = vFrom.dot( vTo ) + 1;\n\n if ( r < EPS ) {\n r = 0;\n\n if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n v1.set( - vFrom.y, vFrom.x, 0 );\n } else {\n v1.set( 0, - vFrom.z, vFrom.y );\n }\n } else {\n v1.crossVectors( vFrom, vTo );\n }\n\n this.x = v1.x;\n this.y = v1.y;\n this.z = v1.z;\n this.w = r;\n\n this.normalize();\n\n return this;\n };\n }()\n};\n\nexport default MathUtil;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tslint:disable: only-arrow-functions\n\nimport { window as win, document as doc, navigator as nav } from \"../../../../utils/browser\";\n\nconst userAgent = nav?.userAgent ?? \"\";\nconst Util = (win ).Util || {};\n\nUtil.MIN_TIMESTEP = 0.001;\nUtil.MAX_TIMESTEP = 1;\n\nUtil.base64 = function(mimeType, base64) {\n return \"data:\" + mimeType + \";base64,\" + base64;\n};\n\nUtil.clamp = function(value, min, max) {\n return Math.min(Math.max(min, value), max);\n};\n\nUtil.lerp = function(a, b, t) {\n return a + ((b - a) * t);\n};\n\nUtil.isIOS = (function() {\n const isIOS = /iPad|iPhone|iPod/.test(nav?.platform);\n return function() {\n return isIOS;\n };\n})();\n\nUtil.isWebViewAndroid = (function() {\n const isWebViewAndroid = userAgent.indexOf(\"Version\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1 &&\n userAgent.indexOf(\"Chrome\") !== -1;\n return function() {\n return isWebViewAndroid;\n };\n})();\n\nUtil.isSafari = (function() {\n const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n return function() {\n return isSafari;\n };\n})();\n\nUtil.isFirefoxAndroid = (function() {\n const isFirefoxAndroid = userAgent.indexOf(\"Firefox\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1;\n return function() {\n return isFirefoxAndroid;\n };\n})();\n\nUtil.isR7 = (function() {\n const isR7 = userAgent.indexOf(\"R7 Build\") !== -1;\n return function() {\n return isR7;\n };\n})();\n\nUtil.isLandscapeMode = function() {\n const rtn = (win.orientation === 90 || win.orientation === -90);\n return Util.isR7() ? !rtn : rtn;\n};\n\n// Helper method to validate the time steps of sensor timestamps.\nUtil.isTimestampDeltaValid = function(timestampDeltaS) {\n if (isNaN(timestampDeltaS)) {\n return false;\n }\n if (timestampDeltaS <= Util.MIN_TIMESTEP) {\n return false;\n }\n if (timestampDeltaS > Util.MAX_TIMESTEP) {\n return false;\n }\n return true;\n};\n\nUtil.getScreenWidth = function() {\n return Math.max(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.getScreenHeight = function() {\n return Math.min(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.requestFullscreen = function(element) {\n if (Util.isWebViewAndroid()) {\n return false;\n }\n if (element.requestFullscreen) {\n element.requestFullscreen();\n } else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n } else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n } else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.exitFullscreen = function() {\n if (doc.exitFullscreen) {\n doc.exitFullscreen();\n } else if (doc.webkitExitFullscreen) {\n doc.webkitExitFullscreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.getFullscreenElement = function() {\n return doc.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n};\n\nUtil.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {\n // No error checking for brevity.\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n const program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n\n for (const attribName in attribLocationMap)\n gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);\n\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n};\n\nUtil.getProgramUniforms = function(gl, program) {\n const uniforms = {};\n const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n let uniformName = \"\";\n for (let i = 0; i < uniformCount; i++) {\n const uniformInfo = gl.getActiveUniform(program, i);\n uniformName = uniformInfo.name.replace(\"[0]\", \"\");\n uniforms[uniformName] = gl.getUniformLocation(program, uniformName);\n }\n return uniforms;\n};\n\nUtil.orthoMatrix = function(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right);\n const bt = 1 / (bottom - top);\n const nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n};\n\nUtil.copyArray = function(source, dest) {\n for (let i = 0, n = source.length; i < n; i++) {\n dest[i] = source[i];\n }\n};\n\nUtil.isMobile = function() {\n let check = false;\n (function(a) {\n if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))check = true;\n })(userAgent || nav?.vendor || win.opera);\n return check;\n};\n\nUtil.extend = function(dest, src) {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n dest[key] = src[key];\n }\n }\n\n return dest;\n};\n\nUtil.safariCssSizeWorkaround = function(canvas) {\n // TODO(smus): Remove this workaround when Safari for iOS is fixed.\n // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).\n //\n // \"To the last I grapple with thee;\n // from hell's heart I stab at thee;\n // for hate's sake I spit my last breath at thee.\"\n // -- Moby Dick, by Herman Melville\n if (Util.isIOS()) {\n const width = canvas.style.width;\n const height = canvas.style.height;\n canvas.style.width = (parseInt(width) + 1) + \"px\";\n canvas.style.height = (parseInt(height)) + \"px\";\n setTimeout(function() {\n canvas.style.width = width;\n canvas.style.height = height;\n }, 100);\n }\n\n // Debug only.\n win.Util = Util;\n win.canvas = canvas;\n};\n\nUtil.isDebug = function() {\n return Util.getQueryParameter(\"debug\");\n};\n\nUtil.getQueryParameter = function(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n const results = regex.exec(location.search);\n return results === null ? \"\" : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n};\n\nUtil.frameDataFromPose = (function() {\n const piOver180 = Math.PI / 180.0;\n const rad45 = Math.PI * 0.25;\n\n // Borrowed from glMatrix.\n function mat4_perspectiveFromFieldOfView(out, fov, near, far) {\n const upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45);\n const downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45);\n const leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45);\n const rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45);\n const xScale = 2.0 / (leftTan + rightTan);\n const yScale = 2.0 / (upTan + downTan);\n\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = ((upTan - downTan) * yScale * 0.5);\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = (far * near) / (near - far);\n out[15] = 0.0;\n return out;\n }\n\n function mat4_fromRotationTranslation(out, q, v) {\n // Quaternion math\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n\n return out;\n }\n\n function mat4_translate(out, a, v) {\n const x = v[0];\n const y = v[1];\n const z = v[2];\n let a00;\n let a01;\n let a02;\n let a03;\n let a10;\n let a11;\n let a12;\n let a13;\n let a20;\n let a21;\n let a22;\n let a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];\n a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];\n a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];\n\n out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;\n out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;\n out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;\n\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n }\n\n function mat4_invert(out, a) {\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n }\n\n const defaultOrientation = new Float32Array([0, 0, 0, 1]);\n const defaultPosition = new Float32Array([0, 0, 0]);\n\n function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {\n mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);\n\n const orientation = pose.orientation || defaultOrientation;\n const position = pose.position || defaultPosition;\n\n mat4_fromRotationTranslation(view, orientation, position);\n if (parameters)\n mat4_translate(view, view, parameters.offset);\n mat4_invert(view, view);\n }\n\n return function(frameData, pose, vrDisplay) {\n if (!frameData || !pose)\n return false;\n\n frameData.pose = pose;\n frameData.timestamp = pose.timestamp;\n\n updateEyeMatrices(\n frameData.leftProjectionMatrix, frameData.leftViewMatrix,\n pose, vrDisplay.getEyeParameters(\"left\"), vrDisplay);\n updateEyeMatrices(\n frameData.rightProjectionMatrix, frameData.rightViewMatrix,\n pose, vrDisplay.getEyeParameters(\"right\"), vrDisplay);\n\n return true;\n };\n})();\n\nUtil.isInsideCrossDomainIFrame = function() {\n const isFramed = (win.self !== win.top);\n const refDomain = Util.getDomainFromUrl(doc.referrer);\n const thisDomain = Util.getDomainFromUrl(win.location.href);\n\n return isFramed && (refDomain !== thisDomain);\n};\n\n// From http://stackoverflow.com/a/23945027.\nUtil.getDomainFromUrl = function(url) {\n let domain;\n // Find & remove protocol (http, ftp, etc.) and get domain.\n if (url.indexOf(\"://\") > -1) {\n domain = url.split(\"/\")[2];\n } else {\n domain = url.split(\"/\")[0];\n }\n\n // find & remove port number\n domain = domain.split(\":\")[0];\n\n return domain;\n};\n\nexport default Util;\n","/* eslint-disable */\n\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * Given an orientation and the gyroscope data, predicts the future orientation\n * of the head. This makes rendering appear faster.\n *\n * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf\n * @param {Number} predictionTimeS time from head movement to the appearance of\n * the corresponding image.\n */\nclass PosePredictor {\n public predictionTimeS;\n public previousQ;\n public previousTimestampS;\n public deltaQ;\n public outQ;\n\n public constructor(predictionTimeS) {\n this.predictionTimeS = predictionTimeS;\n\n // The quaternion corresponding to the previous state.\n this.previousQ = new MathUtil.Quaternion();\n // Previous time a prediction occurred.\n this.previousTimestampS = null;\n\n // The delta quaternion that adjusts the current pose.\n this.deltaQ = new MathUtil.Quaternion();\n // The output quaternion.\n this.outQ = new MathUtil.Quaternion();\n }\n\n public getPrediction(currentQ, gyro, timestampS) {\n if (!this.previousTimestampS) {\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n return currentQ;\n }\n\n // Calculate axis and angle based on gyroscope rotation rate data.\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n\n const angularSpeed = gyro.length();\n\n // If we're rotating slowly, don't do prediction.\n if (angularSpeed < MathUtil.degToRad * 20) {\n if (Util.isDebug()) {\n console.log(\"Moving slowly, at %s deg/s: no prediction\",\n (MathUtil.radToDeg * angularSpeed).toFixed(1));\n }\n this.outQ.copy(currentQ);\n this.previousQ.copy(currentQ);\n return this.outQ;\n }\n\n // Get the predicted angle based on the time delta and latency.\n const deltaT = timestampS - this.previousTimestampS;\n const predictAngle = angularSpeed * this.predictionTimeS;\n\n this.deltaQ.setFromAxisAngle(axis, predictAngle);\n this.outQ.copy(this.previousQ);\n this.outQ.multiply(this.deltaQ);\n\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n\n return this.outQ;\n }\n}\n\nexport default PosePredictor;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3 } from \"gl-matrix\";\n\nimport { Mutable } from \"../../types/internal\";\nimport { window } from \"../../utils/browser\";\nimport { IS_CHROME_WITHOUT_DEVICE_MOTION, IS_ANDROID } from \"../consts\";\n\nconst STILLNESS_THRESHOLD = 200; // millisecond\n\nexport default class DeviceMotion extends Component<{\n devicemotion: {\n inputEvent: DeviceMotionEvent | {\n deviceorientation: {\n alpha: number;\n beta: number;\n gamma: number;\n };\n };\n };\n}> {\n public readonly isWithoutDeviceMotion: boolean;\n public readonly isAndroid: boolean;\n\n public stillGyroVec: vec3;\n public rawGyroVec: vec3;\n public adjustedGyroVec: vec3;\n public lastDevicemotionTimestamp: number;\n\n private _timer: number;\n private _isEnabled: boolean;\n\n public constructor() {\n super();\n this._onDeviceMotion = this._onDeviceMotion.bind(this);\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onChromeWithoutDeviceMotion = this._onChromeWithoutDeviceMotion.bind(this);\n\n this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION;\n this.isAndroid = IS_ANDROID;\n\n this.stillGyroVec = vec3.create();\n this.rawGyroVec = vec3.create();\n this.adjustedGyroVec = vec3.create();\n\n this._timer = -1;\n\n this.lastDevicemotionTimestamp = 0;\n this._isEnabled = false;\n this.enable();\n }\n\n public enable() {\n if (this.isAndroid) {\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n }\n if (this.isWithoutDeviceMotion) {\n window.addEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n } else {\n window.addEventListener(\"devicemotion\", this._onDeviceMotion);\n }\n this._isEnabled = true;\n }\n\n public disable() {\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n window.removeEventListener(\"devicemotion\", this._onDeviceMotion);\n this._isEnabled = false;\n }\n\n private _onChromeWithoutDeviceMotion(e: DeviceOrientationEvent) {\n let {alpha, beta, gamma} = e;\n\n // There is deviceorientation event trigged with empty values\n // on Headless Chrome.\n if (alpha === null) {\n return;\n }\n\n // convert to radian\n alpha = (alpha || 0) * Math.PI / 180;\n beta = (beta || 0) * Math.PI / 180;\n gamma = (gamma || 0) * Math.PI / 180;\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: {\n deviceorientation: {\n alpha,\n beta,\n gamma: -gamma\n }\n }\n }));\n }\n\n private _onDeviceOrientation() {\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timer = window.setTimeout(() => {\n if ((new Date().getTime() - this.lastDevicemotionTimestamp) < STILLNESS_THRESHOLD) {\n vec3.copy(this.stillGyroVec, this.rawGyroVec);\n }\n }, STILLNESS_THRESHOLD);\n }\n\n private _onDeviceMotion(e: DeviceMotionEvent) {\n // desktop chrome triggers devicemotion event with empthy sensor values.\n // Those events should ignored.\n const isGyroSensorAvailable = !(e.rotationRate!.alpha == null);\n const isGravitySensorAvailable = !(e.accelerationIncludingGravity!.x == null);\n\n if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) {\n return;\n }\n\n const devicemotionEvent = {...e} as Mutable;\n\n devicemotionEvent.interval = e.interval;\n devicemotionEvent.timeStamp = e.timeStamp;\n devicemotionEvent.type = e.type;\n devicemotionEvent.rotationRate = {\n alpha: e.rotationRate!.alpha,\n beta: e.rotationRate!.beta,\n gamma: e.rotationRate!.gamma\n };\n devicemotionEvent.accelerationIncludingGravity = {\n x: e.accelerationIncludingGravity!.x,\n y: e.accelerationIncludingGravity!.y,\n z: e.accelerationIncludingGravity!.z\n };\n devicemotionEvent.acceleration = {\n x: e.acceleration!.x,\n y: e.acceleration!.y,\n z: e.acceleration!.z\n };\n\n if (this.isAndroid) {\n vec3.set(\n this.rawGyroVec,\n e.rotationRate!.alpha || 0,\n e.rotationRate!.beta || 0,\n e.rotationRate!.gamma || 0);\n vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec);\n this.lastDevicemotionTimestamp = new Date().getTime();\n\n (devicemotionEvent as any).adjustedRotationRate = {\n alpha: this.adjustedGyroVec[0],\n beta: this.adjustedGyroVec[1],\n gamma: this.adjustedGyroVec[2]};\n }\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: devicemotionEvent\n }));\n }\n}\n","class SensorSample {\n public sample;\n public timestampS;\n\n public constructor(sample?, timestampS?) {\n this.set(sample, timestampS);\n }\n\n public set(sample, timestampS) {\n this.sample = sample;\n this.timestampS = timestampS;\n }\n\n public copy(sensorSample) {\n this.set(sensorSample.sample, sensorSample.timestampS);\n }\n}\n\nexport default SensorSample;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SensorSample from \"./sensor-sample\";\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * An implementation of a simple complementary filter, which fuses gyroscope and\n * accelerometer data from the 'devicemotion' event.\n *\n * Accelerometer data is very noisy, but stable over the long term.\n * Gyroscope data is smooth, but tends to drift over the long term.\n *\n * This fusion is relatively simple:\n * 1. Get orientation estimates from accelerometer by applying a low-pass filter\n * on that data.\n * 2. Get orientation estimates from gyroscope by integrating over time.\n * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the\n * short term.\n */\nclass ComplementaryFilter {\n public kFilter;\n public currentAccelMeasurement;\n public currentGyroMeasurement;\n public previousGyroMeasurement;\n public filterQ;\n public previousFilterQ;\n public accelQ;\n public isOrientationInitialized;\n public estimatedGravity;\n public measuredGravity;\n public gyroIntegralQ;\n\n constructor(kFilter) {\n this.kFilter = kFilter;\n\n // Raw sensor measurements.\n this.currentAccelMeasurement = new SensorSample();\n this.currentGyroMeasurement = new SensorSample();\n this.previousGyroMeasurement = new SensorSample();\n\n // Set default look direction to be in the correct direction.\n if (Util.isIOS()) {\n this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);\n } else {\n this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);\n }\n this.previousFilterQ = new MathUtil.Quaternion();\n this.previousFilterQ.copy(this.filterQ);\n\n // Orientation based on the accelerometer.\n this.accelQ = new MathUtil.Quaternion();\n // Whether or not the orientation has been initialized.\n this.isOrientationInitialized = false;\n // Running estimate of gravity based on the current orientation.\n this.estimatedGravity = new MathUtil.Vector3();\n // Measured gravity based on accelerometer.\n this.measuredGravity = new MathUtil.Vector3();\n\n // Debug only quaternion of gyro-based orientation.\n this.gyroIntegralQ = new MathUtil.Quaternion();\n }\n\n public addAccelMeasurement(vector, timestampS) {\n this.currentAccelMeasurement.set(vector, timestampS);\n }\n\n public addGyroMeasurement = function(vector, timestampS) {\n this.currentGyroMeasurement.set(vector, timestampS);\n\n const deltaT = timestampS - this.previousGyroMeasurement.timestampS;\n if (Util.isTimestampDeltaValid(deltaT)) {\n this.run_();\n }\n\n this.previousGyroMeasurement.copy(this.currentGyroMeasurement);\n };\n\n public getOrientation() {\n return this.filterQ;\n }\n\n public run_() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n if (Util.isDebug()) {\n console.log(\"Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)\",\n MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),\n (this.estimatedGravity.x).toFixed(1),\n (this.estimatedGravity.y).toFixed(1),\n (this.estimatedGravity.z).toFixed(1),\n (this.measuredGravity.x).toFixed(1),\n (this.measuredGravity.y).toFixed(1),\n (this.measuredGravity.z).toFixed(1));\n }\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n }\n\n private accelToQuaternion_(accel) {\n const normAccel = new MathUtil.Vector3();\n normAccel.copy(accel);\n normAccel.normalize();\n const quat = new MathUtil.Quaternion();\n quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);\n quat.inverse();\n return quat;\n }\n\n private gyroToQuaternionDelta_(gyro, dt) {\n // Extract axis and angle from the gyroscope data.\n const quat = new MathUtil.Quaternion();\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n quat.setFromAxisAngle(axis, gyro.length() * dt);\n return quat;\n }\n}\n\nexport default ComplementaryFilter;\n","import MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport ComplementaryFilter from \"./lib/webvr-polyfill/complementary-filter\";\n\nComplementaryFilter.prototype.run_ = function() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n\n if (!this.isFilterQuaternionInitialized) {\n this.isFilterQuaternionInitialized = true;\n }\n};\n\nComplementaryFilter.prototype.getOrientation = function() {\n if (this.isFilterQuaternionInitialized) {\n return this.filterQ;\n } else {\n return null;\n }\n};\n\nexport default ComplementaryFilter;\n","import WebGLUtils from \"../WebGLUtils\";\nimport { STEREO_FORMAT } from \"../../PanoViewer/consts\";\nimport { ValueOf } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nconst latitudeBands = 60;\nconst longitudeBands = 60;\nconst radius = 2;\nconst ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\nlet latIdx: number;\nlet lngIdx: number;\n\nfor (latIdx = 0; latIdx <= latitudeBands; latIdx++) {\n const theta = (latIdx / latitudeBands - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / longitudeBands;\n const v = latIdx / latitudeBands;\n\n textureCoordData.push(u, v);\n vertexPositionData.push(radius * x, radius * y, radius * z);\n\n if (lngIdx !== longitudeBands && latIdx !== latitudeBands) {\n const a = latIdx * (longitudeBands + 1) + lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n}\n\nclass SphereRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n private _stereoFormat: ValueOf;\n\n public constructor(format: SphereRenderer[\"_stereoFormat\"]) {\n super();\n\n this._stereoFormat = format;\n }\n\n public render(ctx: Parameters[0]) {\n const {gl, shaderProgram} = ctx;\n\n let leftEyeScaleOffset: number[];\n let rightEyeScaleOffset: number[];\n\n switch (this._stereoFormat) {\n case STEREO_FORMAT.TOP_BOTTOM:\n leftEyeScaleOffset = [1, 0.5, 0, 0];\n rightEyeScaleOffset = [1, 0.5, 0, 0.5];\n break;\n case STEREO_FORMAT.LEFT_RIGHT:\n leftEyeScaleOffset = [0.5, 1, 0, 0];\n rightEyeScaleOffset = [0.5, 1, 0.5, 0];\n break;\n default:\n leftEyeScaleOffset = [1, 1, 0, 0];\n rightEyeScaleOffset = [1, 1, 0, 0];\n }\n\n const uTexScaleOffset = gl.getUniformLocation(shaderProgram, \"uTexScaleOffset\");\n\n gl.uniform4fv(uTexScaleOffset, [...leftEyeScaleOffset, ...rightEyeScaleOffset]);\n\n super.render(ctx);\n }\n\n public getVertexPositionData() {\n return SphereRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return SphereRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return SphereRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const { width, height } = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n}\n\nexport default SphereRenderer;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\n\nimport { window, IS_IOS, IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { CHROME_VERSION } from \"../consts\";\n\nimport PosePredictor from \"./lib/webvr-polyfill/pose-predictor\";\nimport MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport Util from \"./lib/webvr-polyfill/util\";\nimport DeviceMotion from \"./DeviceMotion\";\nimport ComplementaryFilter from \"./ComplementaryFilter\";\n\n\nconst K_FILTER = 0.98;\nconst PREDICTION_TIME_S = 0.040;\n\nexport default class FusionPoseSensor extends Component<{\n change: {\n quaternion: quat;\n };\n}> {\n public deviceMotion: DeviceMotion | null;\n public accelerometer: any;\n public gyroscope: any;\n public filter: ComplementaryFilter;\n public posePredictor: PosePredictor;\n public filterToWorldQ: any;\n public isFirefoxAndroid: boolean;\n public isIOS: boolean;\n public isChromeUsingDegrees: boolean;\n public inverseWorldToScreenQ: any;\n public worldToScreenQ: any;\n public originalPoseAdjustQ: any;\n public resetQ: any;\n public deviceOrientationFixQ: any;\n public predictedQ: any;\n public previousTimestampS: number;\n\n private _isEnabled: boolean;\n private _deviceOrientationQ: any;\n private _prevOrientation: quat;\n private _alpha: number;\n\n public constructor() {\n super();\n\n this.deviceMotion = new DeviceMotion();\n\n this.accelerometer = new MathUtil.Vector3();\n this.gyroscope = new MathUtil.Vector3();\n\n this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);\n this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);\n\n this.filter = new ComplementaryFilter(K_FILTER);\n this.posePredictor = new PosePredictor(PREDICTION_TIME_S);\n\n this.filterToWorldQ = new MathUtil.Quaternion();\n\n this.isFirefoxAndroid = Util.isFirefoxAndroid();\n // This includes iPhone & iPad(both desktop and mobile mode) ref #326\n this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP;\n\n // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18\n this.isChromeUsingDegrees = CHROME_VERSION >= 66;\n\n this._isEnabled = false;\n\n // Set the filter to world transform, depending on OS.\n if (this.isIOS) {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);\n } else {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n this.inverseWorldToScreenQ = new MathUtil.Quaternion();\n this.worldToScreenQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),\n -window.orientation * Math.PI / 180);\n\n this._setScreenTransform();\n // Adjust this filter for being in landscape mode.\n if (Util.isLandscapeMode()) {\n this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);\n }\n\n // Keep track of a reset transform for resetSensor.\n this.resetQ = new MathUtil.Quaternion();\n\n this.deviceMotion.on(\"devicemotion\", this._onDeviceMotionChange);\n this.enable();\n }\n\n public enable() {\n if (this.isEnabled()) {\n return;\n }\n this.deviceMotion!.enable();\n this._isEnabled = true;\n window.addEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public disable() {\n if (!this.isEnabled()) {\n return;\n }\n this.deviceMotion!.disable();\n this._isEnabled = false;\n window.removeEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public isEnabled() {\n return this._isEnabled;\n }\n\n public destroy() {\n this.disable();\n this.deviceMotion = null;\n }\n\n public getOrientation() {\n let orientation;\n\n // Hack around using deviceorientation instead of devicemotion\n if (this.deviceMotion!.isWithoutDeviceMotion && this._deviceOrientationQ) {\n this.deviceOrientationFixQ = this.deviceOrientationFixQ || (() => {\n const y = new MathUtil.Quaternion()\n .setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -this._alpha);\n\n return y;\n })();\n\n orientation = this._deviceOrientationQ;\n const out = new MathUtil.Quaternion();\n\n out.copy(orientation);\n out.multiply(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.worldToScreenQ);\n out.multiplyQuaternions(this.deviceOrientationFixQ, out);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n } else {\n // Convert from filter space to the the same system used by the\n // deviceorientation event.\n orientation = this.filter.getOrientation();\n\n if (!orientation) {\n return null;\n }\n\n const out = this._convertFusionToPredicted(orientation);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n }\n }\n\n private _triggerChange() {\n const orientation = this.getOrientation();\n\n // if orientation is not prepared. don't trigger change event\n if (!orientation) {\n return;\n }\n\n if (!this._prevOrientation) {\n this._prevOrientation = orientation;\n return;\n }\n\n if (quat.equals(this._prevOrientation, orientation)) {\n return;\n }\n\n this.trigger(new ComponentEvent(\"change\", { quaternion: orientation }));\n }\n\n private _convertFusionToPredicted(orientation: quat) {\n // Predict orientation.\n this.predictedQ =\n this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);\n\n // Convert to THREE coordinate system: -Z forward, Y up, X right.\n const out = new MathUtil.Quaternion();\n\n out.copy(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.predictedQ);\n out.multiply(this.worldToScreenQ);\n\n return out;\n }\n\n private _onDeviceMotionChange({ inputEvent }) {\n const deviceorientation = inputEvent.deviceorientation;\n const deviceMotion = inputEvent;\n const accGravity = deviceMotion.accelerationIncludingGravity;\n const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;\n let timestampS = deviceMotion.timeStamp / 1000;\n\n if (deviceorientation) {\n if (!this._alpha) {\n this._alpha = deviceorientation.alpha;\n }\n this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();\n this._deviceOrientationQ.setFromEulerYXZ(\n deviceorientation.beta,\n deviceorientation.alpha,\n deviceorientation.gamma\n );\n\n this._triggerChange();\n } else {\n // Firefox Android timeStamp returns one thousandth of a millisecond.\n if (this.isFirefoxAndroid) {\n timestampS /= 1000;\n }\n\n this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);\n this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);\n\n // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate`\n // is reported in degrees, so we first convert to radians.\n if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) {\n this.gyroscope.multiplyScalar(Math.PI / 180);\n }\n\n this.filter.addAccelMeasurement(this.accelerometer, timestampS);\n this.filter.addGyroMeasurement(this.gyroscope, timestampS);\n\n this._triggerChange();\n\n this.previousTimestampS = timestampS;\n }\n }\n\n private _onScreenOrientationChange() {\n this._setScreenTransform();\n }\n\n private _setScreenTransform() {\n this.worldToScreenQ.set(0, 0, 0, 1);\n\n const orientation = window.orientation;\n\n switch (orientation) {\n case 0:\n break;\n case 90:\n case -90:\n case 180:\n this.worldToScreenQ\n .setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI);\n break;\n default:\n break;\n }\n this.inverseWorldToScreenQ.copy(this.worldToScreenQ);\n this.inverseWorldToScreenQ.inverse();\n }\n}\n","import Component from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\n\nimport { toAxis } from \"../utils\";\nimport { util, ROTATE_CONSTANT } from \"../../utils/math-util\";\n\nimport FusionPoseSensor from \"./FusionPoseSensor\";\n\nconst getDeltaYaw = (prvQ: quat, curQ: quat): number => {\n const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(util.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nconst getDeltaPitch = (prvQ: quat, curQ: quat): number => {\n const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport default class TiltMotionInput extends Component<{}> {\n public element: HTMLElement;\n public options: { scale: number; threshold: number };\n public fusionPoseSensor: FusionPoseSensor | null;\n public axes: string[];\n public observer: InputTypeObserver | null;\n\n private _prevQuaternion: quat | null;\n private _quaternion: quat | null;\n\n public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {\n super();\n this.element = el;\n\n this._prevQuaternion = null;\n this._quaternion = null;\n\n this.fusionPoseSensor = null;\n\n this.options = {\n ...{\n scale: 1,\n threshold: 0\n }, ...options\n };\n\n this._onPoseChange = this._onPoseChange.bind(this);\n }\n\n public mapAxes(axes: string[]) {\n this.axes = axes;\n }\n\n public connect(observer: InputTypeObserver) {\n if (this.observer) {\n return this;\n }\n this.observer = observer;\n this.fusionPoseSensor = new FusionPoseSensor();\n this.fusionPoseSensor.enable();\n this._attachEvent();\n return this;\n }\n\n public disconnect() {\n if (!this.observer) {\n return this;\n }\n\n this._dettachEvent();\n this.fusionPoseSensor!.disable();\n this.fusionPoseSensor!.destroy();\n this.fusionPoseSensor = null;\n this.observer = null;\n return this;\n }\n\n public destroy() {\n this.disconnect();\n (this.element as any) = null;\n (this.options as any) = null;\n (this.axes as any) = null;\n this._prevQuaternion = null;\n this._quaternion = null;\n }\n\n private _onPoseChange(event) {\n if (!this._prevQuaternion) {\n this._prevQuaternion = quat.clone(event.quaternion);\n this._quaternion = quat.clone(event.quaternion);\n return;\n }\n\n quat.copy(this._prevQuaternion, this._quaternion!);\n quat.copy(this._quaternion!, event.quaternion);\n\n this.observer!.change(this, event, toAxis(this.axes, [\n getDeltaYaw(this._prevQuaternion, this._quaternion as quat),\n getDeltaPitch(this._prevQuaternion, this._quaternion as quat)\n ]));\n }\n\n private _attachEvent() {\n this.fusionPoseSensor!.on(\"change\", this._onPoseChange);\n }\n\n private _dettachEvent() {\n this.fusionPoseSensor!.off(\"change\", this._onPoseChange);\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport { window } from \"../utils/browser\";\n\n// Singleton\nlet screenRotationAngleInst: ScreenRotationAngle | null = null;\nlet refCount = 0;\n\nexport default class ScreenRotationAngle {\n private _spinR: number;\n private _screenOrientationAngle: number;\n\n public constructor() {\n refCount++;\n\n if (screenRotationAngleInst) {\n return screenRotationAngleInst;\n }\n /* eslint-disable */\n screenRotationAngleInst = this;\n /* eslint-enable */\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n\n this._spinR = 0;\n\n this._screenOrientationAngle = 0;\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.addEventListener(\"orientationchange\", this._onOrientationChange);\n }\n\n public getRadian() {\n // Join with screen orientation\n // this._testVal = this._spinR + \", \" + this._screenOrientationAngle + \", \" + window.orientation;\n return this._spinR + glMatrix.toRadian(this._screenOrientationAngle);\n }\n\n public unref() {\n if (--refCount > 0) {\n return;\n }\n\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"orientationchange\", this._onOrientationChange);\n\n this._spinR = 0;\n this._screenOrientationAngle = 0;\n /* eslint-disable */\n screenRotationAngleInst = null;\n /* eslint-enable */\n refCount = 0;\n }\n\n private _onDeviceOrientation(e: DeviceOrientationEvent) {\n if (e.beta === null || e.gamma === null) {\n // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it.\n return;\n }\n\n // Radian\n const betaR = glMatrix.toRadian(e.beta);\n const gammaR = glMatrix.toRadian(e.gamma);\n\n /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */\n this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR));\n }\n\n private _onOrientationChange() {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientationAngle = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n /* iOS */\n this._screenOrientationAngle = window.orientation >= 0 ?\n window.orientation : 360 + (window.orientation as number);\n }\n }\n}\n","import Axes, { PanInput } from \"@egjs/axes\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\nimport { PanInputOption } from \"@egjs/axes/declaration/inputType/PanInput\";\n\nimport ScreenRotationAngle from \"../ScreenRotationAngle\";\n\n/**\n * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle.\n *\n * The reason for using this function is that in VR mode,\n * the roll angle is adjusted in the direction opposite to the screen rotation angle.\n *\n * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move.\n * @extends PanInput\n */\nexport default class RotationPanInput extends PanInput {\n private _useRotation: boolean;\n private _screenRotationAngle: ScreenRotationAngle | null;\n private _userDirection: number;\n\n /**\n * Constructor\n * @private\n * @param {HTMLElement} el target element\n * @param {Object} [options] The option object\n * @param {Boolean} [options.useRotation] Whether to use rotation(or VR)\n */\n public constructor(el: HTMLElement, options: Partial<{ useRotation: boolean } & PanInputOption> = {}) {\n super(el, options);\n\n this._useRotation = false;\n this._screenRotationAngle = null;\n\n this.setUseRotation(!!(options && options.useRotation));\n\n this._userDirection = Axes.DIRECTION_ALL;\n }\n\n public setUseRotation(useRotation: boolean) {\n this._useRotation = useRotation;\n\n if (this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n this._screenRotationAngle = null;\n }\n\n if (this._useRotation) {\n this._screenRotationAngle = new ScreenRotationAngle();\n }\n }\n\n public connect(observer: InputTypeObserver) {\n // User intetened direction\n this._userDirection = this._direction;\n\n // In VR Mode, Use ALL direction if direction is not none\n // Because horizontal and vertical is changed dynamically by screen rotation.\n // this._direction is used to initialize hammerjs\n if (this._useRotation && (this._direction & Axes.DIRECTION_ALL)) {\n this._direction = Axes.DIRECTION_HORIZONTAL;\n }\n\n return super.connect(observer);\n }\n\n public destroy() {\n if (this._useRotation && this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n }\n\n super.destroy();\n }\n\n protected _getOffset(properties: number[], useDirection: boolean[]) {\n if (this._useRotation === false) {\n return super._getOffset(properties, useDirection);\n }\n\n const offset = super._getOffset(properties, [true, true]);\n const newOffset = [0, 0];\n\n const theta = this._screenRotationAngle!.getRadian();\n\n const cosTheta = Math.cos(theta);\n const sinTheta = Math.sin(theta);\n\n // RotateZ\n newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta;\n newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta;\n\n // Use only user allowed direction.\n if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) {\n newOffset[0] = 0;\n } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) {\n newOffset[1] = 0;\n }\n\n return newOffset;\n }\n}\n\n/**\n * Override getDirectionByAngle to return DIRECTION_ALL\n * Ref: https://github.com/naver/egjs-axes/issues/99\n *\n * But we obey axes's rule. If axes's rule is problem, let's apply following code.\n */\n// PanInput.getDirectionByAngle = function (angle, thresholdAngle) {\n// \treturn DIRECTION_ALL;\n// };\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3, glMatrix, quat } from \"gl-matrix\";\n\nimport FusionPoseSensor from \"./input/FusionPoseSensor\";\n\nconst Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0);\n\nexport default class DeviceQuaternion extends Component<{\n change: {\n isTrusted: boolean;\n };\n}> {\n private _fusionPoseSensor: FusionPoseSensor | null;\n private _quaternion: quat;\n\n public constructor() {\n super();\n\n this._fusionPoseSensor = new FusionPoseSensor();\n this._quaternion = quat.create();\n\n this._fusionPoseSensor.enable();\n this._fusionPoseSensor.on(\"change\", e => {\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(\"change\", { isTrusted: true }));\n });\n }\n\n public getCombinedQuaternion(yaw: number) {\n const yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw));\n const conj = quat.conjugate(quat.create(), this._quaternion);\n // Multiply pitch quaternion -> device quaternion -> yaw quaternion\n const outQ = quat.multiply(quat.create(), conj, yawQ);\n\n return outQ;\n }\n\n public destroy() {\n // detach all event handler\n this.off();\n\n if (this._fusionPoseSensor) {\n this._fusionPoseSensor.off();\n this._fusionPoseSensor.destroy();\n this._fusionPoseSensor = null;\n }\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PinchInput, MoveKeyInput, WheelInput } from \"@egjs/axes\";\nimport { vec2, quat, glMatrix } from \"gl-matrix\";\n\nimport { SUPPORT_TOUCH, SUPPORT_DEVICEMOTION } from \"../utils/browserFeature\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { ValueOf } from \"../types/internal\";\n\nimport TiltMotionInput from \"./input/TiltMotionInput\";\nimport RotationPanInput from \"./input/RotationPanInput\";\nimport DeviceQuaternion from \"./DeviceQuaternion\";\nimport {\n GYRO_MODE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n TOUCH_DIRECTION_NONE\n} from \"./consts\";\n\n\nconst DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF];\nconst DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF];\nconst CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF];\n\nexport interface YawPitchControlOptions {\n element: HTMLElement | null;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n touchDirection: number;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n aspectRatio: number;\n}\ninterface YawPitchControlEvents {\n change: ComponentEvent<{\n yaw: number;\n pitch: number;\n fov: number;\n quaternion: quat | null;\n targetElement: HTMLElement;\n isTrusted: boolean;\n }>;\n hold: ComponentEvent<{\n isTrusted: boolean;\n }>;\n animationEnd: ComponentEvent<{\n isTrusted: boolean;\n }>;\n}\n\n/**\n * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates.\n * @alias eg.YawPitchControl\n * @extends eg.Component\n *\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass YawPitchControl extends Component {\n public static VERSION = VERSION;\n // Expose DeviceOrientationControls sub module for test purpose\n public static CONTROL_MODE_VR = CONTROL_MODE_VR;\n public static CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH;\n public static TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL;\n public static TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW;\n public static TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH;\n public static TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE;\n\n public options: YawPitchControlOptions;\n\n private _element: HTMLElement | null;\n private _initialFov: number;\n private _enabled: boolean;\n private _isAnimating: boolean;\n private _deviceQuaternion: DeviceQuaternion | null;\n\n private _axes: Axes;\n private _axesPanInput: RotationPanInput;\n private _axesWheelInput: WheelInput;\n private _axesTiltMotionInput: TiltMotionInput | null;\n private _axesPinchInput: PinchInput | null;\n private _axesMoveKeyInput: MoveKeyInput;\n\n /**\n * @param {object} options The option object of the eg.YawPitch module\n * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module\n * @param {number} [options.yaw=0] initial yaw (degree)\n * @param {number} [options.pitch=0] initial pitch (degree)\n * @param {number} [options.fov=65] initial field of view (degree)\n * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown\n * @param {boolean} [options.useZoom=true] Indicates whether zoom is available\n * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled\n * @param {string} [config.gyroMode=yawPitch] Enables control through device motion.\n * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move)\n * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw\n * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch\n * @param {number[]} [options.fovRange=[30, 110] Range of FOV\n * @param {number} [options.aspectRatio=1] Aspect Ratio\n */\n public constructor(options: Partial) {\n super();\n this.options = {} as any;\n\n const opt = {\n ...{\n element: null,\n yaw: 0,\n pitch: 0,\n fov: 65,\n showPolePoint: false,\n useZoom: true,\n useKeyboard: true,\n gyroMode: GYRO_MODE.YAWPITCH,\n touchDirection: TOUCH_DIRECTION_ALL,\n yawRange: DEFAULT_YAW_RANGE,\n pitchRange: DEFAULT_PITCH_RANGE,\n fovRange: [30, 110],\n aspectRatio: 1 /* TODO: Need Mandatory? */\n }, ...options\n };\n\n this._element = opt.element;\n this._initialFov = opt.fov;\n this._enabled = false;\n this._isAnimating = false;\n this._deviceQuaternion = null;\n\n this._initAxes(opt);\n this.option(opt);\n }\n\n /**\n * Update Pan Scale\n *\n * Scale(Sensitivity) values of panning is related with fov and height.\n * If at least one of them is changed, this function need to be called.\n * @param {*} param\n */\n public updatePanScale(param: Partial<{\n height: number;\n }> = {}) {\n const fov = this._axes.get().fov;\n const areaHeight = param.height || parseInt(window.getComputedStyle(this._element!).height, 10);\n const scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight;\n\n this._axesPanInput.options.scale = [scale, scale];\n this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW;\n\n return this;\n }\n\n public option(): YawPitchControlOptions;\n public option(key: K): YawPitchControlOptions[K];\n public option(key: K, newValue: YawPitchControlOptions[K]): YawPitchControl;\n public option(newOptions: Partial): YawPitchControl;\n /*\n * Override component's option method\n * to call method for updating values which is affected by option change.\n *\n * @param {*} args\n */\n public option(key?: K | Partial, newValue?: YawPitchControlOptions[K]) {\n // Getter\n if (!key) {\n return this._getOptions();\n } else if (key && typeof key === \"string\" && typeof newValue === \"undefined\") {\n return this._getOptions(key);\n }\n\n // Setter\n let newOptions: Partial = {};\n let changedKeyList: string[] = []; // TODO: if value is not changed, then do not push on changedKeyList.\n\n if (typeof key === \"string\") {\n changedKeyList.push(key);\n newOptions[key] = newValue;\n } else {\n const options = key; // Retrieving object here\n changedKeyList = Object.keys(options);\n newOptions = {...options};\n }\n\n this._setOptions(this._getValidatedOptions(newOptions));\n this._applyOptions(changedKeyList);\n return this;\n }\n\n /**\n * Enable YawPitch functionality\n * @method eg.YawPitch#enable\n */\n public enable() {\n if (this._enabled) {\n return this;\n }\n\n this._enabled = true;\n\n // touchDirection is decided by parameter is valid string (Ref. Axes.connect)\n this._applyOptions(Object.keys(this.options));\n\n // TODO: Is this code is needed? Check later.\n this.updatePanScale();\n\n return this;\n }\n\n /**\n * Disable YawPitch functionality\n * @method eg.YawPitch#disable\n */\n public disable(persistOrientation: boolean = false) {\n if (!this._enabled) {\n return this;\n }\n\n // TODO: Check peristOrientation is needed!\n if (!persistOrientation) {\n this._resetOrientation();\n }\n this._axes.disconnect();\n this._enabled = false;\n return this;\n }\n\n /**\n * Set one or more of yaw, pitch, fov\n * @param {Object} coordinate yaw, pitch, fov\n * @param {Number} duration Animation duration. if it is above 0 then it's animated.\n */\n public lookAt({yaw, pitch, fov}, duration) {\n const pos = this._axes.get();\n\n const y = yaw === undefined ? 0 : yaw - pos.yaw;\n const p = pitch === undefined ? 0 : pitch - pos.pitch;\n const f = fov === undefined ? 0 : fov - pos.fov;\n\n // Allow duration of animation to have more than MC_MAXIMUM_DURATION.\n this._axes.options.maximumDuration = Infinity;\n\n this._axes.setBy({\n yaw: y,\n pitch: p,\n fov: f\n }, duration);\n }\n\n public getYawPitch() {\n const yawPitch = this._axes.get();\n\n return {\n yaw: yawPitch.yaw,\n pitch: yawPitch.pitch\n };\n }\n\n public getFov() {\n return this._axes.get().fov;\n }\n\n public getQuaternion() {\n const pos = this._axes.get();\n\n return this._deviceQuaternion!.getCombinedQuaternion(pos.yaw);\n }\n\n public shouldRenderWithQuaternion() {\n return this.options.gyroMode === GYRO_MODE.VR;\n }\n\n /**\n * Destroys objects\n */\n public destroy() {\n /* eslint-disable @typescript-eslint/no-unused-expressions */\n this._axes && this._axes.destroy();\n this._axesPanInput && this._axesPanInput.destroy();\n this._axesWheelInput && this._axesWheelInput.destroy();\n this._axesTiltMotionInput && this._axesTiltMotionInput.destroy();\n this._axesPinchInput && this._axesPinchInput.destroy();\n this._axesMoveKeyInput && this._axesMoveKeyInput.destroy();\n this._deviceQuaternion && this._deviceQuaternion.destroy();\n /* eslint-enable @typescript-eslint/no-unused-expressions */\n }\n\n private _initAxes(opt: YawPitchControlOptions) {\n const yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio);\n const pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint);\n const useRotation = opt.gyroMode === GYRO_MODE.VR;\n\n this._axesPanInput = new RotationPanInput(this._element!, {useRotation});\n this._axesWheelInput = new WheelInput(this._element, {scale: -4});\n this._axesTiltMotionInput = null;\n this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, {scale: -1}) : null;\n this._axesMoveKeyInput = new MoveKeyInput(this._element, {scale: [-6, 6]});\n\n this._axes = new Axes({\n yaw: {\n range: yRange,\n circular: this._isCircular(yRange),\n bounce: [0, 0]\n },\n pitch: {\n range: pRange,\n circular: this._isCircular(pRange),\n bounce: [0, 0]\n },\n fov: {\n range: opt.fovRange,\n circular: [false, false],\n bounce: [0, 0]\n }\n }, {\n deceleration: MC_DECELERATION,\n maximumDuration: MC_MAXIMUM_DURATION\n }, {\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }).on({\n // TODO: change event type after Axes event type inference update\n hold: (evt: any) => {\n // Restore maximumDuration not to be spin too mush.\n this._axes.options.maximumDuration = MC_MAXIMUM_DURATION;\n\n this.trigger(new ComponentEvent(\"hold\", { isTrusted: evt.isTrusted }));\n },\n change: (evt: any) => {\n if (evt.delta.fov !== 0) {\n this._updateControlScale(evt);\n this.updatePanScale();\n }\n this._triggerChange(evt);\n },\n release: evt => {\n this._triggerChange(evt);\n },\n animationEnd: (evt: any) => {\n this.trigger(new ComponentEvent(\"animationEnd\", { isTrusted: evt.isTrusted }));\n }\n });\n }\n\n private _getValidatedOptions(newOptions: Partial) {\n if (newOptions.yawRange) {\n newOptions.yawRange =\n this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio);\n }\n if (newOptions.pitchRange) {\n newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov);\n }\n return newOptions;\n }\n\n private _getOptions(): YawPitchControlOptions;\n private _getOptions(key: K): YawPitchControlOptions[K];\n private _getOptions(key?: K) {\n let value;\n\n if (typeof key === \"string\") {\n value = this.options[key];\n } else if (arguments.length === 0) {\n value = this.options;\n }\n return value;\n }\n\n private _setOptions(options: Partial): void {\n for (const key in options) {\n this.options[key] = options[key];\n }\n }\n\n private _applyOptions(keys: string[]) {\n const options = this.options;\n const axes = this._axes;\n const isVR = options.gyroMode === GYRO_MODE.VR;\n const isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH;\n // If it's VR mode, restrict user interaction to yaw direction only\n const touchDirection = isVR ?\n (TOUCH_DIRECTION_YAW & options.touchDirection) :\n options.touchDirection;\n\n // If one of below is changed, call updateControlScale()\n if (keys.some(key =>\n key === \"showPolePoint\" || key === \"fov\" || key === \"aspectRatio\" ||\n key === \"yawRange\" || key === \"pitchRange\"\n )) {\n // If fov is changed, update pan scale\n if (keys.indexOf(\"fov\") >= 0) {\n axes.setTo({\"fov\": options.fov});\n this.updatePanScale();\n }\n\n this._updateControlScale();\n }\n\n if (keys.some(key => key === \"fovRange\")) {\n const fovRange = options.fovRange;\n const prevFov = axes.get().fov;\n let nextFov = axes.get().fov;\n\n vec2.copy(axes.axis.fov.range as vec2, fovRange as vec2);\n\n if (nextFov < fovRange[0]) {\n nextFov = fovRange[0];\n } else if (prevFov > fovRange[1]) {\n nextFov = fovRange[1];\n }\n\n if (prevFov !== nextFov) {\n axes.setTo({\n fov: nextFov\n }, 0);\n this._updateControlScale();\n this.updatePanScale();\n }\n }\n\n if (keys.some(key => key === \"gyroMode\") && SUPPORT_DEVICEMOTION) {\n // Disconnect first\n if (this._axesTiltMotionInput) {\n this._axes.disconnect(this._axesTiltMotionInput);\n this._axesTiltMotionInput.destroy();\n this._axesTiltMotionInput = null;\n }\n\n if (this._deviceQuaternion) {\n this._deviceQuaternion.destroy();\n this._deviceQuaternion = null;\n }\n\n if (isVR) {\n this._initDeviceQuaternion();\n } else if (isYawPitch) {\n this._axesTiltMotionInput = new TiltMotionInput(this._element!);\n this._axes.connect([\"yaw\", \"pitch\"], this._axesTiltMotionInput);\n }\n\n this._axesPanInput.setUseRotation(isVR);\n }\n\n if (keys.some(key => key === \"useKeyboard\")) {\n const useKeyboard = options.useKeyboard;\n\n if (useKeyboard) {\n axes.connect([\"yaw\", \"pitch\"], this._axesMoveKeyInput);\n } else {\n axes.disconnect(this._axesMoveKeyInput);\n }\n }\n\n if (keys.some(key => key === \"useZoom\")) {\n const useZoom = options.useZoom;\n\n // Disconnect first\n axes.disconnect(this._axesWheelInput);\n if (useZoom) {\n axes.connect([\"fov\"], this._axesWheelInput);\n }\n }\n\n this._togglePinchInputByOption(options.touchDirection, options.useZoom);\n\n if (keys.some(key => key === \"touchDirection\") && this._enabled) {\n this._enableTouch(touchDirection);\n }\n }\n\n private _togglePinchInputByOption(touchDirection: YawPitchControlOptions[\"touchDirection\"], useZoom: boolean) {\n if (this._axesPinchInput) {\n // disconnect first\n this._axes.disconnect(this._axesPinchInput);\n\n // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll.\n if (\n useZoom &&\n touchDirection === TOUCH_DIRECTION_ALL &&\n // TODO: Get rid of using private property of axes instance.\n (this._axes as any)._inputs.indexOf(this._axesPinchInput) === -1\n ) {\n this._axes.connect([\"fov\"], this._axesPinchInput);\n }\n }\n }\n\n private _enableTouch(direction: YawPitchControlOptions[\"touchDirection\"]) {\n // Disconnect first\n if (this._axesPanInput) {\n this._axes.disconnect(this._axesPanInput);\n }\n\n const yawEnabled = direction & TOUCH_DIRECTION_YAW ? \"yaw\" : null;\n const pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? \"pitch\" : null;\n\n this._axes.connect([yawEnabled, pitchEnabled] as string[], this._axesPanInput);\n }\n\n private _initDeviceQuaternion() {\n this._deviceQuaternion = new DeviceQuaternion();\n this._deviceQuaternion.on(\"change\", e => {\n this._triggerChange(e);\n });\n }\n\n private _getValidYawRange(newYawRange: number[], newFov?: number, newAspectRatio?: number) {\n const ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1);\n const fov = newFov || this._axes.get().fov;\n const horizontalFov = fov * ratio;\n const isValid = newYawRange[1] - newYawRange[0] >= horizontalFov;\n\n if (isValid) {\n return newYawRange;\n } else {\n return this.options.yawRange || DEFAULT_YAW_RANGE;\n }\n }\n\n private _getValidPitchRange(newPitchRange: number[], newFov?: number) {\n const fov = newFov || this._axes.get().fov;\n const isValid = newPitchRange[1] - newPitchRange[0] >= fov;\n\n if (isValid) {\n return newPitchRange;\n } else {\n return this.options.pitchRange || DEFAULT_PITCH_RANGE;\n }\n }\n\n private _isCircular(range: number[]) {\n return range[1] - range[0] < 360 ? [false, false] : [true, true];\n }\n\n /**\n * Update yaw/pitch min/max by 5 factor\n *\n * 1. showPolePoint\n * 2. fov\n * 3. yawRange\n * 4. pitchRange\n * 5. aspectRatio\n *\n * If one of above is changed, call this function\n */\n private _updateControlScale(changeEvt?: any) { // TODO: Change type after Axes type inference update\n const opt = this.options;\n const fov = this._axes.get().fov;\n\n const pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint);\n const yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio);\n\n // TODO: If not changed!?\n const pos = this._axes.get();\n let y = pos.yaw;\n let p = pos.pitch;\n\n vec2.copy(this._axes.axis.yaw.range as any, yRange as any);\n vec2.copy(this._axes.axis.pitch.range as any, pRange as any);\n this._axes.axis.yaw.circular = this._isCircular(yRange);\n this._axes.axis.pitch.circular = this._isCircular(pRange);\n\n /**\n * update yaw/pitch by it's range.\n */\n if (y < yRange[0]) {\n y = yRange[0];\n } else if (y > yRange[1]) {\n y = yRange[1];\n }\n\n if (p < pRange[0]) {\n p = pRange[0];\n } else if (p > pRange[1]) {\n p = pRange[1];\n }\n\n if (changeEvt) {\n changeEvt.set({\n yaw: y,\n pitch: p\n });\n }\n\n this._axes.setTo({\n yaw: y,\n pitch: p\n }, 0);\n\n return this;\n }\n\n private _updatePitchRange(pitchRange: number[], fov: number, showPolePoint: boolean) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n // Circular pitch on VR\n return CIRCULAR_PITCH_RANGE;\n }\n\n const verticalAngle = pitchRange[1] - pitchRange[0];\n const halfFov = fov / 2;\n const isPanorama = verticalAngle < 180;\n\n if (showPolePoint && !isPanorama) {\n // Use full pinch range\n return pitchRange.concat();\n }\n\n // Round value as movableCood do.\n return [pitchRange[0] + halfFov, pitchRange[1] - halfFov];\n }\n\n private _updateYawRange(yawRange: number[], fov: number, aspectRatio: number) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n return DEFAULT_YAW_RANGE;\n }\n\n const horizontalAngle = yawRange[1] - yawRange[0];\n\n /**\n * Full 360 Mode\n */\n if (horizontalAngle >= 360) {\n // Don't limit yaw range on Full 360 mode.\n return yawRange.concat();\n }\n\n /**\n * Panorama mode\n */\n // Ref : https://github.com/naver/egjs-view360/issues/290\n const halfHorizontalFov =\n mathUtil.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))) as number;\n\n // Round value as movableCood do.\n return [\n yawRange[0] + halfHorizontalFov,\n yawRange[1] - halfHorizontalFov\n ];\n }\n\n // TODO: update param type after Axes event type inference update\n private _triggerChange(evt: any) {\n const pos = this._axes.get();\n const opt = this.options;\n const event: YawPitchControlEvents[\"change\"] extends ComponentEvent ? T : never = {\n targetElement: opt.element as HTMLElement,\n isTrusted: evt.isTrusted,\n yaw: pos.yaw,\n pitch: pos.pitch,\n fov: pos.fov,\n quaternion: null\n };\n\n if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) {\n event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw);\n }\n\n this.trigger(new ComponentEvent(\"change\", event));\n }\n\n // TODO: makes constant to be logic\n private _adjustAspectRatio(input: number) {\n const inputRange = [\n 0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670,\n 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19,\n 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26,\n 2.30, 2.60, 3.00, 5.00, 6.00\n ];\n const outputRange = [\n 0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710,\n 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15,\n 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72,\n 1.82, 1.92, 2.00, 2.24, 2.30\n ];\n\n let rangeIdx = -1;\n\n for (let i = 0; i < inputRange.length - 1; i++) {\n if (inputRange[i] <= input && inputRange[i + 1] >= input) {\n rangeIdx = i;\n break;\n }\n }\n\n if (rangeIdx === -1) {\n if (inputRange[0] > input) {\n return outputRange[0];\n } else {\n // FIXME: this looks definitely wrong\n return outputRange[(outputRange[0] as any).length - 1];\n }\n }\n\n const inputA = inputRange[rangeIdx];\n const inputB = inputRange[rangeIdx + 1];\n const outputA = outputRange[rangeIdx];\n const outputB = outputRange[rangeIdx + 1];\n\n return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA));\n }\n\n private _lerp(a: number, b: number, fraction: number) {\n return a + fraction * (b - a);\n }\n\n private _resetOrientation() {\n const opt = this.options;\n\n this._axes.setTo({\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }, 0);\n\n return this;\n }\n}\n\nexport default YawPitchControl;\n","/**\n * Constant value for gyro mode.
(Reference {@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide})\n * @ko gyro 모드 대한 상수 값.
({@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide} 참고)\n * @namespace\n * @name GYRO_MODE\n * @memberof eg.view360.PanoViewer\n */\n/**\n * Disable gyro\n * @ko gyro 비활성화\n * @name NONE\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"none\"\n */\n/**\n * YawPitch Mode\n * @ko YawPitch Mode\n * @name YAWPITCH\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"yawPitch\"\n */\n/**\n * VR Mode\n * @ko VR Mode\n * @name VR\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"VR\"\n */\nimport { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\nimport { GYRO_MODE } from \"../YawPitchControl/consts\";\n\n/**\n * Constant value for errors\n * @ko 에러에 대한 상수 값\n * @namespace\n * @name ERROR_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst ERROR_TYPE = {\n /**\n * Unsupported device\n * @ko 미지원 기기\n * @name INVALID_DEVICE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 10\n */\n INVALID_DEVICE: 10,\n /**\n * Webgl not support\n * @ko WEBGL 미지원\n * @name NO_WEBGL\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 11\n */\n NO_WEBGL: 11,\n /**\n * Failed to load image\n * @ko 이미지 로드 실패\n * @name FAIL_IMAGE_LOAD\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 12\n */\n FAIL_IMAGE_LOAD: 12,\n /**\n * Failed to bind texture\n * @ko 텍스쳐 바인딩 실패\n * @name FAIL_BIND_TEXTURE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 13\n */\n FAIL_BIND_TEXTURE: 13,\n /**\n * Only one resource(image or video) should be specified\n * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함)\n * @name INVALID_RESOURCE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 14\n */\n INVALID_RESOURCE: 14,\n /**\n * WebGL context lost occurred\n * @ko WebGL context lost 발생\n * @name RENDERING_CONTEXT_LOST\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 15\n */\n RENDERING_CONTEXT_LOST: 15\n};\n\n/**\n * Constant value for events\n * @ko 이벤트에 대한 상수 값\n * @namespace\n * @name EVENTS\n * @memberof eg.view360.PanoViewer\n */\nconst PANOVIEWER_EVENTS: {\n READY: \"ready\";\n VIEW_CHANGE: \"viewChange\";\n ANIMATION_END: \"animationEnd\";\n ERROR: \"error\";\n} = {\n /**\n * Events that is fired when PanoViewer is ready to show image and handle user interaction.\n * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트\n * @name READY\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default ready\n */\n READY: \"ready\",\n /**\n * Events that is fired when direction or fov is changed.\n * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트\n * @name VIEW_CHANGE\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default viewChange\n */\n VIEW_CHANGE: \"viewChange\",\n /**\n * Events that is fired when animation which is triggered by inertia is ended.\n * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트\n * @name ANIMATION_END\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default animationEnd\n */\n ANIMATION_END: \"animationEnd\",\n /**\n * Events that is fired when error occurs\n * @ko 에러 발생 시 발생하는 이벤트\n * @name ERROR\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default error\n */\n ERROR: \"error\"\n};\n\n/**\n * Constant value for projection type\n * @ko 프로젝션 타입 대한 상수 값\n * @namespace\n * @name PROJECTION_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst PROJECTION_TYPE: {\n EQUIRECTANGULAR: \"equirectangular\";\n CUBEMAP: \"cubemap\";\n CUBESTRIP: \"cubestrip\";\n PANORAMA: \"panorama\";\n STEREOSCOPIC_EQUI: \"stereoequi\";\n} = {\n /**\n * Constant value for equirectangular type.\n * @ko equirectangular 에 대한 상수 값.\n * @name EQUIRECTANGULAR\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default equirectangular\n */\n EQUIRECTANGULAR: \"equirectangular\",\n /**\n * Constant value for cubemap type.\n * @ko cubemap 에 대한 상수 값.\n * @name CUBEMAP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubemap\n */\n CUBEMAP: \"cubemap\",\n /**\n * Constant value for cubestrip type.\n * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC.\n * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다.\n * @name CUBESTRIP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubestrip\n */\n CUBESTRIP: \"cubestrip\",\n /**\n * Constant value for PANORAMA type.\n *\n * PANORAMA is a format for a panorma image which is taken from smartphone.\n * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다.\n *\n * @name PANORAMA\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default panorama\n */\n PANORAMA: \"panorama\",\n /**\n * Constant value for EQUI_STEREOSCOPY type.\n *\n * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present.\n * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다.\n *\n * @name STEREOSCOPIC_EQUI\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default stereoequi\n */\n STEREOSCOPIC_EQUI: \"stereoequi\"\n};\n\n/**\n * A constant value for the format of the stereoscopic equirectangular projection type.\n * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값\n * @namespace\n * @name STEREO_FORMAT\n * @memberof eg.view360.PanoViewer\n */\nconst STEREO_FORMAT: {\n TOP_BOTTOM: \"3dv\";\n LEFT_RIGHT: \"3dh\";\n NONE: \"\";\n} = {\n /**\n * A constant value for format of top bottom stereoscopic 360 equirectangular projection.\n * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name TOP_BOTTOM\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dv\"\n */\n TOP_BOTTOM: \"3dv\",\n /**\n * A constant value for format of left right stereoscopic 360 equirectangular projection.\n * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name LEFT_RIGHT\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dh\"\n */\n LEFT_RIGHT: \"3dh\",\n /**\n * A constant value specifying media is not in stereoscopic format.\n * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"\"\n */\n NONE: \"\"\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst PANOVIEWER_OPTIONS: { [key in keyof PanoViewerOptions]: true } = {\n image: true,\n video: true,\n projectionType: true,\n cubemapConfig: true,\n stereoFormat: true,\n width: true,\n height: true,\n yaw: true,\n pitch: true,\n fov: true,\n showPolePoint: true,\n useZoom: true,\n useKeyboard: true,\n gyroMode: true,\n yawRange: true,\n pitchRange: true,\n fovRange: true,\n touchDirection: true,\n canvasClass: true\n};\n\nconst DEFAULT_CANVAS_CLASS = \"view360-canvas\";\n\nexport {\n GYRO_MODE,\n PANOVIEWER_EVENTS,\n ERROR_TYPE,\n PROJECTION_TYPE,\n STEREO_FORMAT,\n PANOVIEWER_OPTIONS,\n DEFAULT_CANVAS_CLASS\n};\n","import agent from \"@egjs/agent\";\n\nimport { TypedArray } from \"../types/internal\";\n\nconst WEBGL_ERROR_CODE = {\n \"0\": \"NO_ERROR\",\n \"1280\": \"INVALID_ENUM\",\n \"1281\": \"INVALID_VALUE\",\n \"1282\": \"INVALID_OPERATION\",\n \"1285\": \"OUT_OF_MEMORY\",\n \"1286\": \"INVALID_FRAMEBUFFER_OPERATION\",\n \"37442\": \"CONTEXT_LOST_WEBGL\"\n};\n\nlet webglAvailability: boolean | null = null;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet MAX_TEXTURE_SIZE_FOR_TEST: number | null = null;\n\nexport default class WebGLUtils {\n public static createShader(gl: WebGLRenderingContext, type: number, source: string) {\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (success) {\n return shader;\n }\n\n // eslint-disable-next-line\n console.error(gl.getShaderInfoLog(shader));\n\n return null;\n }\n\n public static createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = gl.createProgram()!;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (success) {\n return program;\n }\n\n gl.deleteProgram(program);\n return null;\n }\n\n public static initBuffer(gl: WebGLRenderingContext, target: number /* bind point */, data: TypedArray, itemSize: number, attr?: number) {\n const buffer = gl.createBuffer()!;\n\n gl.bindBuffer(target, buffer);\n gl.bufferData(target, data, gl.STATIC_DRAW);\n\n if (buffer) {\n (buffer as any).itemSize = itemSize;\n (buffer as any).numItems = data.length / itemSize;\n }\n\n if (attr !== undefined) {\n gl.enableVertexAttribArray(attr);\n gl.vertexAttribPointer(attr, (buffer as any).itemSize, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n }\n\n public static getWebglContext(canvas: HTMLCanvasElement, userContextAttributes?: WebGLContextAttributes) {\n const webglIdentifiers = [\"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n const contextAttributes = {\n ...{\n preserveDrawingBuffer: false,\n antialias: false\n }, ...userContextAttributes\n };\n\n const onWebglcontextcreationerror = e => e.statusMessage;\n\n canvas.addEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n return context;\n }\n\n public static createTexture(gl: WebGLRenderingContext, textureTarget: number) {\n const texture = gl.createTexture();\n\n gl.bindTexture(textureTarget, texture);\n gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(textureTarget, null);\n\n return texture;\n }\n\n /**\n * Returns the webgl availability of the current browser.\n * @method WebGLUtils#isWebGLAvailable\n * @retuen {Boolean} isWebGLAvailable\n */\n public static isWebGLAvailable(): boolean {\n if (webglAvailability === null) {\n const canvas = document.createElement(\"canvas\");\n const webglContext = WebGLUtils.getWebglContext(canvas);\n\n webglAvailability = !!webglContext;\n\n // webglContext Resource forced collection\n if (webglContext) {\n const loseContextExtension = webglContext.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n return !!webglAvailability;\n }\n\n /**\n * Returns whether webgl is stable in the current browser.\n * @method WebGLUtils#isStableWebGL\n * @retuen {Boolean} isStableWebGL\n */\n public static isStableWebGL() {\n const agentInfo = agent();\n let isStableWebgl = true;\n\n if (agentInfo.os.name === \"android\") {\n const version = parseFloat(agentInfo.os.version);\n\n if (version <= 4.3 && version >= 1) {\n isStableWebgl = false;\n } else if (version === 4.4) {\n if (agentInfo.browser.name !== \"chrome\") {\n isStableWebgl = false;\n }\n }\n }\n return isStableWebgl;\n }\n\n public static getErrorNameFromWebGLErrorCode(code: number | string) {\n if (!(code in WEBGL_ERROR_CODE)) {\n return \"UNKNOWN_ERROR\";\n }\n\n return WEBGL_ERROR_CODE[code];\n }\n\n\n /**\n * This function is wrapper for texImage2D to handle exceptions on texImage2D.\n * Purpose is to prevent service from being stopped by script error.\n */\n public static texImage2D(gl: WebGLRenderingContext, target: number, pixels: TexImageSource) {\n try {\n gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n } catch (error) {\n /* eslint-disable no-console */\n console.error(\"WebGLUtils.texImage2D error:\", error);\n /* eslint-enable no-console */\n }\n }\n\n public static getMaxTextureSize(gl: WebGLRenderingContext) {\n // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test\n return MAX_TEXTURE_SIZE_FOR_TEST || gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n}\n\n/**\n * This function should not be used in service code. It's provided only for test purpose.\n * It should be set to null or 0 when test is done.\n * @param {Number} size\n */\nconst setMaxTextureSizeForTestOnlyPurpose = (size: number) => {\n MAX_TEXTURE_SIZE_FOR_TEST = size;\n};\n\nexport {\n setMaxTextureSizeForTestOnlyPurpose\n};\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport agent from \"@egjs/agent\";\nimport { mat4 } from \"gl-matrix\";\n\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nconst agentInfo = agent();\nconst isIE11 = agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11;\n\nconst EVENTS: {\n ERROR: \"error\";\n} = {\n ERROR: \"error\"\n};\n\n/**\n *\n * Extends Component for firing errors occurs internally.\n */\nabstract class Renderer extends Component<{\n [EVENTS.ERROR]: {\n message: string;\n };\n}> {\n public static EVENTS = EVENTS;\n\n private _forceDimension: { width: number; height: number } | null;\n private _pixelCanvas: HTMLCanvasElement | null;\n private _pixelContext: CanvasRenderingContext2D | null;\n\n public constructor() {\n super();\n\n this._forceDimension = null;\n this._pixelCanvas = null;\n this._pixelContext = null;\n }\n\n public abstract getVertexPositionData(): number[];\n public abstract getIndexData(): number[];\n public abstract getTextureCoordData(textureData: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }): number[];\n\n public abstract getVertexShaderSource(): string;\n public abstract getFragmentShaderSource(): string;\n public abstract bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n public abstract updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n\n public render({ gl, shaderProgram, indexBuffer, mvMatrix, pMatrix }: {\n gl: WebGLRenderingContext;\n shaderProgram: WebGLProgram;\n indexBuffer: WebGLBuffer;\n mvMatrix: mat4;\n pMatrix: mat4;\n }) {\n gl.uniformMatrix4fv((shaderProgram as any).pMatrixUniform, false, pMatrix);\n gl.uniformMatrix4fv((shaderProgram as any).mvMatrixUniform, false, mvMatrix);\n\n if (indexBuffer) {\n gl.drawElements(gl.TRIANGLES, (indexBuffer as any).numItems, gl.UNSIGNED_SHORT, 0);\n }\n }\n\n // Define interface for Renderers\n /**\n * Following MUST BE DEFINED on Child of Renderer\n *\n * DATA\n *\n * - getVertexPositionData\n * - getIndexData\n * - getTextureCoordData\n *\n * SOURCE\n *\n * - getVertexShaderSource\n * - getFragmentShaderSource\n *\n * TEXTURE\n *\n * - bindTexture\n */\n public getDimension(pixelSource: HTMLImageElement | HTMLVideoElement) {\n const width = (pixelSource as HTMLImageElement).naturalWidth\n || (pixelSource as HTMLVideoElement).videoWidth;\n const height = (pixelSource as HTMLImageElement).naturalHeight\n || (pixelSource as HTMLVideoElement).videoHeight;\n\n return { width, height };\n }\n\n /**\n * Update data used by shader\n */\n public updateShaderData(param) { // eslint-disable-line @typescript-eslint/no-unused-vars\n /*\n * Update following data in implementation layer.\n * If the data is not changed, it does not need to implement this function.\n *\n * - _VERTEX_POSITION_DATA\n * - _TEXTURE_COORD_DATA\n * - _INDEX_DATA\n */\n }\n\n /**\n *\n * @param {HTMLImageElement | HTMLVideoElement} image\n * @param {Object = {width, height}} forceDimension Forced dimension to resize\n */\n protected _initPixelSource(image: HTMLImageElement | HTMLVideoElement, forceDimension: Renderer[\"_forceDimension\"] = null) {\n const isIE11Video = isIE11 && (image instanceof HTMLVideoElement);\n\n if (isIE11Video || forceDimension) {\n const {width, height} = forceDimension || this.getDimension(image);\n\n this._pixelCanvas = document.createElement(\"canvas\");\n this._pixelCanvas.width = width;\n this._pixelCanvas.height = height;\n this._pixelContext = this._pixelCanvas.getContext(\"2d\");\n }\n this._forceDimension = forceDimension;\n }\n\n protected _getPixelSource(image: HTMLImageElement | HTMLVideoElement) {\n if (!this._pixelCanvas) {\n return image;\n }\n\n /**\n * IE11 && Video\n * or\n * Dimension is forced (Image is larger than texture size.)\n */\n const contentDimension = this.getDimension(image);\n const textureDimension = this._forceDimension || contentDimension;\n\n if (this._pixelCanvas.width !== textureDimension.width) {\n this._pixelCanvas.width = textureDimension.width;\n }\n\n if (this._pixelCanvas.height !== textureDimension.height) {\n this._pixelCanvas.height = textureDimension.height;\n }\n\n if (this._forceDimension) {\n this._pixelContext!.drawImage(image,\n 0, 0, contentDimension.width, contentDimension.height,\n 0, 0, textureDimension.width, textureDimension.height);\n } else {\n this._pixelContext!.drawImage(image, 0, 0);\n }\n\n return this._pixelCanvas;\n }\n\n protected _extractTileConfig(imageConfig: CubemapConfig) {\n let tileConfig: TileConfig[] =\n Array.isArray(imageConfig.tileConfig) ?\n imageConfig.tileConfig : Array(...Array(6)).map(() => imageConfig.tileConfig) as TileConfig[];\n\n tileConfig = tileConfig.map(\n config => ({\n ...{\n flipHorizontal: false,\n rotation: 0\n }, ...config\n })\n );\n\n return tileConfig;\n }\n\n protected _triggerError(error) {\n /* eslint-disable no-console */\n console.error(\"Renderer Error:\", error);\n /* eslint-enable no-console */\n\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n message: typeof error === \"string\" ? error : error.message\n }));\n }\n}\n\nexport default Renderer;\n","import agent from \"@egjs/agent\";\n\nimport WebGLUtils from \"../WebGLUtils\";\nimport { util as mathUtil } from \"../../utils/math-util\";\nimport { CubemapConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nclass CubeRenderer extends Renderer {\n public static extractOrder(imageConfig: CubemapConfig) {\n return imageConfig.order || \"RLUDBF\";\n }\n\n private static _VERTEX_POSITION_DATA: number[] | null = null;\n private static _INDEX_DATA: number[] | null = null;\n\n public getVertexPositionData() {\n CubeRenderer._VERTEX_POSITION_DATA =\n CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // top\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // bottom\n 1, -1, -1,\n -1, -1, -1,\n -1, -1, 1,\n 1, -1, 1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n return CubeRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n if (CubeRenderer._INDEX_DATA) {\n return CubeRenderer._INDEX_DATA;\n }\n\n const indexData: number[] = [];\n const vertexPositionData = this.getVertexPositionData();\n\n for (let i = 0; i < (vertexPositionData.length / 3); i += 4) {\n indexData.push(\n i,\n i + 2,\n i + 1,\n i,\n i + 3,\n i + 2\n );\n }\n\n CubeRenderer._INDEX_DATA = indexData;\n return indexData;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n const vertexOrder = \"BFUDRL\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const base = this.getVertexPositionData();\n const tileConfig = this._extractTileConfig(imageConfig);\n const elemSize = 3;\n const vertexPerTile = 4;\n const { trim } = imageConfig;\n\n const texCoords = vertexOrder.split(\"\")\n .map(face => tileConfig[order.indexOf(face)])\n .map((config, i) => {\n const rotation = Math.floor(config.rotation / 90);\n const ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2];\n\n for (let r = 0; r < Math.abs(rotation); r++) {\n if ((config.flipHorizontal && rotation > 0) ||\n (!config.flipHorizontal && rotation < 0)) {\n ordermap.push(ordermap.shift()!);\n } else {\n ordermap.unshift(ordermap.pop()!);\n }\n }\n\n const elemPerTile = elemSize * vertexPerTile;\n const tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile);\n const tileTemp: number[][] = [];\n\n for (let j = 0; j < vertexPerTile; j++) {\n tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize);\n }\n return tileTemp;\n })\n .map(coord => this._shrinkCoord({ image, faceCoords: coord, trim }))\n .reduce((acc: number[], val: number[][]) => [\n ...acc,\n ...val.reduce((coords, coord) => [...coords, ...coord], [])\n ], []);\n\n return texCoords;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n const baseOrder = \"RLUDBF\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const orderMap = {};\n\n order.split(\"\").forEach((v, i) => {\n orderMap[v] = i;\n });\n\n try {\n if (image instanceof Array) {\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]);\n }\n } else {\n const maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image);\n\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n const tile = this.extractTileFromImage(\n image, tileIdx, maxCubeMapTextureSize\n );\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile);\n }\n }\n } catch (e) {\n this._triggerError(e);\n }\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n this.updateTexture(gl, image, imageConfig);\n }\n\n public getSourceTileSize(image: HTMLImageElement | HTMLVideoElement) {\n const {width, height} = this.getDimension(image);\n const aspectRatio = width / height;\n let inputTextureSize;\n\n if (aspectRatio === 1 / 6) {\n inputTextureSize = width;\n } else if (aspectRatio === 6) {\n inputTextureSize = height;\n } else if (aspectRatio === 2 / 3) {\n inputTextureSize = width / 2;\n } else {\n inputTextureSize = width / 3;\n }\n return inputTextureSize;\n }\n\n public extractTileFromImage(image: HTMLImageElement | HTMLVideoElement, tileIdx: number, outputTextureSize: number) {\n const {width} = this.getDimension(image);\n const inputTextureSize = this.getSourceTileSize(image);\n\n const canvas = document.createElement(\"canvas\");\n\n canvas.width = outputTextureSize;\n canvas.height = outputTextureSize;\n const context = canvas.getContext(\"2d\");\n const tilePerRow = width / inputTextureSize;\n\n const x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow);\n const y = Math.floor(tileIdx / tilePerRow) * (inputTextureSize);\n\n context!.drawImage(\n image, x, y,\n inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize\n );\n return canvas;\n }\n\n public getMaxCubeMapTextureSize(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n const agentInfo = agent();\n const maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n let imageWidth = this.getSourceTileSize(image);\n\n if (agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11) {\n if (!mathUtil.isPowerOfTwo(imageWidth)) {\n for (let i = 1; i < maxCubeMapTextureSize; i *= 2) {\n if (i < imageWidth) {\n continue;\n } else {\n imageWidth = i;\n break;\n }\n }\n }\n }\n if (agentInfo.os.name === \"ios\") {\n const majorVersion = agentInfo.os.majorVersion;\n\n // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다.\n if (majorVersion === 9) {\n imageWidth = 1024;\n }\n // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다.\n if (majorVersion === 8) {\n imageWidth = 512;\n }\n }\n // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수\n return Math.min(maxCubeMapTextureSize, imageWidth);\n }\n\n private _shrinkCoord(coordData: {\n image: HTMLImageElement | HTMLVideoElement;\n faceCoords: number[][];\n trim: number;\n }) {\n const { image, faceCoords, trim } = coordData;\n\n const inputTextureSize = Array.isArray(image)\n ? this.getDimension(image[0]).width\n : this.getSourceTileSize(image);\n\n // Shrink by \"trim\" px\n const SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize);\n\n const axisMultipliers = [0, 1, 2].map(axisIndex => {\n const axisDir = mathUtil.sign(faceCoords[0][axisIndex]);\n const notSameDir = faceCoords.some(coord => mathUtil.sign(coord[axisIndex]) !== axisDir);\n\n return notSameDir;\n }).map(notSameDir => notSameDir ? SHRINK_MULTIPLIER : 1);\n\n return faceCoords.map(coords => coords.map((coord, axisIndex) => coord * axisMultipliers[axisIndex]));\n }\n}\n\nexport default CubeRenderer;\n","\nimport WebGLUtils from \"../WebGLUtils\";\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nexport default class CubeStripRenderer extends Renderer {\n private _vertices: number[];\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}`;\n }\n\n public getVertexPositionData() {\n if (!this._vertices) {\n this._vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n }\n\n return this._vertices;\n }\n\n public getIndexData() {\n // TODO: 한번만 계산하도록 수정하기\n const indices = (() => {\n const indexData: number[] = [];\n\n for (let i = 0; i < (this._vertices.length / 3); i += 4) {\n indexData.push(\n i,\n i + 1,\n i + 2,\n i,\n i + 2,\n i + 3\n );\n }\n return indexData;\n })();\n\n return indices;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n // TODO: make it cols, rows as config.\n const cols = 3;\n const rows = 2;\n\n const textureSize = this.getDimension(image);\n const { trim } = imageConfig;\n\n const order = imageConfig.order || \"RLUDFB\";\n let coords: number[][] = [];\n\n // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다.\n for (let r = rows - 1; r >= 0; r--) {\n for (let c = 0; c < cols; c++) {\n const coord = [\n c / cols, r / rows,\n (c + 1) / cols, r / rows,\n (c + 1) / cols, (r + 1) / rows,\n c / cols, (r + 1) / rows\n ];\n\n coords.push(coord);\n }\n }\n\n const tileConfigs = this._extractTileConfig(imageConfig);\n\n // Transform Coord By Flip & Rotation\n coords = coords\n // shrink coord to avoid pixel bleeding\n .map(coord => this._shrinkCoord(coord, textureSize, trim))\n .map((coord, i) => this._transformCoord(coord, tileConfigs[i]));\n\n // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치\n return \"BFUDRL\".split(\"\")\n .map(face => order.indexOf(face))\n .map(index => coords[index])\n .reduce((acc, val) => acc.concat(val), []);\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n private _transformCoord(coord: number[], tileConfig: TileConfig) {\n let newCoord = coord.slice();\n\n if (tileConfig.flipHorizontal) {\n newCoord = this._flipHorizontalCoord(newCoord);\n }\n\n if (tileConfig.rotation) {\n newCoord = this._rotateCoord(newCoord, tileConfig.rotation);\n }\n\n return newCoord;\n }\n\n private _shrinkCoord(coord: number[], textureSize: { width: number; height: number }, trim: number) {\n const { width, height } = textureSize;\n\n // Shrink by \"trim\" px\n const SHRINK_Y = trim * (1 / height);\n const SHRINK_X = trim * (1 / width);\n\n return [\n coord[0] + SHRINK_X, coord[1] + SHRINK_Y,\n coord[2] - SHRINK_X, coord[3] + SHRINK_Y,\n coord[4] - SHRINK_X, coord[5] - SHRINK_Y,\n coord[6] + SHRINK_X, coord[7] - SHRINK_Y\n ];\n }\n\n private _rotateCoord(coord: number[], rotationAngle: number) {\n const SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord.\n const shiftCount = Math.floor(rotationAngle / 90) % 4;\n\n if (shiftCount === 0) {\n return coord;\n }\n\n let moved;\n let rotatedCoord: number[] = [];\n\n if (shiftCount > 0) {\n moved = coord.splice(0, shiftCount * SIZE);\n rotatedCoord = coord.concat(moved);\n } else {\n moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE);\n rotatedCoord = moved.concat(coord);\n }\n\n return rotatedCoord;\n }\n\n private _flipHorizontalCoord(coord: number[]) {\n return [\n coord[2], coord[3],\n coord[0], coord[1],\n coord[6], coord[7],\n coord[4], coord[5]\n ];\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport WebGLUtils from \"../WebGLUtils\";\n\nimport Renderer from \"./Renderer\";\n\n// const latitudeBands = 60;\nconst MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6;\nconst longitudeBands = 60;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\n\nclass CylinderRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n public getVertexPositionData() {\n return CylinderRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return CylinderRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return CylinderRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n let resizeDimension: { width: number; height: number } | undefined;\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device texture limit(${maxSize}))`);\n\n // Request resizing texture.\n /**\n * TODO: Is it need to apply on another projection type?\n */\n resizeDimension = width > height ?\n {width: maxSize, height: maxSize * height / width} :\n {width: maxSize * width / height, height: maxSize};\n }\n\n // Pixel Source for IE11 & Video or resizing needed\n this._initPixelSource(image, resizeDimension);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n public updateShaderData({ imageAspectRatio = MIN_ASPECT_RATIO_FOR_FULL_PANORAMA }) {\n let lngIdx: number;\n let cylinderMaxRadian: number;\n let halfCylinderY: number;\n let rotated: boolean;\n let aspectRatio: number;\n\n // Exception case: orientation is rotated.\n if (imageAspectRatio < 1) {\n /**\n * If rotated is true, we assume that image is rotated counter clockwise.\n * TODO: If there's other rotation, it is need to implement by each rotation.\n */\n rotated = true;\n aspectRatio = 1 / imageAspectRatio;\n } else {\n rotated = false;\n aspectRatio = imageAspectRatio;\n }\n\n if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) {\n const fov = 360 / aspectRatio;\n\n cylinderMaxRadian = 2 * Math.PI; // 360 deg\n halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2));\n } else {\n cylinderMaxRadian = aspectRatio;\n halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1.\n }\n\n // initialize shader data before update\n textureCoordData.length = 0;\n vertexPositionData.length = 0;\n indexData.length = 0;\n\n const CYLIDER_Y = [-halfCylinderY, halfCylinderY];\n const startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360)\n\n // console.log(\"cylinderMaxRadian:\", glMatrix.toDegree(cylinderMaxRadian), \"CYLIDER_Y\", CYLIDER_Y, \"start angle\", glMatrix.toDegree(startAngleForCenterAlign));\n for (let yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength/* bottom & top */; yIdx++) {\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const angle = startAngleForCenterAlign + (lngIdx / longitudeBands * cylinderMaxRadian);\n const x = Math.cos(angle);\n const y = CYLIDER_Y[yIdx];\n const z = Math.sin(angle);\n let u: number;\n let v: number;\n\n if (rotated) {\n // Rotated 90 degree (counter clock wise)\n u = 1 - yIdx; // yLength - yIdx;\n v = lngIdx / longitudeBands;\n } else {\n // \t// Normal case (Not rotated)\n u = lngIdx / longitudeBands;\n v = yIdx;\n }\n\n textureCoordData.push(u, v);\n vertexPositionData.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < longitudeBands) {\n const a = lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n }\n}\n\nexport default CylinderRenderer;\n","import Promise from \"promise-polyfill\";\nimport { mat4 } from \"gl-matrix\";\n\nconst VR_DISPLAY_PRESENT_CHANGE = \"vrdisplaypresentchange\";\nconst DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1];\nconst DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1];\nconst EYES = {\n LEFT: \"left\",\n RIGHT: \"right\"\n} as const;\n\nclass VRManager {\n private _vrDisplay: VRDisplay | null;\n private _frameData: VRFrameData;\n private _yawOffset: number;\n private _leftBounds: number[];\n private _rightBounds: number[];\n\n public constructor() {\n this._frameData = new window.VRFrameData();\n this._clear();\n }\n\n public get context() { return this._vrDisplay; }\n\n public destroy = () => {\n const vrDisplay = this._vrDisplay;\n\n this.removeEndCallback(this.destroy);\n\n if (vrDisplay && vrDisplay.isPresenting) {\n void vrDisplay.exitPresent();\n }\n\n this._clear();\n };\n\n public canRender() {\n return Boolean(this._vrDisplay);\n }\n\n public beforeRender(gl: WebGLRenderingContext) {\n // Render to the default backbuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public afterRender() {\n this._vrDisplay!.submitFrame();\n }\n\n public getEyeParams(gl: WebGLRenderingContext) {\n const display = this._vrDisplay!;\n const halfWidth = gl.drawingBufferWidth * 0.5;\n const height = gl.drawingBufferHeight;\n const frameData = this._frameData;\n\n display.getFrameData(frameData);\n\n const leftMVMatrix = frameData.leftViewMatrix;\n const rightMVMatrix = frameData.rightViewMatrix;\n\n mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset);\n mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset);\n\n return [\n {\n viewport: [0, 0, halfWidth, height],\n mvMatrix: leftMVMatrix,\n pMatrix: frameData.leftProjectionMatrix\n },\n {\n viewport: [halfWidth, 0, halfWidth, height],\n mvMatrix: rightMVMatrix,\n pMatrix: frameData.rightProjectionMatrix\n }\n ];\n }\n\n public isPresenting() {\n return Boolean(this._vrDisplay && this._vrDisplay.isPresenting);\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public requestPresent(canvas: HTMLCanvasElement) {\n return navigator.getVRDisplays().then(displays => {\n const vrDisplay = displays.length && displays[0];\n\n if (!vrDisplay) {\n return Promise.reject(new Error(\"No displays available.\"));\n }\n if (!vrDisplay.capabilities.canPresent) {\n return Promise.reject(new Error(\"Display lacking capability to present.\"));\n }\n\n return vrDisplay.requestPresent([{source: canvas}]).then(() => {\n const leftEye = vrDisplay.getEyeParameters(EYES.LEFT);\n const rightEye = vrDisplay.getEyeParameters(EYES.RIGHT);\n\n canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;\n canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);\n\n this._setDisplay(vrDisplay);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setDisplay(vrDisplay: VRDisplay) {\n this._vrDisplay = vrDisplay;\n\n const layers = vrDisplay.getLayers();\n\n if (layers.length) {\n const layer = layers[0];\n\n this._leftBounds = layer.leftBounds as number[];\n this._rightBounds = layer.rightBounds as number[];\n }\n\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._vrDisplay = null;\n this._leftBounds = DEFAULT_LEFT_BOUNDS;\n this._rightBounds = DEFAULT_RIGHT_BOUNDS;\n this._yawOffset = 0;\n }\n}\n\nexport default VRManager;\n","import { mat4, glMatrix } from \"gl-matrix\";\nimport { XRFrame, XRLayer, XRReferenceSpace, XRSession, XRSessionInit } from \"webxr\";\n\nimport { IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { merge } from \"../../utils/utils\";\n\nconst XR_REFERENCE_SPACE = \"local\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\nclass XRManager {\n private _xrSession: XRSession | null;\n private _xrLayer: XRLayer | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n private _yawOffset: number;\n private _presenting: boolean;\n\n public constructor(options: XRSessionOptions = {}) {\n this._clear();\n this._options = options;\n }\n\n public get context() { return this._xrSession; }\n\n public destroy = () => {\n const xrSession = this._xrSession;\n\n this.removeEndCallback(this.destroy);\n\n if (xrSession) {\n // Capture to avoid errors\n xrSession.end().then(() => void 0, () => void 0);\n }\n this._clear();\n };\n\n public canRender(frame: XRFrame) {\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n return Boolean(pose);\n }\n\n public beforeRender(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer!.framebuffer);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n public afterRender() {}\n\n public getEyeParams(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) {\n // Can't render\n return null;\n }\n\n const glLayer = session.renderState.baseLayer;\n\n return pose.views.map(view => {\n const viewport = glLayer!.getViewport(view);\n const mvMatrix = view.transform.inverse.matrix;\n\n if (IS_SAFARI_ON_DESKTOP) {\n mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180));\n }\n\n mat4.rotateY(mvMatrix, mvMatrix, this._yawOffset);\n\n return {\n viewport: [viewport.x, viewport.y, viewport.width, viewport.height],\n mvMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n public isPresenting() {\n return this._presenting;\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.addEventListener(\"end\", callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.removeEventListener(\"end\", callback);\n }\n\n public async requestPresent(canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {\n const options = merge({\n requiredFeatures: [XR_REFERENCE_SPACE]\n }, this._options);\n\n const attributes = gl.getContextAttributes();\n if (attributes && (attributes as any).xrCompatible !== true) {\n await (gl as any).makeXRCompatible();\n }\n\n return (navigator as any).xr.requestSession(\"immersive-vr\", options).then(session => {\n const xrLayer = new (window as any).XRWebGLLayer(session, gl);\n\n session.updateRenderState({baseLayer: xrLayer});\n return session.requestReferenceSpace(XR_REFERENCE_SPACE)\n .then(refSpace => {\n this._setSession(session, xrLayer, refSpace);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setSession(session: XRSession, xrLayer: XRLayer, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrLayer = xrLayer;\n this._xrRefSpace = refSpace;\n this._presenting = true;\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._xrSession = null;\n this._xrLayer = null;\n this._xrRefSpace = null;\n this._presenting = false;\n this._yawOffset = 0;\n this._options = {};\n }\n}\n\nexport default XRManager;\n","import { IS_SAFARI_ON_DESKTOP } from \"../utils/browser\";\n\nclass WebGLAnimator {\n private _callback: ((...args: any[]) => any) | null;\n private _context: any;\n private _rafId: number;\n private _rafTimer: number;\n\n public constructor() {\n this._callback = null;\n this._context = window;\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public setCallback(callback: (...args: any[]) => any) {\n this._callback = callback;\n }\n\n public setContext(context: any) {\n this._context = context;\n }\n\n public start() {\n const context = this._context;\n const callback = this._callback;\n\n // No context / callback set\n if (!context || !callback) return;\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n if (IS_SAFARI_ON_DESKTOP) {\n this._rafId = context.requestAnimationFrame(this._onLoopNextTick);\n } else {\n this._rafId = context.requestAnimationFrame(this._onLoop);\n }\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n /**\n * There can be more than 1 argument when we use XRSession's raf\n */\n private _onLoop = (...args: any[]) => {\n this._callback!(...args);\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n };\n\n /**\n * MacOS X Safari Bug Fix\n * This code guarantees that rendering should be occurred.\n *\n * In MacOS X(10.14.2), Safari (12.0.2)\n * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term\n * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms)\n * So browser cannot render the frame and may be freezing.\n */\n private _onLoopNextTick = (...args: any[]) => {\n const before = performance.now();\n\n this._callback!(...args);\n\n const diff = performance.now() - before;\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n this._rafTimer = -1;\n }\n\n /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */\n if (diff < 16) {\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n } else {\n /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */\n this._rafTimer = window.setTimeout(this._onLoop, 0);\n }\n };\n}\n\nexport default WebGLAnimator;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { XRFrame } from \"webxr\";\nimport Promise from \"promise-polyfill\";\nimport { glMatrix, vec3, mat3, mat4, quat } from \"gl-matrix\";\nimport ImReady, { OnReady } from \"@egjs/imready\";\n\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { devicePixelRatio, WEBXR_SUPPORTED } from \"../utils/browserFeature\";\nimport { PROJECTION_TYPE, STEREO_FORMAT } from \"../PanoViewer/consts\";\nimport { IS_IOS } from \"../utils/browser\";\nimport { CubemapConfig, ImageCandidate, ValueOf, VideoCandidate } from \"../types/internal\";\nimport YawPitchControl from \"../YawPitchControl/YawPitchControl\";\nimport { toImageElement, toVideoElement } from \"../utils/utils\";\n\nimport WebGLUtils from \"./WebGLUtils\";\nimport Renderer from \"./renderer/Renderer\";\nimport CubeRenderer from \"./renderer/CubeRenderer\";\nimport CubeStripRenderer from \"./renderer/CubeStripRenderer\";\nimport SphereRenderer from \"./renderer/SphereRenderer\";\nimport CylinderRenderer from \"./renderer/CylinderRenderer\";\nimport VRManager from \"./vr/VRManager\";\nimport XRManager from \"./vr/XRManager\";\nimport WebGLAnimator from \"./WebGLAnimator\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ImageType = PROJECTION_TYPE;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet DEVICE_PIXEL_RATIO = devicePixelRatio || 1;\n\n// DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다.\nif (DEVICE_PIXEL_RATIO > 2) {\n DEVICE_PIXEL_RATIO = 2;\n}\n\n// define custom events name\n/**\n * TODO: how to manage events/errortype with PanoViewer\n *\n * I think renderer events should be seperated from viewer events although it has same name.\n */\nconst EVENTS: {\n BIND_TEXTURE: \"bindTexture\";\n IMAGE_LOADED: \"imageLoaded\";\n ERROR: \"error\";\n RENDERING_CONTEXT_LOST: \"renderingContextLost\";\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\";\n} = {\n BIND_TEXTURE: \"bindTexture\",\n IMAGE_LOADED: \"imageLoaded\",\n ERROR: \"error\",\n RENDERING_CONTEXT_LOST: \"renderingContextLost\",\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\"\n};\n\nconst ERROR_TYPE = {\n INVALID_DEVICE: 10,\n NO_WEBGL: 11,\n FAIL_IMAGE_LOAD: 12,\n RENDERER_ERROR: 13\n};\n\nclass PanoImageRenderer extends Component<{\n [EVENTS.ERROR]: {\n type: number;\n message: string;\n };\n [EVENTS.IMAGE_LOADED]: {\n content: HTMLElement;\n isVideo: boolean;\n projectionType: ValueOf;\n };\n [EVENTS.BIND_TEXTURE]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_LOST]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_RESTORE]: ComponentEvent;\n}> {\n public static EVENTS = EVENTS;\n public static ERROR_TYPE = ERROR_TYPE;\n\n public sphericalConfig: {\n initialYaw: number;\n initialPitch: number;\n fieldOfView: number;\n imageType: ValueOf;\n stereoFormat: ValueOf;\n cubemapConfig: Partial;\n };\n\n public fieldOfView: number;\n public width: number;\n public height: number;\n\n public canvas: HTMLCanvasElement;\n public context: WebGLRenderingContext;\n public shaderProgram: WebGLProgram | null;\n public texture: WebGLTexture;\n\n public pMatrix: mat4;\n public mvMatrix: mat4;\n\n public textureCoordBuffer: WebGLBuffer | null = null;\n public vertexBuffer: WebGLBuffer | null = null;\n public indexBuffer: WebGLBuffer | null = null;\n\n private _wrapper: HTMLElement | null;\n private _wrapperOrigStyle: string | null;\n private _lastQuaternion: quat | null;\n private _lastYaw: number | null;\n private _lastPitch: number | null;\n private _lastFieldOfView: number | null;\n private _renderingContextAttributes?: WebGLContextAttributes;\n\n private _renderer: Renderer;\n private _contentLoader: ImReady | null;\n private _image: HTMLImageElement | HTMLImageElement[] | HTMLVideoElement | null;\n private _imageConfig: CubemapConfig | null;\n private _imageType: ValueOf;\n private _imageIsReady: boolean;\n private _isVideo: boolean;\n private _isCubeMap: boolean;\n private _shouldForceDraw: boolean;\n private _keepUpdate: boolean;\n private _hasExternalCanvas: boolean;\n\n private _yawPitchControl: YawPitchControl;\n private _animator: WebGLAnimator;\n private _vr: VRManager | XRManager | null;\n\n public constructor(\n image: ImageCandidate | VideoCandidate,\n width: number,\n height: number,\n isVideo: boolean,\n container: HTMLElement,\n canvasClass: string,\n sphericalConfig: PanoImageRenderer[\"sphericalConfig\"],\n renderingContextAttributes?: WebGLContextAttributes\n ) {\n // Super constructor\n super();\n\n this.sphericalConfig = sphericalConfig;\n this.fieldOfView = sphericalConfig.fieldOfView;\n\n this.width = width;\n this.height = height;\n\n this._lastQuaternion = null;\n this._lastYaw = null;\n this._lastPitch = null;\n this._lastFieldOfView = null;\n\n this.pMatrix = mat4.create();\n this.mvMatrix = mat4.create();\n\n // initialzie pMatrix\n mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), width / height, 0.1, 100);\n\n this.textureCoordBuffer = null;\n this.vertexBuffer = null;\n this.indexBuffer = null;\n\n this.canvas = this._initCanvas(container, canvasClass, width, height);\n\n this._setDefaultCanvasStyle();\n this._wrapper = null; // canvas wrapper\n this._wrapperOrigStyle = null;\n\n this._renderingContextAttributes = renderingContextAttributes;\n this._image = null;\n this._imageConfig = null;\n this._imageIsReady = false;\n this._shouldForceDraw = false;\n this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still.\n\n this._onContentLoad = this._onContentLoad.bind(this);\n this._onContentError = \tthis._onContentError.bind(this);\n\n this._animator = new WebGLAnimator();\n\n // VR/XR manager\n this._vr = null;\n\n if (image) {\n this.setImage({\n image,\n imageType: sphericalConfig.imageType,\n isVideo,\n cubemapConfig: sphericalConfig.cubemapConfig\n });\n }\n }\n\n // FIXME: Please refactor me to have more loose connection to yawpitchcontrol\n public setYawPitchControl(yawPitchControl: YawPitchControl) {\n this._yawPitchControl = yawPitchControl;\n }\n\n public getContent() {\n return this._image;\n }\n\n public setImage({\n image,\n imageType,\n isVideo = false,\n cubemapConfig\n }: {\n image: ImageCandidate | VideoCandidate;\n imageType: PanoImageRenderer[\"_imageType\"];\n isVideo: boolean;\n cubemapConfig: Partial;\n }) {\n this._imageIsReady = false;\n this._isVideo = isVideo;\n this._imageConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only */\n order: (imageType === ImageType.CUBEMAP) ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n },\n ...cubemapConfig\n };\n this._setImageType(imageType);\n\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._contentLoader = new ImReady()\n .on(\"ready\", this._onContentLoad)\n .on(\"error\", this._onContentError);\n\n if (isVideo) {\n this._image = toVideoElement(image as VideoCandidate);\n this._contentLoader.check([this._image]);\n this._keepUpdate = true;\n } else {\n this._image = toImageElement(image as ImageCandidate);\n this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n this._keepUpdate = false;\n }\n }\n\n public isImageLoaded() {\n return !!this._image && this._imageIsReady &&\n (!this._isVideo || (this._image as HTMLVideoElement).readyState >= 2 /* HAVE_CURRENT_DATA */);\n }\n\n public bindTexture() {\n return new Promise((res, rej) => {\n const contentLoader = this._contentLoader;\n\n if (!this._image) {\n return rej(\"Image is not defined\");\n }\n\n if (!contentLoader) {\n return rej(\"ImageLoader is not initialized\");\n }\n\n if (contentLoader.isReady()) {\n this._bindTexture();\n res();\n } else {\n contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n contentLoader.once(\"ready\", e => {\n if (e.errorCount > 0) {\n rej(\"Failed to load images.\");\n } else {\n this._bindTexture();\n res();\n }\n });\n }\n });\n }\n\n // 부모 엘리먼트에 canvas 를 붙임\n public attachTo(parentElement) {\n if (!this._hasExternalCanvas) {\n this.detach();\n parentElement.appendChild(this.canvas);\n }\n this._wrapper = parentElement;\n }\n\n public forceContextLoss() {\n if (this.hasRenderingContext()) {\n const loseContextExtension = this.context.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n\n // 부모 엘리먼트에서 canvas 를 제거\n public detach() {\n if (!this._hasExternalCanvas && this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n\n public destroy() {\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._animator.stop();\n this.detach();\n this.forceContextLoss();\n\n this.off();\n\n this.canvas.removeEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n this.canvas.removeEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n }\n\n public hasRenderingContext() {\n const ctx = this.context;\n if (\n !ctx\n || ctx.isContextLost()\n || !ctx.getProgramParameter(this.shaderProgram!, ctx.LINK_STATUS)) {\n return false;\n }\n return true;\n }\n\n public updateFieldOfView(fieldOfView) {\n this.fieldOfView = fieldOfView;\n this._updateViewport();\n }\n\n public updateViewportDimensions(width, height) {\n let viewPortChanged = false;\n\n this.width = width;\n this.height = height;\n\n const w = width * DEVICE_PIXEL_RATIO;\n const h = height * DEVICE_PIXEL_RATIO;\n\n if (w !== this.canvas.width) {\n this.canvas.width = w;\n viewPortChanged = true;\n }\n\n if (h !== this.canvas.height) {\n this.canvas.height = h;\n viewPortChanged = true;\n }\n\n if (!viewPortChanged) {\n return;\n }\n\n this._updateViewport();\n this._shouldForceDraw = true;\n }\n\n public keepUpdate(doUpdate) {\n if (doUpdate && this.isImageLoaded() === false) {\n // Force to draw a frame after image is loaded on render()\n this._shouldForceDraw = true;\n }\n\n this._keepUpdate = doUpdate;\n }\n\n public startRender() {\n this._animator.setCallback(this._render.bind(this));\n this._animator.start();\n }\n\n public stopRender() {\n this._animator.stop();\n }\n\n public renderWithQuaternion(quaternion, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // updatefieldOfView only if fieldOfView is changed.\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion);\n\n this._draw();\n\n this._lastQuaternion = quat.clone(quaternion);\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n public renderWithYawPitch(yaw, pitch, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastYaw !== null && this._lastYaw === yaw &&\n this._lastPitch !== null && this._lastPitch === pitch &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n mat4.identity(this.mvMatrix);\n mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch));\n mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw));\n\n this._draw();\n\n this._lastYaw = yaw;\n this._lastPitch = pitch;\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n /**\n * Returns projection renderer by each type\n */\n public getProjectionRenderer() {\n return this._renderer;\n }\n\n /**\n * @return Promise\n */\n public enterVR(options) {\n const vr = this._vr;\n\n if (!WEBXR_SUPPORTED && !(navigator as any).getVRDisplays) {\n return Promise.reject(\"VR is not available on this browser.\");\n }\n if (vr && vr.isPresenting()) {\n return Promise.resolve(\"VR already enabled.\");\n }\n\n return this._requestPresent(options);\n }\n\n public exitVR = () => {\n const vr = this._vr;\n const gl = this.context;\n const animator = this._animator;\n\n if (!vr) return;\n\n vr.removeEndCallback(this.exitVR);\n vr.destroy();\n this._vr = null;\n\n // Restore canvas & context on iOS\n if (IS_IOS) {\n this._restoreStyle();\n }\n this.updateViewportDimensions(this.width, this.height);\n this._updateViewport();\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._bindBuffers();\n this._shouldForceDraw = true;\n\n animator.stop();\n animator.setContext(window);\n animator.setCallback(this._render.bind(this));\n animator.start();\n };\n\n private _setImageType(imageType) {\n if (!imageType || this._imageType === imageType) {\n return;\n }\n\n this._imageType = imageType;\n this._isCubeMap = imageType === ImageType.CUBEMAP;\n\n if (this._renderer) {\n this._renderer.off();\n }\n\n switch (imageType) {\n case ImageType.CUBEMAP:\n this._renderer = new CubeRenderer();\n break;\n case ImageType.CUBESTRIP:\n this._renderer = new CubeStripRenderer();\n break;\n case ImageType.PANORAMA:\n this._renderer = new CylinderRenderer();\n break;\n case ImageType.STEREOSCOPIC_EQUI:\n this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat);\n break;\n default:\n this._renderer = new SphereRenderer(STEREO_FORMAT.NONE);\n break;\n }\n\n this._renderer.on(Renderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERER_ERROR,\n message: e.message\n }));\n });\n\n this._initWebGL();\n }\n\n private _initCanvas(container: HTMLElement, canvasClass: string, width: number, height: number) {\n const canvasInContainer = container.querySelector(`.${canvasClass}`);\n const canvas = canvasInContainer || this._createCanvas(canvasClass);\n\n this._hasExternalCanvas = !!canvasInContainer;\n\n canvas.width = width;\n canvas.height = height;\n\n this._onWebglcontextlost = this._onWebglcontextlost.bind(this);\n this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this);\n\n canvas.addEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n canvas.addEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n\n return canvas;\n }\n\n private _createCanvas(className: string) {\n const canvas = document.createElement(\"canvas\");\n\n canvas.className = className;\n\n return canvas;\n }\n\n private _setDefaultCanvasStyle() {\n const canvas = this.canvas;\n\n canvas.style.bottom = \"0\";\n canvas.style.left = \"0\";\n canvas.style.right = \"0\";\n canvas.style.top = \"0\";\n canvas.style.margin = \"auto\";\n canvas.style.maxHeight = \"100%\";\n canvas.style.maxWidth = \"100%\";\n canvas.style.outline = \"none\";\n canvas.style.position = \"absolute\";\n }\n\n private _onContentError() {\n this._imageIsReady = false;\n this._image = null;\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_IMAGE_LOAD,\n message: \"failed to load image\"\n }));\n\n return false;\n }\n\n private _triggerContentLoad() {\n this.trigger(new ComponentEvent(EVENTS.IMAGE_LOADED, {\n content: this._image as HTMLElement,\n isVideo: this._isVideo,\n projectionType: this._imageType\n }));\n }\n\n private _onContentLoad(e: OnReady) {\n if (e.errorCount > 0) return;\n\n this._imageIsReady = true;\n\n this._triggerContentLoad();\n }\n\n private _initShaderProgram() {\n const gl = this.context;\n\n if (this.shaderProgram) {\n gl.deleteProgram(this.shaderProgram);\n this.shaderProgram = null;\n }\n\n const renderer = this._renderer;\n\n const vsSource = renderer.getVertexShaderSource();\n const fsSource = renderer.getFragmentShaderSource();\n\n const vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource)!;\n const fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource)!;\n\n const shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader);\n\n if (!shaderProgram) {\n throw new Error(`Failed to initialize shaders: ${WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())}`);\n }\n\n gl.useProgram(shaderProgram);\n (shaderProgram as any).vertexPositionAttribute = gl.getAttribLocation(shaderProgram, \"aVertexPosition\");\n (shaderProgram as any).pMatrixUniform = gl.getUniformLocation(shaderProgram, \"uPMatrix\");\n (shaderProgram as any).mvMatrixUniform = gl.getUniformLocation(shaderProgram, \"uMVMatrix\");\n (shaderProgram as any).samplerUniform = gl.getUniformLocation(shaderProgram, \"uSampler\");\n (shaderProgram as any).textureCoordAttribute = gl.getAttribLocation(shaderProgram, \"aTextureCoord\");\n (shaderProgram as any).uEye = gl.getUniformLocation(shaderProgram, \"uEye\");\n\n gl.enableVertexAttribArray((shaderProgram as any).vertexPositionAttribute);\n gl.enableVertexAttribArray((shaderProgram as any).textureCoordAttribute);\n\n // clear buffer\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\n // Use TEXTURE0\n gl.uniform1i((shaderProgram as any).samplerUniform, 0);\n\n this.shaderProgram = shaderProgram;\n }\n\n private _onWebglcontextlost(e) {\n e.preventDefault();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_LOST));\n }\n\n private _onWebglcontextrestored() {\n this._initWebGL();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_RESTORE));\n }\n\n private _updateViewport() {\n mat4.perspective(\n this.pMatrix,\n glMatrix.toRadian(this.fieldOfView),\n this.canvas.width / this.canvas.height,\n 0.1,\n 100);\n\n this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight);\n }\n\n private _initWebGL() {\n let gl: WebGLRenderingContext;\n\n // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed.\n try {\n this._initRenderingContext();\n gl = this.context;\n\n this.updateViewportDimensions(this.width, this.height);\n this._initShaderProgram();\n } catch (e) {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n this.destroy();\n console.error(e); // eslint-disable-line no-console\n return;\n }\n // 캔버스를 투명으로 채운다.\n gl.clearColor(0, 0, 0, 0);\n const textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\n\n if (this.texture) {\n gl.deleteTexture(this.texture);\n }\n\n this.texture = WebGLUtils.createTexture(gl, textureTarget)!;\n\n if (this._imageType === ImageType.CUBESTRIP) {\n // TODO: Apply following options on other projection type.\n gl.enable(gl.CULL_FACE);\n // gl.enable(gl.DEPTH_TEST);\n }\n }\n\n private _initRenderingContext() {\n if (this.hasRenderingContext()) {\n return;\n }\n\n if (!window.WebGLRenderingContext) {\n throw new Error(\"WebGLRenderingContext not available.\");\n }\n\n this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes)!;\n\n if (!this.context) {\n throw new Error(\"Failed to acquire 3D rendering context\");\n }\n }\n\n private _initBuffers() {\n const image = this._image as HTMLImageElement | HTMLVideoElement;\n\n const vertexPositionData = this._renderer.getVertexPositionData();\n const indexData = this._renderer.getIndexData();\n const textureCoordData = this._renderer.getTextureCoordData({\n image,\n imageConfig: this._imageConfig!\n });\n const gl = this.context;\n\n this.vertexBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3,\n (this.shaderProgram as any).vertexPositionAttribute);\n\n this.indexBuffer = WebGLUtils.initBuffer(\n gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1);\n\n this.textureCoordBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2,\n (this.shaderProgram as any).textureCoordAttribute);\n\n this._bindBuffers();\n }\n\n private _bindTexture() {\n // Detect if it is EAC Format while CUBESTRIP mode.\n // We assume it is EAC if image is not 3/2 ratio.\n if (this._imageType === ImageType.CUBESTRIP) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const isEAC = width && height && width / height !== 1.5 ? 1 : 0;\n\n this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram!, \"uIsEAC\"), isEAC);\n } else if (this._imageType === ImageType.PANORAMA) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const imageAspectRatio = width && height && width / height;\n\n this._renderer.updateShaderData({imageAspectRatio});\n }\n\n // initialize shader buffers after image is loaded.(by updateShaderData)\n // because buffer may be differ by image size.(eg. CylinderRenderer)\n this._initBuffers();\n\n this._renderer.bindTexture(\n this.context,\n this.texture,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n this._shouldForceDraw = true;\n\n this.trigger(new ComponentEvent(EVENTS.BIND_TEXTURE));\n }\n\n private _updateTexture() {\n this._renderer.updateTexture(\n this.context,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n }\n\n private _render() {\n const yawPitchControl = this._yawPitchControl;\n const fov = yawPitchControl.getFov();\n\n if (yawPitchControl.shouldRenderWithQuaternion()) {\n const quaternion = yawPitchControl.getQuaternion();\n\n this.renderWithQuaternion(quaternion, fov);\n } else {\n const yawPitch = yawPitchControl.getYawPitch();\n\n this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov);\n }\n }\n\n private _renderStereo = (time: number, frame: XRFrame) => {\n const vr = this._vr;\n const gl = this.context;\n\n const eyeParams = vr!.getEyeParams(gl, frame);\n\n if (!eyeParams) return;\n\n vr!.beforeRender(gl, frame);\n\n // Render both eyes\n for (const eyeIndex of [0, 1]) {\n const eyeParam = eyeParams[eyeIndex];\n\n this.mvMatrix = eyeParam.mvMatrix;\n this.pMatrix = eyeParam.pMatrix;\n\n gl.viewport(...eyeParam.viewport as [number, number, number, number]);\n gl.uniform1f((this.shaderProgram as any).uEye, eyeIndex);\n\n this._bindBuffers();\n this._draw();\n }\n\n vr!.afterRender();\n };\n\n private _bindBuffers() {\n const gl = this.context;\n const program = this.shaderProgram;\n\n const vertexBuffer = this.vertexBuffer;\n const textureCoordBuffer = this.textureCoordBuffer;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray((program as any).vertexPositionAttribute);\n gl.vertexAttribPointer(\n (program as any).vertexPositionAttribute, (vertexBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);\n gl.enableVertexAttribArray((program as any).textureCoordAttribute);\n gl.vertexAttribPointer(\n (program as any).textureCoordAttribute, (textureCoordBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n }\n\n private _draw() {\n if (this._isVideo && this._keepUpdate) {\n this._updateTexture();\n }\n\n this._renderer.render({\n gl: this.context,\n shaderProgram: this.shaderProgram!,\n indexBuffer: this.indexBuffer!,\n mvMatrix: this.mvMatrix,\n pMatrix: this.pMatrix\n });\n }\n\n private _requestPresent(options) {\n const gl = this.context;\n const canvas = this.canvas;\n const animator = this._animator;\n\n this._vr = WEBXR_SUPPORTED ?\n new XRManager(options) :\n new VRManager();\n\n const vr = this._vr;\n\n animator.stop();\n return new Promise((resolve, reject) => {\n vr.requestPresent(canvas, gl)\n .then(() => {\n vr.addEndCallback(this.exitVR);\n animator.setContext(vr.context);\n animator.setCallback(this._onFirstVRFrame);\n\n if (IS_IOS) {\n this._setWrapperFullscreen();\n }\n\n this._shouldForceDraw = true;\n animator.start();\n\n resolve(\"success\");\n })\n .catch(e => {\n vr.destroy();\n this._vr = null;\n animator.start();\n\n reject(e);\n });\n });\n }\n\n private _onFirstVRFrame = (time, frame) => {\n const vr = this._vr!;\n const gl = this.context;\n const animator = this._animator;\n\n // If rendering is not ready, wait for next frame\n if (!vr.canRender(frame)) return;\n\n const minusZDir = vec3.fromValues(0, 0, -1);\n const eyeParam = vr.getEyeParams(gl, frame)![0];\n // Extract only rotation\n const mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix);\n const pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix);\n\n const mvInv = mat3.invert(mat3.create(), mvMatrix);\n const pInv = mat3.invert(mat3.create(), pMatrix);\n const viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv);\n\n vec3.transformMat3(viewDir, viewDir, mvInv);\n\n const yawOffset = mathUtil.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1));\n\n if (yawOffset === 0) {\n // If the yawOffset is exactly 0, then device sensor is not ready\n // So read it again until it has any value in it\n return;\n }\n\n vr.setYawOffset(yawOffset);\n animator.setCallback(this._renderStereo);\n };\n\n private _setWrapperFullscreen() {\n const wrapper = this._wrapper;\n\n if (!wrapper) return;\n\n this._wrapperOrigStyle = wrapper.getAttribute(\"style\");\n const wrapperStyle = wrapper.style;\n\n wrapperStyle.width = \"100vw\";\n wrapperStyle.height = \"100vh\";\n wrapperStyle.position = \"fixed\";\n wrapperStyle.left = \"0\";\n wrapperStyle.top = \"0\";\n wrapperStyle.zIndex = \"9999\";\n }\n\n private _restoreStyle() {\n const wrapper = this._wrapper;\n const canvas = this.canvas;\n\n if (!wrapper) return;\n\n if (this._wrapperOrigStyle) {\n wrapper.setAttribute(\"style\", this._wrapperOrigStyle);\n } else {\n wrapper.removeAttribute(\"style\");\n }\n\n this._wrapperOrigStyle = null;\n\n // Restore canvas style\n canvas.removeAttribute(\"style\");\n this._setDefaultCanvasStyle();\n }\n}\n\nexport default PanoImageRenderer;\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { VERSION } from \"../version\";\nimport { merge } from \"../utils/utils\";\n\nimport PanoViewer from \"./PanoViewer\";\nimport * as Constants from \"./consts\";\n\nconst PanoViewerModule = {\n PanoViewer,\n VERSION\n};\n\nmerge(PanoViewerModule, Constants);\n\nexport default PanoViewerModule;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Promise from \"promise-polyfill\";\nimport { quat } from \"gl-matrix\";\n\nimport { DeviceMotionEvent, checkXRSupport } from \"../utils/browserFeature\";\nimport YawPitchControl, { YawPitchControlOptions } from \"../YawPitchControl/YawPitchControl\";\nimport PanoImageRenderer from \"../PanoImageRenderer/PanoImageRenderer\";\nimport WebGLUtils from \"../PanoImageRenderer/WebGLUtils\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { CubemapConfig, ValueOf } from \"../types/internal\";\nimport { AnimationEndEvent, ReadyEvent, ViewChangeEvent, ErrorEvent } from \"../types/event\";\n\nimport { ERROR_TYPE, PANOVIEWER_EVENTS as EVENTS, GYRO_MODE, PROJECTION_TYPE, STEREO_FORMAT, DEFAULT_CANVAS_CLASS } from \"./consts\";\n\nexport interface PanoViewerOptions {\n image: string | HTMLElement;\n video: string | HTMLElement;\n projectionType: ValueOf;\n cubemapConfig: Partial;\n stereoFormat: ValueOf;\n width: number;\n height: number;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n touchDirection: ValueOf;\n canvasClass: string;\n}\n\nexport interface PanoViewerEvent {\n ready: ReadyEvent;\n viewChange: ViewChangeEvent;\n animationEnd: AnimationEndEvent;\n error: ErrorEvent;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * PanoViewer\n */\nclass PanoViewer extends Component {\n /**\n * Check whether the current environment can execute PanoViewer\n * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다.\n * @return PanoViewer executable PanoViewer 실행가능 여부\n */\n public static isSupported(): boolean {\n return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL();\n }\n\n /**\n * Check whether the current environment supports the WebGL\n * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다.\n * @return WebGL support WebGL 지원여부\n */\n public static isWebGLAvailable(): boolean {\n return WebGLUtils.isWebGLAvailable();\n }\n\n /**\n * Check whether the current environment supports the gyro sensor.\n * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다.\n * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수\n */\n public static isGyroSensorAvailable(callback: (isAvailable: boolean) => any) {\n if (!DeviceMotionEvent && callback) {\n callback(false);\n return;\n }\n\n let onDeviceMotionChange;\n\n const checkGyro = () => new Promise(res => {\n onDeviceMotionChange = deviceMotion => {\n const isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null);\n\n res(isGyroSensorAvailable);\n };\n\n window.addEventListener(\"devicemotion\", onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n Promise.race([checkGyro(), timeout()]).then((isGyroSensorAvailable: boolean) => {\n window.removeEventListener(\"devicemotion\", onDeviceMotionChange);\n\n if (callback) {\n callback(isGyroSensorAvailable);\n }\n\n PanoViewer.isGyroSensorAvailable = fb => {\n if (fb) {\n fb(isGyroSensorAvailable);\n }\n return isGyroSensorAvailable;\n };\n });\n }\n\n private static _isValidTouchDirection(direction) {\n return direction === PanoViewer.TOUCH_DIRECTION.NONE ||\n direction === PanoViewer.TOUCH_DIRECTION.YAW ||\n direction === PanoViewer.TOUCH_DIRECTION.PITCH ||\n direction === PanoViewer.TOUCH_DIRECTION.ALL;\n }\n\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @name VERSION\n * @static\n * @type {String}\n * @example\n * eg.view360.PanoViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.PanoViewer\n */\n public static VERSION = VERSION;\n public static ERROR_TYPE = ERROR_TYPE;\n public static EVENTS = EVENTS;\n public static PROJECTION_TYPE = PROJECTION_TYPE;\n public static GYRO_MODE = GYRO_MODE;\n // This should be deprecated!\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static ProjectionType = PROJECTION_TYPE;\n public static STEREO_FORMAT = STEREO_FORMAT;\n\n /**\n * Constant value for touch directions\n * @ko 터치 방향에 대한 상수 값.\n * @namespace\n * @name TOUCH_DIRECTION\n */\n public static TOUCH_DIRECTION = {\n /**\n * Constant value for none direction.\n * @ko none 방향에 대한 상수 값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 1\n */\n NONE: YawPitchControl.TOUCH_DIRECTION_NONE,\n /**\n * Constant value for horizontal(yaw) direction.\n * @ko horizontal(yaw) 방향에 대한 상수 값.\n * @name YAW\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 6\n */\n YAW: YawPitchControl.TOUCH_DIRECTION_YAW,\n /**\n * Constant value for vertical direction.\n * @ko vertical(pitch) 방향에 대한 상수 값.\n * @name PITCH\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 24\n */\n PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH,\n /**\n * Constant value for all direction.\n * @ko all 방향에 대한 상수 값.\n * @name ALL\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 30\n */\n ALL: YawPitchControl.TOUCH_DIRECTION_ALL\n };\n\n private _container: HTMLElement;\n // Options\n private _image: ConstructorParameters[0];\n private _isVideo: boolean;\n private _projectionType: ValueOf;\n private _cubemapConfig: Partial;\n private _stereoFormat: ValueOf;\n private _width: number;\n private _height: number;\n private _yaw: number;\n private _pitch: number;\n private _fov: number;\n private _gyroMode: ValueOf;\n private _quaternion: quat | null;\n private _aspectRatio: number;\n private _isReady: boolean;\n private _canvasClass: string;\n\n // Internal Values\n private _photoSphereRenderer: PanoImageRenderer | null;\n private _yawPitchControl: YawPitchControl | null;\n\n /**\n * @classdesc 360 media viewer\n * @ko 360 미디어 뷰어\n *\n * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트\n * @param options\n *\n * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
\n * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다.\n * @param {Object} [options.cubemapConfig.order = \"RLUDBF\"(ProjectionType === CUBEMAP) | \"RLUDFB\" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서\n * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다.\n * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다.\n * @param {String} [options.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
\n * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위)\n * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위)\n * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위)\n * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위)\n * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위)\n * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다\n * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다.\n * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키\n * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE}
\n * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위\n * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위\n * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위\n * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
\n * @param {String} [options.canvasClass=\"view360-canvas\"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n *\n * @example\n * ```\n * // PanoViewer Creation\n * // create PanoViewer with option\n * var PanoViewer = eg.view360.PanoViewer;\n * // Area where the image will be displayed(HTMLElement)\n * var container = document.getElementById(\"myPanoViewer\");\n *\n * var panoViewer = new PanoViewer(container, {\n * // If projectionType is not specified, the default is \"equirectangular\".\n * // Specifies an image of the \"equirectangular\" type.\n * image: \"/path/to/image/image.jpg\"\n * });\n * ```\n *\n * @example\n * ```\n * // Cubemap Config Setting Example\n * // For support Youtube EAC projection, You should set cubemapConfig as follows.\n * cubemapConfig: {\n * order: \"LFRDBU\",\n * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}]\n * }\n * ```\n */\n public constructor(container: HTMLElement, options: Partial = {}) {\n super();\n\n // Raises the error event if webgl is not supported.\n if (!WebGLUtils.isWebGLAvailable()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n }, 0);\n return this;\n }\n\n if (!WebGLUtils.isStableWebGL()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_DEVICE,\n message: \"blacklisted browser\"\n }));\n }, 0);\n\n return this;\n }\n\n if (!!options.image && !!options.video) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_RESOURCE,\n message: \"Specifying multi resouces(both image and video) is not valid.\"\n }));\n }, 0);\n return this;\n }\n\n // Check XR support at not when imported, but when created.\n // This is intended to make polyfills easier to use.\n checkXRSupport();\n\n this._container = container;\n this._image = options.image! as HTMLImageElement || options.video! as HTMLVideoElement;\n this._isVideo = !!options.video;\n this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/\n order: this._projectionType === PROJECTION_TYPE.CUBEMAP ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...options.cubemapConfig\n };\n this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n\n // If the width and height are not provided, will use the size of the container.\n this._width = options.width || parseInt(window.getComputedStyle(container).width, 10);\n this._height = options.height || parseInt(window.getComputedStyle(container).height, 10);\n\n /**\n * Cache the direction for the performance in renderLoop\n *\n * This value should be updated by \"change\" event of YawPitchControl.\n */\n this._yaw = options.yaw || 0;\n this._pitch = options.pitch || 0;\n this._fov = options.fov || 65;\n\n this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH;\n this._quaternion = null;\n\n this._aspectRatio = this._height !== 0 ? this._width / this._height : 1;\n\n this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS;\n\n const fovRange = options.fovRange || [30, 110];\n const touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ?\n options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL;\n const yawPitchConfig = {\n ...options,\n ...{\n element: container,\n yaw: this._yaw,\n pitch: this._pitch,\n fov: this._fov,\n gyroMode: this._gyroMode,\n fovRange,\n aspectRatio: this._aspectRatio,\n touchDirection\n }\n };\n\n this._isReady = false;\n\n this._initYawPitchControl(yawPitchConfig);\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n /**\n * Get the video element that the viewer is currently playing. You can use this for playback.\n * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다.\n * @return HTMLVideoElementHTMLVideoElement\n * @example\n * ```\n * var videoTag = panoViewer.getVideo();\n * videoTag.play(); // play the video!\n * ```\n */\n public getVideo() {\n if (!this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent() as HTMLVideoElement;\n }\n\n /**\n * Set the video information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정)\n * @param {object} param\n * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}(\"equirectangular\")] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setVideo(\"/path/to/video/video.mp4\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR\n * });\n * ```\n */\n public setVideo(video: string | HTMLElement | { type: string; src: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n }> = {}) {\n if (video) {\n this.setImage(video, {\n projectionType: param.projectionType,\n isVideo: true,\n cubemapConfig: param.cubemapConfig,\n stereoFormat: param.stereoFormat\n });\n }\n\n return this;\n }\n\n /**\n * Get the image information that the viewer is currently using.\n * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다.\n * @return Image Object이미지 객체\n * @example\n * var imageObj = panoViewer.getImage();\n */\n public getImage() {\n if (this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent();\n }\n\n /**\n * Set the image information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.)\n * @param {object} param Additional information이미지 추가 정보\n * @param {string} [param.projectionType=\"equirectangular\"] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setImage(\"/path/to/image/image.png\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP\n * });\n * ```\n */\n public setImage(image: string | HTMLElement | { src: string; type: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n isVideo: boolean;\n }> = {}) {\n const cubemapConfig = {\n ...{\n order: \"RLUDBF\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...param.cubemapConfig\n };\n const stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n const isVideo = !!(param.isVideo);\n\n if (this._image && this._isVideo !== isVideo) {\n /* eslint-disable no-console */\n console.warn(\"PanoViewer is not currently supporting content type changes. (Image <--> Video)\");\n /* eslint-enable no-console */\n return this;\n }\n\n if (image) {\n this._deactivate();\n\n this._image = image as HTMLImageElement;\n this._isVideo = isVideo;\n this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = cubemapConfig;\n this._stereoFormat = stereoFormat;\n\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n return this;\n }\n\n /**\n * Set whether the renderer always updates the texture and renders.\n * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다.\n * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public keepUpdate(doUpdate: boolean) {\n this._photoSphereRenderer!.keepUpdate(doUpdate);\n return this;\n }\n\n /**\n * Get the current projection type (equirectangular/cube)\n * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다.\n * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE}\n */\n public getProjectionType() {\n return this._projectionType;\n }\n\n /**\n * Activate the device's motion sensor, and return the Promise whether the sensor is enabled\n * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element.\n * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다.\n * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다.\n */\n public enableSensor() {\n return new Promise((resolve, reject) => {\n if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\") {\n DeviceMotionEvent.requestPermission().then(permissionState => {\n if (permissionState === \"granted\") {\n resolve();\n } else {\n reject(new Error(\"permission denied\"));\n }\n }).catch(e => {\n // This can happen when this method wasn't triggered by user interaction\n reject(e);\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Disable the device's motion sensor.\n * @ko 디바이스의 모션 센서를 비활성화합니다.\n * @deprecated\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public disableSensor() {\n return this;\n }\n\n /**\n * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred).\n * This method must be used in the context of user interaction, like onclick callback on the button element.\n * It can be rejected when an enabling device sensor fails or image/video is still loading(\"ready\" event not triggered).\n * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다)\n * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우(\"ready\"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다.\n * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요.\n * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error)\n */\n public enterVR(options: {\n requiredFeatures?: any[];\n optionalFeatures?: any[];\n [key: string]: any;\n } = {}): globalThis.Promise {\n if (!this._isReady) {\n return Promise.reject(new Error(\"PanoViewer is not ready to show image.\")) as any;\n }\n\n return new Promise((resolve, reject) => {\n this.enableSensor()\n .then(() => this._photoSphereRenderer!.enterVR(options))\n .then((res: string) => resolve(res))\n .catch(e => reject(e));\n }) as any;\n }\n\n /**\n * Exit VR stereo rendering mode.\n * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public exitVR() {\n this._photoSphereRenderer!.exitVR();\n return this;\n }\n\n /**\n * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}.\n * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다.\n * @param useZoom\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseZoom(useZoom: boolean): this {\n if (typeof useZoom === \"boolean\") {\n this._yawPitchControl!.option(\"useZoom\", useZoom);\n }\n\n return this;\n }\n\n /**\n * When true, enables the keyboard move key control: awsd, arrow keys\n * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키)\n * @param useKeyboard\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseKeyboard(useKeyboard: boolean): this {\n this._yawPitchControl!.option(\"useKeyboard\", useKeyboard);\n return this;\n }\n\n /**\n * Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")\n * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")\n * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE}\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setGyroMode(\"yawPitch\");\n * //equivalent\n * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH);\n * ```\n */\n public setGyroMode(gyroMode: PanoViewer[\"_gyroMode\"]) {\n this._yawPitchControl!.option(\"gyroMode\", gyroMode);\n return this;\n }\n\n /**\n * Set the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 설정합니다.\n * @param range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setFovRange([50, 90]);\n */\n public setFovRange(range: number[]) {\n this._yawPitchControl!.option(\"fovRange\", range);\n return this;\n }\n\n /**\n * Get the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 반환합니다.\n * @return FOV range\n * @example\n * var range = panoViewer.getFovRange(); // [50, 90]\n */\n public getFovRange(): [number, number] {\n return this._yawPitchControl!.option(\"fovRange\") as [number, number];\n }\n\n /**\n * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size.\n * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다.\n * @param {object} [size]\n * @param {number} [size.width=width of the container]\n * @param {number} [size.height=height of the container]\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public updateViewportDimensions(size: Partial<{\n width: number;\n height: number;\n }> = {}): this {\n if (!this._isReady) {\n return this;\n }\n\n let containerSize;\n\n if (size.width === undefined || size.height === undefined) {\n containerSize = window.getComputedStyle(this._container);\n }\n\n const width = size.width || parseInt(containerSize.width, 10);\n const height = size.height || parseInt(containerSize.height, 10);\n\n // Skip if viewport is not changed.\n if (width === this._width && height === this._height) {\n return this;\n }\n\n this._width = width;\n this._height = height;\n\n this._aspectRatio = width / height;\n this._photoSphereRenderer!.updateViewportDimensions(width, height);\n this._yawPitchControl!.option(\"aspectRatio\", this._aspectRatio);\n this._yawPitchControl!.updatePanScale({height});\n\n this.lookAt({}, 0);\n return this;\n }\n\n /**\n * Get the current field of view(FOV)\n * @ko 현재 field of view(FOV) 값을 반환합니다.\n */\n public getFov(): number {\n return this._fov;\n }\n\n /**\n * Get current yaw value\n * @ko 현재 yaw 값을 반환합니다.\n */\n public getYaw() {\n return this._yaw;\n }\n\n /**\n * Get current pitch value\n * @ko 현재 pitch 값을 반환합니다.\n */\n public getPitch() {\n return this._pitch;\n }\n\n /**\n * Get the range of controllable Yaw values\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n */\n public getYawRange(): [number, number] {\n return this._yawPitchControl!.option(\"yawRange\") as [number, number];\n }\n\n /**\n * Get the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다.\n */\n public getPitchRange(): [number, number] {\n return this._yawPitchControl!.option(\"pitchRange\") as [number, number];\n }\n\n /**\n * Set the range of controllable yaw\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setYawRange([-90, 90]);\n */\n public setYawRange(yawRange: number[]) {\n this._yawPitchControl!.option(\"yawRange\", yawRange);\n return this;\n }\n\n /**\n * Set the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 설정합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setPitchRange([-40, 40]);\n */\n public setPitchRange(pitchRange: number[]) {\n this._yawPitchControl!.option(\"pitchRange\", pitchRange);\n return this;\n }\n\n /**\n * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed.\n * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다.\n * @param showPolePoint\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setShowPolePoint(showPolePoint: boolean) {\n this._yawPitchControl!.option(\"showPolePoint\", showPolePoint);\n return this;\n }\n\n /**\n * Set a new view by setting camera configuration. Any parameters not specified remain the same.\n * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다.\n * @param {object} orientation\n * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위)\n * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위)\n * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위)\n * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초)\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * // Change the yaw angle (absolute angle) to 30 degrees for one second.\n * panoViewer.lookAt({yaw: 30}, 1000);\n * ```\n */\n public lookAt(orientation: Partial<{\n yaw: number;\n pitch: number;\n fov: number;\n }>, duration: number = 0) {\n if (!this._isReady) {\n return this;\n }\n\n const yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw;\n const pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch;\n const pitchRange = this._yawPitchControl!.option(\"pitchRange\");\n const verticalAngleOfImage = pitchRange[1] - pitchRange[0];\n let fov = orientation.fov !== undefined ? orientation.fov : this._fov;\n\n if (verticalAngleOfImage < fov) {\n fov = verticalAngleOfImage;\n }\n\n this._yawPitchControl!.lookAt({yaw, pitch, fov}, duration);\n\n if (duration === 0) {\n this._photoSphereRenderer!.renderWithYawPitch(yaw, pitch, fov);\n }\n return this;\n }\n\n /**\n * Set touch direction by which user can control.\n * @ko 사용자가 조작가능한 터치 방향을 지정합니다.\n * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @return PanoViewer instance\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Limit the touch direction to the yaw direction only.\n * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW);\n * ```\n */\n public setTouchDirection(direction: number): this {\n if (PanoViewer._isValidTouchDirection(direction)) {\n this._yawPitchControl!.option(\"touchDirection\", direction);\n }\n\n return this;\n }\n\n /**\n * Returns touch direction by which user can control\n * @ko 사용자가 조작가능한 터치 방향을 반환한다.\n * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Returns the current touch direction.\n * var dir = panoViewer.getTouchDirection();\n * ```\n */\n public getTouchDirection(): number {\n return this._yawPitchControl!.option(\"touchDirection\") ;\n }\n\n /**\n * Destroy viewer. Remove all registered event listeners and remove viewer canvas.\n * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public destroy(): this {\n this._deactivate();\n\n if (this._yawPitchControl) {\n this._yawPitchControl.destroy();\n this._yawPitchControl = null;\n }\n\n return this;\n }\n\n // TODO: Remove parameters as they're just using private values\n private _initRenderer(\n yaw: number,\n pitch: number,\n fov: number,\n projectionType: PanoViewer[\"_projectionType\"],\n cubemapConfig: PanoViewer[\"_cubemapConfig\"]\n ) {\n this._photoSphereRenderer = new PanoImageRenderer(\n this._image,\n this._width,\n this._height,\n this._isVideo,\n this._container,\n this._canvasClass,\n {\n initialYaw: yaw,\n initialPitch: pitch,\n fieldOfView: fov,\n imageType: projectionType,\n cubemapConfig,\n stereoFormat: this._stereoFormat\n },\n );\n this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl!);\n\n this._bindRendererHandler();\n\n this._photoSphereRenderer\n .bindTexture()\n .then(() => this._activate())\n .catch(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_BIND_TEXTURE,\n message: \"failed to bind texture\"\n }));\n });\n }\n\n /**\n * @private\n * update values of YawPitchControl if needed.\n * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image.\n *\n * This function should be called after isReady status is true.\n */\n private _updateYawPitchIfNeeded() {\n if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) {\n // update fov by aspect ratio\n const image = this._photoSphereRenderer!.getContent()! as HTMLImageElement;\n let imageAspectRatio = image.naturalWidth / image.naturalHeight;\n let yawSize;\n let maxFov;\n\n // If height is larger than width, then we assume it's rotated by 90 degree.\n if (imageAspectRatio < 1) {\n // So inverse the aspect ratio.\n imageAspectRatio = 1 / imageAspectRatio;\n }\n\n if (imageAspectRatio < 6) {\n yawSize = mathUtil.toDegree(imageAspectRatio);\n // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5\n maxFov = mathUtil.toDegree(Math.atan(0.5)) * 2;\n } else {\n yawSize = 360;\n maxFov = (360 / imageAspectRatio); // Make it 5 fixed as axes does.\n }\n\n // console.log(\"_updateYawPitchIfNeeded\", maxFov, \"aspectRatio\", image.naturalWidth, image.naturalHeight, \"yawSize\", yawSize);\n const minFov = (this._yawPitchControl!.option(\"fovRange\"))[0];\n\n // this option should be called after fov is set.\n this._yawPitchControl!.option({\n \"fov\": maxFov, /* parameter for internal validation for pitchrange */\n \"yawRange\": [-yawSize / 2, yawSize / 2],\n \"pitchRange\": [-maxFov / 2, maxFov / 2],\n \"fovRange\": [minFov, maxFov]\n });\n this.lookAt({fov: maxFov});\n }\n }\n\n private\t_bindRendererHandler() {\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, e));\n });\n\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, () => {\n this._deactivate();\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERING_CONTEXT_LOST,\n message: \"webgl rendering context lost\"\n }));\n });\n }\n\n private _initYawPitchControl(yawPitchConfig: Partial) {\n this._yawPitchControl = new YawPitchControl(yawPitchConfig);\n\n this._yawPitchControl.on(EVENTS.ANIMATION_END, e => {\n this.trigger(new ComponentEvent(EVENTS.ANIMATION_END, e));\n });\n\n this._yawPitchControl.on(\"change\", e => {\n this._yaw = e.yaw;\n this._pitch = e.pitch;\n this._fov = e.fov;\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(EVENTS.VIEW_CHANGE, {\n yaw: e.yaw,\n pitch: e.pitch,\n fov: e.fov,\n quaternion: e.quaternion,\n isTrusted: e.isTrusted\n }));\n });\n }\n\n private _activate() {\n this._photoSphereRenderer!.attachTo(this._container);\n this._yawPitchControl!.enable();\n\n this.updateViewportDimensions();\n\n this._isReady = true;\n\n // update yawPitchControl after isReady status is true.\n this._updateYawPitchIfNeeded();\n\n this.trigger(new ComponentEvent(EVENTS.READY));\n this._photoSphereRenderer!.startRender();\n }\n\n /**\n * Destroy webgl context and block user interaction and stop rendering\n */\n private _deactivate() {\n // Turn off the video if it has one\n const video = this.getVideo();\n if (video) {\n video.pause();\n }\n\n if (this._isReady) {\n this._photoSphereRenderer!.stopRender();\n this._yawPitchControl!.disable();\n this._isReady = false;\n }\n\n if (this._photoSphereRenderer) {\n this._photoSphereRenderer.destroy();\n this._photoSphereRenderer = null;\n }\n }\n}\n\nexport default PanoViewer;\n\n"],"names":["VERSION","merge","target","_i","srcs","forEach","source","Object","keys","key","value","Array","isArray","appendSourceElement","video","videoUrl","videoSrc","videoType","src","type","sourceElement","document","createElement","appendChild","win","window","Math","self","Function","doc","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","IS_IOS","IS_SAFARI_ON_DESKTOP","Float32Array","getComputedStyle","toDegree","a","PI","userAgent","SUPPORT_TOUCH","SUPPORT_DEVICEMOTION","DeviceMotionEvent","devicePixelRatio","WEBXR_SUPPORTED","docStyle","documentElement","style","i","len","length","CSS","supports","checkXRSupport","xr","isSessionSupported","then","res","catch","supportsSession","util","n","extractPitchFromQuat","quaternion","baseV","vec3","fromValues","transformQuat","atan2","sqrt","pow","hypot","x","y","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","angleBetweenVec2","v1","v2","det","vec2","dot","yawOffsetBetween","viewDir","targetDir","viewDirXZ","targetDirXZ","normalize","sign","Number","getRotationDelta","prevQ","curQ","rotateKind","prevQuaternion","quat","clone","curQuaternion","prevPoint","curPoint","rotateDirection","cross","create","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","distance","abs","projectedPrevPoint","subtract","scale","trigonometricRatio","theta","acos","crossVec","thetaDirection","version","branch","build","match","exec","parseInt","r","CHROME_VERSION","IS_CHROME_WITHOUT_DEVICE_MOTION","IS_ANDROID","test","MC_BIND_SCALE","GYRO_MODE","NONE","YAWPITCH","VR","MathUtil","degToRad","radToDeg","Vector2","prototype","constructor","set","this","copy","v","subVectors","b","Vector3","z","scalar","invScalar","multiplyScalar","applyQuaternion","q","qx","qy","qz","qw","w","ix","iy","iz","iw","crossVectors","ax","ay","az","bx","by","bz","Quaternion","undefined","setFromEulerXYZ","c1","cos","c2","c3","s1","sin","s2","s3","setFromEulerYXZ","setFromAxisAngle","axis","angle","halfAngle","s","multiply","multiplyQuaternions","qax","qay","qaz","qaw","qbx","qby","qbz","qbw","inverse","l","slerp","qb","t","cosHalfTheta","halfTheta","sinHalfTheta","ratioA","ratioB","setFromUnitVectors","vFrom","vTo","isIOS","isWebViewAndroid","isSafari","isFirefoxAndroid","isR7","piOver180","rad45","defaultOrientation","defaultPosition","Util","updateEyeMatrices","projection","view","pose","parameters","vrDisplay","out","fov","fieldOfView","near","depthNear","far","depthFar","upTan","tan","upDegrees","downTan","downDegrees","leftTan","leftDegrees","rightTan","rightDegrees","xScale","yScale","a00","a01","a03","a10","a11","a12","a13","a20","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b07","b08","b09","b10","b11","orientation","position","xx","x2","xy","y2","xz","z2","yy","yz","zz","wx","wy","wz","offset","a02","a21","b06","MIN_TIMESTEP","MAX_TIMESTEP","base64","mimeType","clamp","min","max","lerp","platform","indexOf","isLandscapeMode","rtn","isTimestampDeltaValid","timestampDeltaS","isNaN","getScreenWidth","screen","width","height","getScreenHeight","requestFullscreen","element","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","exitFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","getFullscreenElement","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","linkProgram","gl","vertexSource","fragmentSource","attribLocationMap","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","attribName","program","createProgram","attachShader","bindAttribLocation","deleteShader","getProgramUniforms","uniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","uniformName","getActiveUniform","replace","getUniformLocation","orthoMatrix","left","right","bottom","top","lr","bt","nf","copyArray","dest","isMobile","check","vendor","opera","substr","extend","hasOwnProperty","safariCssSizeWorkaround","canvas","width_1","height_1","setTimeout","isDebug","getQueryParameter","results","RegExp","location","search","decodeURIComponent","frameDataFromPose","frameData","timestamp","leftProjectionMatrix","leftViewMatrix","getEyeParameters","rightProjectionMatrix","rightViewMatrix","isInsideCrossDomainIFrame","isFramed","refDomain","getDomainFromUrl","referrer","thisDomain","href","url","domain","split","predictionTimeS","previousQ","previousTimestampS","deltaQ","outQ","currentQ","gyro","timestampS","angularSpeed","console","log","toFixed","predictAngle","_super","_this","_onDeviceMotion","bind","_onDeviceOrientation","_onChromeWithoutDeviceMotion","isWithoutDeviceMotion","isAndroid","stillGyroVec","rawGyroVec","adjustedGyroVec","_timer","lastDevicemotionTimestamp","_isEnabled","enable","__extends","addEventListener","removeEventListener","e","alpha","beta","gamma","trigger","ComponentEvent","inputEvent","deviceorientation","clearTimeout","Date","getTime","isGyroSensorAvailable","rotationRate","isGravitySensorAvailable","accelerationIncludingGravity","interval","devicemotionEvent","__assign","timeStamp","acceleration","adjustedRotationRate","Component","sample","sensorSample","kFilter","vector","currentGyroMeasurement","deltaT","previousGyroMeasurement","run_","currentAccelMeasurement","SensorSample","filterQ","previousFilterQ","accelQ","isOrientationInitialized","estimatedGravity","measuredGravity","gyroIntegralQ","accelToQuaternion_","gyroDeltaQ","gyroToQuaternionDelta_","invFilterQ","getQuaternionAngle","targetQ","accel","normAccel","dt","ComplementaryFilter","isFilterQuaternionInitialized","getOrientation","deviceMotion","DeviceMotion","accelerometer","gyroscope","_onDeviceMotionChange","_onScreenOrientationChange","filter","posePredictor","PosePredictor","filterToWorldQ","isChromeUsingDegrees","inverseWorldToScreenQ","worldToScreenQ","originalPoseAdjustQ","_setScreenTransform","resetQ","on","isEnabled","disable","_deviceOrientationQ","deviceOrientationFixQ","_alpha","outQuat","_convertFusionToPredicted","_prevOrientation","equals","predictedQ","getPrediction","_a","accGravity","rotRate","_triggerChange","addAccelMeasurement","addGyroMeasurement","el","options","_prevQuaternion","_quaternion","fusionPoseSensor","threshold","_onPoseChange","axes","observer","FusionPoseSensor","_attachEvent","_dettachEvent","destroy","disconnect","event","prvQ","change","yawDeltaByYaw","reduce","acc","off","screenRotationAngleInst","refCount","_onOrientationChange","_spinR","_screenOrientationAngle","glMatrix","toRadian","betaR","gammaR","_useRotation","_screenRotationAngle","setUseRotation","useRotation","_userDirection","Axes","DIRECTION_ALL","unref","ScreenRotationAngle","_direction","DIRECTION_HORIZONTAL","connect","properties","useDirection","_getOffset","newOffset","getRadian","cosTheta","sinTheta","DIRECTION_VERTICAL","PanInput","Y_AXIS_VECTOR","_fusionPoseSensor","isTrusted","yaw","yawQ","setAxisAngle","conj","conjugate","DEFAULT_YAW_RANGE","DEFAULT_PITCH_RANGE","CIRCULAR_PITCH_RANGE","opt","pitch","showPolePoint","useZoom","useKeyboard","gyroMode","touchDirection","TOUCH_DIRECTION_YAW","yawRange","pitchRange","fovRange","aspectRatio","_element","_initialFov","_enabled","_isAnimating","_deviceQuaternion","_initAxes","option","param","_axes","get","areaHeight","_axesPanInput","deceleration","newValue","_getOptions","newOptions","changedKeyList","push","_setOptions","_getValidatedOptions","_applyOptions","updatePanScale","persistOrientation","_resetOrientation","duration","pos","p","f","maximumDuration","Infinity","setBy","yawPitch","getCombinedQuaternion","_axesWheelInput","_axesTiltMotionInput","_axesPinchInput","_axesMoveKeyInput","yRange","_updateYawRange","pRange","_updatePitchRange","RotationPanInput","WheelInput","PinchInput","MoveKeyInput","range","circular","_isCircular","bounce","hold","evt","delta","_updateControlScale","release","animationEnd","_getValidYawRange","_getValidPitchRange","arguments","prevFov","nextFov","isVR","isYawPitch","some","setTo","_initDeviceQuaternion","TiltMotionInput","_togglePinchInputByOption","_enableTouch","_inputs","direction","yawEnabled","pitchEnabled","DeviceQuaternion","newYawRange","newFov","newAspectRatio","ratio","_adjustAspectRatio","horizontalFov","newPitchRange","changeEvt","verticalAngle","halfFov","concat","halfHorizontalFov","mathUtil","targetElement","input","inputRange","outputRange","rangeIdx","inputA","inputB","outputA","outputB","_lerp","fraction","YawPitchControl","ERROR_TYPE","INVALID_DEVICE","NO_WEBGL","FAIL_IMAGE_LOAD","FAIL_BIND_TEXTURE","INVALID_RESOURCE","RENDERING_CONTEXT_LOST","PANOVIEWER_EVENTS","READY","VIEW_CHANGE","ANIMATION_END","ERROR","PROJECTION_TYPE","EQUIRECTANGULAR","CUBEMAP","CUBESTRIP","PANORAMA","STEREOSCOPIC_EQUI","STEREO_FORMAT","TOP_BOTTOM","LEFT_RIGHT","DEFAULT_CANVAS_CLASS","image","projectionType","cubemapConfig","stereoFormat","canvasClass","WEBGL_ERROR_CODE","webglAvailability","WebGLUtils","shader","getShaderParameter","COMPILE_STATUS","error","getShaderInfoLog","LINK_STATUS","deleteProgram","data","itemSize","attr","buffer","createBuffer","bindBuffer","bufferData","STATIC_DRAW","numItems","enableVertexAttribArray","vertexAttribPointer","FLOAT","userContextAttributes","context","contextAttributes","preserveDrawingBuffer","antialias","onWebglcontextcreationerror","statusMessage","webglIdentifiers_1","__values","identifier","getContext","textureTarget","texture","createTexture","bindTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","loseContextExtension","webglContext","getWebglContext","getExtension","loseContext","agentInfo","isStableWebgl","parseFloat","code","pixels","texImage2D","RGBA","UNSIGNED_BYTE","getParameter","MAX_TEXTURE_SIZE","isIE11","majorVersion","EVENTS","_forceDimension","_pixelCanvas","_pixelContext","shaderProgram","indexBuffer","mvMatrix","pMatrix","uniformMatrix4fv","pMatrixUniform","mvMatrixUniform","drawElements","TRIANGLES","UNSIGNED_SHORT","pixelSource","naturalWidth","videoWidth","naturalHeight","videoHeight","forceDimension","HTMLVideoElement","getDimension","contentDimension","textureDimension","drawImage","imageConfig","tileConfig","map","config","flipHorizontal","rotation","message","Renderer","CubeRenderer","order","_VERTEX_POSITION_DATA","_INDEX_DATA","indexData","vertexPositionData","getVertexPositionData","extractOrder","base","_extractTileConfig","trim","face","floor","ordermap","shift","unshift","pop","tileVertex","slice","elemSize","tileTemp","j","splice","coord","_shrinkCoord","faceCoords","val","coords","orderMap","surfaceIdx","tileIdx","TEXTURE_CUBE_MAP_POSITIVE_X","maxCubeMapTextureSize","getMaxCubeMapTextureSize","tile","extractTileFromImage","_triggerError","TEXTURE_CUBE_MAP","updateTexture","inputTextureSize","outputTextureSize","getSourceTileSize","tilePerRow","MAX_CUBE_MAP_TEXTURE_SIZE","imageWidth","isPowerOfTwo","coordData","SHRINK_MULTIPLIER","axisMultipliers","axisIndex","axisDir","notSameDir","_vertices","textureSize","rows","c","tileConfigs","_transformCoord","index","TEXTURE_2D","_getPixelSource","size","maxSize","getMaxTextureSize","_initPixelSource","activeTexture","TEXTURE0","pixelStorei","UNPACK_FLIP_Y_WEBGL","newCoord","_flipHorizontalCoord","_rotateCoord","SHRINK_Y","SHRINK_X","rotationAngle","moved","shiftCount","ANGLE_CORRECTION_FOR_CENTER_ALIGN","textureCoordData","latIdx","lngIdx","phi","sinPhi","u","format","_stereoFormat","ctx","leftEyeScaleOffset","rightEyeScaleOffset","uTexScaleOffset","uniform4fv","render","SphereRenderer","_TEXTURE_COORD_DATA","CylinderRenderer","resizeDimension","rotated","cylinderMaxRadian","_b","imageAspectRatio","halfCylinderY","CYLIDER_Y","startAngleForCenterAlign","yIdx","yLength","VR_DISPLAY_PRESENT_CHANGE","DEFAULT_LEFT_BOUNDS","DEFAULT_RIGHT_BOUNDS","EYES","_vrDisplay","removeEndCallback","isPresenting","exitPresent","_clear","_frameData","VRFrameData","Boolean","bindFramebuffer","FRAMEBUFFER","submitFrame","display","halfWidth","drawingBufferWidth","drawingBufferHeight","getFrameData","leftMVMatrix","rightMVMatrix","mat4","rotateY","_yawOffset","viewport","callback","getVRDisplays","displays","capabilities","canPresent","requestPresent","leftEye","rightEye","renderWidth","renderHeight","_setDisplay","Promise","reject","Error","layers","getLayers","layer","_leftBounds","leftBounds","_rightBounds","rightBounds","addEndCallback","xrSession","_xrSession","end","_options","frame","getViewerPose","_xrRefSpace","baseLayer","session","renderState","framebuffer","glLayer","views","getViewport","transform","matrix","rotateX","projectionMatrix","_presenting","requiredFeatures","attributes","getContextAttributes","xrCompatible","makeXRCompatible","requestSession","xrLayer","XRWebGLLayer","updateRenderState","requestReferenceSpace","refSpace","_setSession","_xrLayer","args","_callback","_rafId","_context","requestAnimationFrame","_onLoop","before","performance","now","diff","_rafTimer","_onLoopNextTick","cancelAnimationFrame","ImageType","DEVICE_PIXEL_RATIO","BIND_TEXTURE","IMAGE_LOADED","RENDERING_CONTEXT_RESTORE","RENDERER_ERROR","isVideo","container","sphericalConfig","renderingContextAttributes","vr","_vr","animator","_animator","exitVR","_restoreStyle","updateViewportDimensions","_updateViewport","_bindBuffers","_shouldForceDraw","stop","setContext","setCallback","_render","start","time","eyeParams","getEyeParams","beforeRender","eyeIndex","eyeParam","uniform1f","uEye","_draw","afterRender","minusZDir","canRender","mat3","fromMat4","mvInv","invert","pInv","transformMat3","yawOffset","setYawOffset","_renderStereo","_lastQuaternion","_lastYaw","_lastPitch","_lastFieldOfView","perspective","textureCoordBuffer","vertexBuffer","_initCanvas","_setDefaultCanvasStyle","_wrapper","_wrapperOrigStyle","_renderingContextAttributes","_image","_imageConfig","_imageIsReady","_keepUpdate","_onContentLoad","_onContentError","WebGLAnimator","setImage","imageType","yawPitchControl","_yawPitchControl","_isVideo","_setImageType","_contentLoader","ImReady","videoCandidate","video_1","setAttribute","querySelectorAll","readyState","load","toVideoElement","parsedImages","img","imgEl","Image","crossOrigin","toImageElement","rej","contentLoader","isReady","_bindTexture","once","errorCount","parentElement","_hasExternalCanvas","detach","hasRenderingContext","removeChild","forceContextLoss","_onWebglcontextlost","_onWebglcontextrestored","isContextLost","viewPortChanged","h","doUpdate","isImageLoaded","exactEquals","updateFieldOfView","fromQuat","identity","_renderer","resolve","_requestPresent","_imageType","_isCubeMap","CubeStripRenderer","_initWebGL","canvasInContainer","querySelector","_createCanvas","className","margin","maxHeight","maxWidth","outline","content","_triggerContentLoad","renderer","vsSource","getVertexShaderSource","fsSource","getFragmentShaderSource","getErrorNameFromWebGLErrorCode","getError","useProgram","vertexPositionAttribute","getAttribLocation","samplerUniform","textureCoordAttribute","clear","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","STENCIL_BUFFER_BIT","uniform1i","preventDefault","_initRenderingContext","_initShaderProgram","clearColor","deleteTexture","CULL_FACE","WebGLRenderingContext","getIndexData","getTextureCoordData","initBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","Uint16Array","isEAC","updateShaderData","_initBuffers","getFov","shouldRenderWithQuaternion","getQuaternion","renderWithQuaternion","getYawPitch","renderWithYawPitch","_updateTexture","XRManager","VRManager","_onFirstVRFrame","_setWrapperFullscreen","wrapper","getAttribute","wrapperStyle","zIndex","removeAttribute","PanoImageRenderer","PanoViewerModule","PanoViewer","isWebGLAvailable","isStableWebGL","_container","_projectionType","_cubemapConfig","_width","_height","_yaw","_pitch","_fov","_gyroMode","_aspectRatio","_canvasClass","_isValidTouchDirection","TOUCH_DIRECTION_ALL","yawPitchConfig","_isReady","_initYawPitchControl","_initRenderer","onDeviceMotionChange","race","fb","TOUCH_DIRECTION","YAW","PITCH","ALL","_photoSphereRenderer","getContent","warn","_deactivate","keepUpdate","requestPermission","permissionState","enableSensor","enterVR","containerSize","lookAt","verticalAngleOfImage","initialYaw","initialPitch","setYawPitchControl","_bindRendererHandler","_activate","yawSize","maxFov","minFov","ProjectionType","atan","attachTo","_updateYawPitchIfNeeded","startRender","getVideo","pause","stopRender","TOUCH_DIRECTION_NONE","TOUCH_DIRECTION_PITCH","Constants"],"mappings":"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"} \ No newline at end of file diff --git a/dist/PanoViewer/view360.panoviewer.pkgd.js b/dist/PanoViewer/view360.panoviewer.pkgd.js new file mode 100644 index 000000000..a852d3464 --- /dev/null +++ b/dist/PanoViewer/view360.panoviewer.pkgd.js @@ -0,0 +1,14123 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.eg = global.eg || {}, global.eg.view360 = factory())); +}(this, (function () { 'use strict'; + + var VERSION = "3.6.3"; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); + }; + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + function __generator(thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }, + f, + y, + t, + g; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; + + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + + switch (op[0]) { + case 0: + case 1: + t = op; + break; + + case 4: + _.label++; + return { + value: op[1], + done: false + }; + + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + + case 7: + op = _.ops.pop(); + + _.trys.pop(); + + continue; + + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + + if (t && _.label < t[2]) { + _.label = t[2]; + + _.ops.push(op); + + break; + } + + if (t[2]) _.ops.pop(); + + _.trys.pop(); + + continue; + } + + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; + } + } + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + + return ar; + } + + var merge = function (target) { + var srcs = []; + + for (var _i = 1; _i < arguments.length; _i++) { + srcs[_i - 1] = arguments[_i]; + } + + srcs.forEach(function (source) { + Object.keys(source).forEach(function (key) { + var value = source[key]; + + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = __spread(target[key], value); + } else { + target[key] = value; + } + }); + }); + return target; + }; + var toImageElement = function (image) { + var images = image instanceof Array ? image : [image]; + var parsedImages = images.map(function (img) { + var imgEl = img; + + if (typeof img === "string") { + imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = img; + } + + return imgEl; + }); + return parsedImages.length === 1 ? parsedImages[0] : parsedImages; + }; + var toVideoElement = function (videoCandidate) { + if (videoCandidate instanceof HTMLVideoElement) { + return videoCandidate; + } else { + // url + var video_1 = document.createElement("video"); + video_1.setAttribute("crossorigin", "anonymous"); + video_1.setAttribute("webkit-playsinline", ""); + video_1.setAttribute("playsinline", ""); + + if (videoCandidate instanceof Array) { + videoCandidate.forEach(function (v) { + return appendSourceElement(video_1, v); + }); + } else { + appendSourceElement(video_1, videoCandidate); + } + + var sourceCount = video_1.querySelectorAll("source").length; + + if (sourceCount > 0) { + if (video_1.readyState < 1) { + video_1.load(); + } + } + + return video_1; + } + }; + /** + * + * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src} + */ + + var appendSourceElement = function (video, videoUrl) { + var videoSrc; + var videoType; + + if (typeof videoUrl === "object") { + videoSrc = videoUrl.src; + videoType = videoUrl.type; + } else if (typeof videoUrl === "string") { + videoSrc = videoUrl; + } + + if (!videoSrc) { + return false; + } + + var sourceElement = document.createElement("source"); + sourceElement.src = videoSrc; + + if (videoType) { + sourceElement.type = videoType; + } + + video.appendChild(sourceElement); + }; + + /* + Copyright (c) NAVER Corp. + name: @egjs/component + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-component + version: 3.0.1 + */ + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __values$1(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read$1(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread$1() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read$1(arguments[i])); + + return ar; + } + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + var isUndefined = function (value) { + return typeof value === "undefined"; + }; + + /** + * Event class to provide additional properties + * @ko Component에서 추가적인 프로퍼티를 제공하는 이벤트 클래스 + */ + + var ComponentEvent = + /*#__PURE__*/ + function () { + /** + * Create a new instance of ComponentEvent. + * @ko ComponentEvent의 새로운 인스턴스를 생성한다. + * @param eventType The name of the event.이벤트 이름. + * @param props An object that contains additional event properties.추가적인 이벤트 프로퍼티 오브젝트. + */ + function ComponentEvent(eventType, props) { + var e_1, _a; + + this.eventType = eventType; + this._canceled = false; + if (!props) return; + + try { + for (var _b = __values$1(Object.keys(props)), _c = _b.next(); !_c.done; _c = _b.next()) { + var key = _c.value; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + + this[key] = props[key]; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + } + /** + * Stop the event. {@link ComponentEvent#isCanceled} will return `true` after. + * @ko 이벤트를 중단한다. 이후 {@link ComponentEvent#isCanceled}가 `true`를 반환한다. + */ + + + var __proto = ComponentEvent.prototype; + + __proto.stop = function () { + this._canceled = true; + }; + /** + * Returns a boolean value that indicates whether {@link ComponentEvent#stop} is called before. + * @ko {@link ComponentEvent#stop}이 호출되었는지 여부를 반환한다. + * @return {boolean} A boolean value that indicates whether {@link ComponentEvent#stop} is called before.이전에 {@link ComponentEvent#stop}이 불려졌는지 여부를 반환한다. + */ + + + __proto.isCanceled = function () { + return this._canceled; + }; + + return ComponentEvent; + }(); + + /** + * A class used to manage events in a component + * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스 + */ + + var Component = + /*#__PURE__*/ + function () { + /** + * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"} + */ + function Component() { + this._eventHandler = {}; + } + /** + * Trigger a custom event. + * @ko 커스텀 이벤트를 발생시킨다 + * @param {string | ComponentEvent} event The name of the custom event to be triggered or an instance of the ComponentEvent발생할 커스텀 이벤트의 이름 또는 ComponentEvent의 인스턴스 + * @param {any[]} params Event data to be sent when triggering a custom event 커스텀 이벤트가 발생할 때 전달할 데이터 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * beforeHi: ComponentEvent<{ foo: number; bar: string }>; + * hi: { foo: { a: number; b: boolean } }; + * someEvent: (foo: number, bar: string) => void; + * someOtherEvent: void; // When there's no event argument + * }> { + * some(){ + * if(this.trigger("beforeHi")){ // When event call to stop return false. + * this.trigger("hi");// fire hi event. + * } + * } + * } + * + * const some = new Some(); + * some.on("beforeHi", e => { + * if(condition){ + * e.stop(); // When event call to stop, `hi` event not call. + * } + * // `currentTarget` is component instance. + * console.log(some === e.currentTarget); // true + * + * typeof e.foo; // number + * typeof e.bar; // string + * }); + * some.on("hi", e => { + * typeof e.foo.b; // boolean + * }); + * // If you want to more know event design. You can see article. + * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F + * ``` + */ + + + var __proto = Component.prototype; + + __proto.trigger = function (event) { + var params = []; + + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + + var eventName = event instanceof ComponentEvent ? event.eventType : event; + + var handlers = __spread$1(this._eventHandler[eventName] || []); + + if (handlers.length <= 0) { + return this; + } + + if (event instanceof ComponentEvent) { + event.currentTarget = this; + handlers.forEach(function (handler) { + handler(event); + }); + } else { + handlers.forEach(function (handler) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + handler.apply(void 0, __spread$1(params)); + }); + } + + return this; + }; + /** + * Executed event just one time. + * @ko 이벤트가 한번만 실행된다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: ComponentEvent; + * }> { + * hi() { + * alert("hi"); + * } + * thing() { + * this.once("hi", this.hi); + * } + * } + * + * var some = new Some(); + * some.thing(); + * some.trigger(new ComponentEvent("hi")); + * // fire alert("hi"); + * some.trigger(new ComponentEvent("hi")); + * // Nothing happens + * ``` + */ + + + __proto.once = function (eventName, handlerToAttach) { + var _this = this; + + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + + for (var key in eventHash) { + this.once(key, eventHash[key]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var listener_1 = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } // eslint-disable-next-line @typescript-eslint/no-unsafe-call + + + handlerToAttach.apply(void 0, __spread$1(args)); + + _this.off(eventName, listener_1); + }; + + this.on(eventName, listener_1); + } + + return this; + }; + /** + * Checks whether an event has been attached to a component. + * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다. + * @param {string} eventName The name of the event to be attached 등록 여부를 확인할 이벤트의 이름 + * @return {boolean} Indicates whether the event is attached. 이벤트 등록 여부 + * @example + * ```ts + * import Component from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * some() { + * this.hasOn("hi");// check hi event. + * } + * } + * ``` + */ + + + __proto.hasOn = function (eventName) { + return !!this._eventHandler[eventName]; + }; + /** + * Attaches an event to a component. + * @ko 컴포넌트에 이벤트를 등록한다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.on("hi",this.hi); //attach event + * } + * } + * ``` + */ + + + __proto.on = function (eventName, handlerToAttach) { + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + + for (var name in eventHash) { + this.on(name, eventHash[name]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var handlerList = this._eventHandler[eventName]; + + if (isUndefined(handlerList)) { + this._eventHandler[eventName] = []; + handlerList = this._eventHandler[eventName]; + } + + handlerList.push(handlerToAttach); + } + + return this; + }; + /** + * Detaches an event from the component.
If the `eventName` is not given this will detach all event handlers attached.
If the `handlerToDetach` is not given, this will detach all event handlers for `eventName`. + * @ko 컴포넌트에 등록된 이벤트를 해제한다.
`eventName`이 주어지지 않았을 경우 모든 이벤트 핸들러를 제거한다.
`handlerToAttach`가 주어지지 않았을 경우 `eventName`에 해당하는 모든 이벤트 핸들러를 제거한다. + * @param {string?} eventName The name of the event to be detached 해제할 이벤트의 이름 + * @param {function?} handlerToDetach The handler function of the event to be detached 해제할 이벤트의 핸들러 함수 + * @return An instance of a component itself 컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.off("hi",this.hi); //detach event + * } + * } + * ``` + */ + + + __proto.off = function (eventName, handlerToDetach) { + var e_1, _a; // Detach all event handlers. + + + if (isUndefined(eventName)) { + this._eventHandler = {}; + return this; + } // Detach all handlers for eventname or detach event handlers by object. + + + if (isUndefined(handlerToDetach)) { + if (typeof eventName === "string") { + delete this._eventHandler[eventName]; + return this; + } else { + var eventHash = eventName; + + for (var name in eventHash) { + this.off(name, eventHash[name]); + } + + return this; + } + } // Detach single event handler + + + var handlerList = this._eventHandler[eventName]; + + if (handlerList) { + var idx = 0; + + try { + for (var handlerList_1 = __values$1(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) { + var handlerFunction = handlerList_1_1.value; + + if (handlerFunction === handlerToDetach) { + handlerList.splice(idx, 1); + + if (handlerList.length <= 0) { + delete this._eventHandler[eventName]; + } + + break; + } + + idx++; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1); + } finally { + if (e_1) throw e_1.error; + } + } + } + + return this; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @example + * Component.VERSION; // ex) 3.0.0 + * @memberof Component + */ + + + Component.VERSION = "3.0.1"; + return Component; + }(); + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + var ComponentEvent$1 = ComponentEvent; + + /** + * @this {Promise} + */ + function finallyConstructor(callback) { + var constructor = this.constructor; + return this.then( + function(value) { + // @ts-ignore + return constructor.resolve(callback()).then(function() { + return value; + }); + }, + function(reason) { + // @ts-ignore + return constructor.resolve(callback()).then(function() { + // @ts-ignore + return constructor.reject(reason); + }); + } + ); + } + + function allSettled(arr) { + var P = this; + return new P(function(resolve, reject) { + if (!(arr && typeof arr.length !== 'undefined')) { + return reject( + new TypeError( + typeof arr + + ' ' + + arr + + ' is not iterable(cannot read property Symbol(Symbol.iterator))' + ) + ); + } + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return resolve([]); + var remaining = args.length; + + function res(i, val) { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then; + if (typeof then === 'function') { + then.call( + val, + function(val) { + res(i, val); + }, + function(e) { + args[i] = { status: 'rejected', reason: e }; + if (--remaining === 0) { + resolve(args); + } + } + ); + return; + } + } + args[i] = { status: 'fulfilled', value: val }; + if (--remaining === 0) { + resolve(args); + } + } + + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + } + + // Store setTimeout reference so promise-polyfill will be unaffected by + // other code modifying setTimeout (like sinon.useFakeTimers()) + var setTimeoutFunc = setTimeout; + + function isArray(x) { + return Boolean(x && typeof x.length !== 'undefined'); + } + + function noop() {} + + // Polyfill for Function.prototype.bind + function bind(fn, thisArg) { + return function() { + fn.apply(thisArg, arguments); + }; + } + + /** + * @constructor + * @param {Function} fn + */ + function Promise$1(fn) { + if (!(this instanceof Promise$1)) + throw new TypeError('Promises must be constructed via new'); + if (typeof fn !== 'function') throw new TypeError('not a function'); + /** @type {!number} */ + this._state = 0; + /** @type {!boolean} */ + this._handled = false; + /** @type {Promise|undefined} */ + this._value = undefined; + /** @type {!Array} */ + this._deferreds = []; + + doResolve(fn, this); + } + + function handle(self, deferred) { + while (self._state === 3) { + self = self._value; + } + if (self._state === 0) { + self._deferreds.push(deferred); + return; + } + self._handled = true; + Promise$1._immediateFn(function() { + var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + (self._state === 1 ? resolve : reject)(deferred.promise, self._value); + return; + } + var ret; + try { + ret = cb(self._value); + } catch (e) { + reject(deferred.promise, e); + return; + } + resolve(deferred.promise, ret); + }); + } + + function resolve(self, newValue) { + try { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) + throw new TypeError('A promise cannot be resolved with itself.'); + if ( + newValue && + (typeof newValue === 'object' || typeof newValue === 'function') + ) { + var then = newValue.then; + if (newValue instanceof Promise$1) { + self._state = 3; + self._value = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(bind(then, newValue), self); + return; + } + } + self._state = 1; + self._value = newValue; + finale(self); + } catch (e) { + reject(self, e); + } + } + + function reject(self, newValue) { + self._state = 2; + self._value = newValue; + finale(self); + } + + function finale(self) { + if (self._state === 2 && self._deferreds.length === 0) { + Promise$1._immediateFn(function() { + if (!self._handled) { + Promise$1._unhandledRejectionFn(self._value); + } + }); + } + + for (var i = 0, len = self._deferreds.length; i < len; i++) { + handle(self, self._deferreds[i]); + } + self._deferreds = null; + } + + /** + * @constructor + */ + function Handler(onFulfilled, onRejected, promise) { + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; + } + + /** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ + function doResolve(fn, self) { + var done = false; + try { + fn( + function(value) { + if (done) return; + done = true; + resolve(self, value); + }, + function(reason) { + if (done) return; + done = true; + reject(self, reason); + } + ); + } catch (ex) { + if (done) return; + done = true; + reject(self, ex); + } + } + + Promise$1.prototype['catch'] = function(onRejected) { + return this.then(null, onRejected); + }; + + Promise$1.prototype.then = function(onFulfilled, onRejected) { + // @ts-ignore + var prom = new this.constructor(noop); + + handle(this, new Handler(onFulfilled, onRejected, prom)); + return prom; + }; + + Promise$1.prototype['finally'] = finallyConstructor; + + Promise$1.all = function(arr) { + return new Promise$1(function(resolve, reject) { + if (!isArray(arr)) { + return reject(new TypeError('Promise.all accepts an array')); + } + + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return resolve([]); + var remaining = args.length; + + function res(i, val) { + try { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then; + if (typeof then === 'function') { + then.call( + val, + function(val) { + res(i, val); + }, + reject + ); + return; + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex); + } + } + + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + }; + + Promise$1.allSettled = allSettled; + + Promise$1.resolve = function(value) { + if (value && typeof value === 'object' && value.constructor === Promise$1) { + return value; + } + + return new Promise$1(function(resolve) { + resolve(value); + }); + }; + + Promise$1.reject = function(value) { + return new Promise$1(function(resolve, reject) { + reject(value); + }); + }; + + Promise$1.race = function(arr) { + return new Promise$1(function(resolve, reject) { + if (!isArray(arr)) { + return reject(new TypeError('Promise.race accepts an array')); + } + + for (var i = 0, len = arr.length; i < len; i++) { + Promise$1.resolve(arr[i]).then(resolve, reject); + } + }); + }; + + // Use polyfill for setImmediate for performance gains + Promise$1._immediateFn = + // @ts-ignore + (typeof setImmediate === 'function' && + function(fn) { + // @ts-ignore + setImmediate(fn); + }) || + function(fn) { + setTimeoutFunc(fn, 0); + }; + + Promise$1._unhandledRejectionFn = function _unhandledRejectionFn(err) { + if (typeof console !== 'undefined' && console) { + console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console + } + }; + + /* + Copyright (c) 2015 NAVER Corp. + name: @egjs/agent + license: MIT + author: NAVER Corp. + repository: git+https://github.com/naver/agent.git + version: 2.2.1 + */ + function some(arr, callback) { + var length = arr.length; + + for (var i = 0; i < length; ++i) { + if (callback(arr[i], i)) { + return true; + } + } + + return false; + } + function find(arr, callback) { + var length = arr.length; + + for (var i = 0; i < length; ++i) { + if (callback(arr[i], i)) { + return arr[i]; + } + } + + return null; + } + function getUserAgent(agent) { + var userAgent = agent; + + if (typeof userAgent === "undefined") { + if (typeof navigator === "undefined" || !navigator) { + return ""; + } + + userAgent = navigator.userAgent || ""; + } + + return userAgent.toLowerCase(); + } + function execRegExp(pattern, text) { + try { + return new RegExp(pattern, "g").exec(text); + } catch (e) { + return null; + } + } + function hasUserAgentData() { + if (typeof navigator === "undefined" || !navigator || !navigator.userAgentData) { + return false; + } + + var userAgentData = navigator.userAgentData; + var brands = userAgentData.brands || userAgentData.uaList; + return !!(brands && brands.length); + } + function findVersion(versionTest, userAgent) { + var result = execRegExp("(" + versionTest + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent); + return result ? result[3] : ""; + } + function convertVersion(text) { + return text.replace(/_/g, "."); + } + function findPreset(presets, userAgent) { + var userPreset = null; + var version = "-1"; + some(presets, function (preset) { + var result = execRegExp("(" + preset.test + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent); + + if (!result || preset.brand) { + return false; + } + + userPreset = preset; + version = result[3] || "-1"; + + if (preset.versionAlias) { + version = preset.versionAlias; + } else if (preset.versionTest) { + version = findVersion(preset.versionTest.toLowerCase(), userAgent) || version; + } + + version = convertVersion(version); + return true; + }); + return { + preset: userPreset, + version: version + }; + } + function findBrand(brands, preset) { + return find(brands, function (_a) { + var brand = _a.brand; + return execRegExp("" + preset.test, brand.toLowerCase()); + }); + } + + var BROWSER_PRESETS = [{ + test: "phantomjs", + id: "phantomjs" + }, { + test: "whale", + id: "whale" + }, { + test: "edgios|edge|edg", + id: "edge" + }, { + test: "msie|trident|windows phone", + id: "ie", + versionTest: "iemobile|msie|rv" + }, { + test: "miuibrowser", + id: "miui browser" + }, { + test: "samsungbrowser", + id: "samsung internet" + }, { + test: "samsung", + id: "samsung internet", + versionTest: "version" + }, { + test: "chrome|crios", + id: "chrome" + }, { + test: "firefox|fxios", + id: "firefox" + }, { + test: "android", + id: "android browser", + versionTest: "version" + }, { + test: "safari|iphone|ipad|ipod", + id: "safari", + versionTest: "version" + }]; // chromium's engine(blink) is based on applewebkit 537.36. + + var CHROMIUM_PRESETS = [{ + test: "(?=.*applewebkit/(53[0-7]|5[0-2]|[0-4]))(?=.*\\schrome)", + id: "chrome" + }, { + test: "chromium", + id: "chrome" + }, { + test: "whale", + id: "chrome", + brand: true + }]; + var WEBKIT_PRESETS = [{ + test: "applewebkit", + id: "webkit" + }]; + var WEBVIEW_PRESETS = [{ + test: "(?=(iphone|ipad))(?!(.*version))", + id: "webview" + }, { + test: "(?=(android|iphone|ipad))(?=.*(naver|daum|; wv))", + id: "webview" + }, { + // test webview + test: "webview", + id: "webview" + }]; + var OS_PRESETS = [{ + test: "windows phone", + id: "windows phone" + }, { + test: "windows 2000", + id: "window", + versionAlias: "5.0" + }, { + test: "windows nt", + id: "window" + }, { + test: "iphone|ipad|ipod", + id: "ios", + versionTest: "iphone os|cpu os" + }, { + test: "mac os x", + id: "mac" + }, { + test: "android", + id: "android" + }, { + test: "tizen", + id: "tizen" + }, { + test: "webos|web0s", + id: "webos" + }]; + + function parseUserAgentData(osData) { + var userAgentData = navigator.userAgentData; + var brands = (userAgentData.uaList || userAgentData.brands).slice(); + var isMobile = userAgentData.mobile || false; + var firstBrand = brands[0]; + var browser = { + name: firstBrand.brand, + version: firstBrand.version, + majorVersion: -1, + webkit: false, + webview: some(WEBVIEW_PRESETS, function (preset) { + return findBrand(brands, preset); + }), + chromium: some(CHROMIUM_PRESETS, function (preset) { + return findBrand(brands, preset); + }) + }; + var os = { + name: "unknown", + version: "-1", + majorVersion: -1 + }; + browser.webkit = !browser.chromium && some(WEBKIT_PRESETS, function (preset) { + return findBrand(brands, preset); + }); + + if (osData) { + var platform_1 = osData.platform.toLowerCase(); + var result = find(OS_PRESETS, function (preset) { + return new RegExp("" + preset.test, "g").exec(platform_1); + }); + os.name = result ? result.id : platform_1; + os.version = osData.platformVersion; + } + + some(BROWSER_PRESETS, function (preset) { + var result = findBrand(brands, preset); + + if (!result) { + return false; + } + + browser.name = preset.id; + browser.version = osData ? osData.uaFullVersion : result.version; + return true; + }); + + if (navigator.platform === "Linux armv8l") { + os.name = "android"; + } else if (browser.webkit) { + os.name = isMobile ? "ios" : "mac"; + } + + if (os.name === "ios" && browser.webview) { + browser.version = "-1"; + } + + os.version = convertVersion(os.version); + browser.version = convertVersion(browser.version); + os.majorVersion = parseInt(os.version, 10); + browser.majorVersion = parseInt(browser.version, 10); + return { + browser: browser, + os: os, + isMobile: isMobile, + isHints: true + }; + } + + function parseUserAgent(userAgent) { + var nextAgent = getUserAgent(userAgent); + var isMobile = !!/mobi/g.exec(nextAgent); + var browser = { + name: "unknown", + version: "-1", + majorVersion: -1, + webview: !!findPreset(WEBVIEW_PRESETS, nextAgent).preset, + chromium: !!findPreset(CHROMIUM_PRESETS, nextAgent).preset, + webkit: false + }; + var os = { + name: "unknown", + version: "-1", + majorVersion: -1 + }; + + var _a = findPreset(BROWSER_PRESETS, nextAgent), + browserPreset = _a.preset, + browserVersion = _a.version; + + var _b = findPreset(OS_PRESETS, nextAgent), + osPreset = _b.preset, + osVersion = _b.version; + + browser.webkit = !browser.chromium && !!findPreset(WEBKIT_PRESETS, nextAgent).preset; + + if (osPreset) { + os.name = osPreset.id; + os.version = osVersion; + os.majorVersion = parseInt(osVersion, 10); + } + + if (browserPreset) { + browser.name = browserPreset.id; + browser.version = browserVersion; + + if (browser.webview && os.name === "ios" && browser.name !== "safari") { + browser.webview = false; + } + } + + browser.majorVersion = parseInt(browser.version, 10); + return { + browser: browser, + os: os, + isMobile: isMobile, + isHints: false + }; + } + /** + * Extracts browser and operating system information from the user agent string. + * @ko 유저 에이전트 문자열에서 브라우저와 운영체제 정보를 추출한다. + * @function eg.agent#agent + * @param - user agent string to parse 파싱할 유저에이전트 문자열 + * @return - agent Info 에이전트 정보 + * @example + import agent from "@egjs/agent"; + // eg.agent(); + const { os, browser, isMobile } = agent(); + */ + + function agent(userAgent) { + if (typeof userAgent === "undefined" && hasUserAgentData()) { + return parseUserAgentData(); + } else { + return parseUserAgent(userAgent); + } + } + + /* eslint-disable @typescript-eslint/no-implied-eval */ + /* eslint-disable no-new-func, no-nested-ternary */ + + var win = typeof window !== "undefined" && window.Math === Math ? window : typeof self !== "undefined" && self.Math === Math ? self : Function("return this")(); + /* eslint-enable no-new-func, no-nested-ternary */ + + var doc = win.document; + var nav = win.navigator; + var agent$1 = agent(); + var osName = agent$1.os.name; + var browserName = agent$1.browser.name; + var IS_IOS = osName === "ios"; + var IS_SAFARI_ON_DESKTOP = osName === "mac" && browserName === "safari"; + + /* eslint-disable @typescript-eslint/naming-convention */ + win.Float32Array = typeof win.Float32Array !== "undefined" ? win.Float32Array : win.Array; + var Float32Array$1 = win.Float32Array; + var getComputedStyle = win.getComputedStyle; + var userAgent = win.navigator && win.navigator.userAgent; + var SUPPORT_TOUCH = ("ontouchstart" in win); + var SUPPORT_DEVICEMOTION = ("ondevicemotion" in win); + var DeviceMotionEvent = win.DeviceMotionEvent; + var devicePixelRatio = win.devicePixelRatio; + + var TRANSFORM = function () { + var _a; + + var docStyle = (_a = doc === null || doc === void 0 ? void 0 : doc.documentElement.style) !== null && _a !== void 0 ? _a : {}; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in docStyle) { + return target[i]; + } + } + + return ""; + }(); // check for will-change support + + + var SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports && win.CSS.supports("will-change", "transform"); + var WEBXR_SUPPORTED = false; + + var checkXRSupport = function () { + var navigator = window.navigator; + + if (!navigator.xr) { + return; + } + + if (navigator.xr.isSessionSupported) { + navigator.xr.isSessionSupported("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } else if (navigator.xr.supportsSession) { + navigator.xr.supportsSession("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } + }; + + /* + Copyright (c) 2015 NAVER Corp. + name: @egjs/axes + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-axes + version: 3.3.0 + */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics$1 = function (d, b) { + extendStatics$1 = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics$1(d, b); + }; + + function __extends$1(d, b) { + extendStatics$1(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign$1 = function () { + __assign$1 = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign$1.apply(this, arguments); + }; + + /* eslint-disable no-new-func, no-nested-ternary */ + var win$1; + + if (typeof window === "undefined") { + // window is undefined in node.js + win$1 = { + navigator: { + userAgent: "" + } + }; + } else { + win$1 = window; + } + + var DIRECTION_NONE = 1; + var DIRECTION_LEFT = 2; + var DIRECTION_RIGHT = 4; + var DIRECTION_HORIZONTAL = 2 | 4; + var DIRECTION_UP = 8; + var DIRECTION_DOWN = 16; + var DIRECTION_VERTICAL = 8 | 16; + var DIRECTION_ALL = 2 | 4 | 8 | 16; + var MOUSE_LEFT = "left"; + var MOUSE_RIGHT = "right"; + var MOUSE_MIDDLE = "middle"; + var VELOCITY_INTERVAL = 16; + var IOS_EDGE_THRESHOLD = 30; + var IS_IOS_SAFARI = "ontouchstart" in win$1 && agent().browser.name === "safari"; + var TRANSFORM$1 = function () { + if (typeof document === "undefined") { + return ""; + } + + var bodyStyle = (document.head || document.getElementsByTagName("head")[0]).style; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in bodyStyle) { + return target[i]; + } + } + + return ""; + }(); + var PREVENT_DRAG_CSSPROPS = { + "user-select": "none", + "-webkit-user-drag": "none" + }; + + var toArray = function (nodes) { + // const el = Array.prototype.slice.call(nodes); + // for IE8 + var el = []; + + for (var i = 0, len = nodes.length; i < len; i++) { + el.push(nodes[i]); + } + + return el; + }; + var $ = function (param, multi) { + if (multi === void 0) { + multi = false; + } + + var el; + + if (typeof param === "string") { + // String (HTML, Selector) + // check if string is HTML tag format + var match = param.match(/^<([a-z]+)\s*([^>]*)>/); // creating element + + if (match) { + // HTML + var dummy = document.createElement("div"); + dummy.innerHTML = param; + el = toArray(dummy.childNodes); + } else { + // Selector + el = toArray(document.querySelectorAll(param)); + } + + if (!multi) { + el = el.length >= 1 ? el[0] : undefined; + } + } else if (param === win$1) { + // window + el = param; + } else if (param.nodeName && (param.nodeType === 1 || param.nodeType === 9)) { + // HTMLElement, Document + el = param; + } else if ("jQuery" in win$1 && param instanceof jQuery || param.constructor.prototype.jquery) { + // jQuery + el = multi ? param.toArray() : param.get(0); + } else if (Array.isArray(param)) { + el = param.map(function (v) { + return $(v); + }); + + if (!multi) { + el = el.length >= 1 ? el[0] : undefined; + } + } + + return el; + }; + var raf = win$1.requestAnimationFrame || win$1.webkitRequestAnimationFrame; + var caf = win$1.cancelAnimationFrame || win$1.webkitCancelAnimationFrame; + + if (raf && !caf) { + var keyInfo_1 = {}; + var oldraf_1 = raf; + + raf = function (callback) { + var wrapCallback = function (timestamp) { + if (keyInfo_1[key]) { + callback(timestamp); + } + }; + + var key = oldraf_1(wrapCallback); + keyInfo_1[key] = true; + return key; + }; + + caf = function (key) { + delete keyInfo_1[key]; + }; + } else if (!(raf && caf)) { + raf = function (callback) { + return win$1.setTimeout(function () { + callback(win$1.performance && win$1.performance.now && win$1.performance.now() || new Date().getTime()); + }, 16); + }; + + caf = win$1.clearTimeout; + } + /** + * A polyfill for the window.requestAnimationFrame() method. + * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame + * @private + */ + + + var requestAnimationFrame = function (fp) { + return raf(fp); + }; + /** + * A polyfill for the window.cancelAnimationFrame() method. It cancels an animation executed through a call to the requestAnimationFrame() method. + * @param {Number} key − The ID value returned through a call to the requestAnimationFrame() method. requestAnimationFrame() 메서드가 반환한 아이디 값 + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame + * @private + */ + + var cancelAnimationFrame = function (key) { + caf(key); + }; + var map = function (obj, callback) { + var tranformed = {}; + + for (var k in obj) { + if (k) { + tranformed[k] = callback(obj[k], k); + } + } + + return tranformed; + }; + var filter = function (obj, callback) { + var filtered = {}; + + for (var k in obj) { + if (k && callback(obj[k], k)) { + filtered[k] = obj[k]; + } + } + + return filtered; + }; + var every = function (obj, callback) { + for (var k in obj) { + if (k && !callback(obj[k], k)) { + return false; + } + } + + return true; + }; + var equal = function (target, base) { + return every(target, function (v, k) { + return v === base[k]; + }); + }; + var roundNumFunc = {}; + var roundNumber = function (num, roundUnit) { + // Cache for performance + if (!roundNumFunc[roundUnit]) { + roundNumFunc[roundUnit] = getRoundFunc(roundUnit); + } + + return roundNumFunc[roundUnit](num); + }; + var roundNumbers = function (num, roundUnit) { + if (!num || !roundUnit) { + return num; + } + + return map(num, function (value, key) { + return roundNumber(value, typeof roundUnit === "number" ? roundUnit : roundUnit[key]); + }); + }; + var getDecimalPlace = function (val) { + if (!isFinite(val)) { + return 0; + } + + var v = "" + val; + + if (v.indexOf("e") >= 0) { + // Exponential Format + // 1e-10, 1e-12 + var p = 0; + var e = 1; + + while (Math.round(val * e) / e !== val) { + e *= 10; + p++; + } + + return p; + } // In general, following has performance benefit. + // https://jsperf.com/precision-calculation + + + return v.indexOf(".") >= 0 ? v.length - v.indexOf(".") - 1 : 0; + }; + var inversePow = function (n) { + // replace Math.pow(10, -n) to solve floating point issue. + // eg. Math.pow(10, -4) => 0.00009999999999999999 + return 1 / Math.pow(10, n); + }; + var getRoundFunc = function (v) { + var p = v < 1 ? Math.pow(10, getDecimalPlace(v)) : 1; + return function (n) { + if (v === 0) { + return 0; + } + + return Math.round(Math.round(n / v) * v * p) / p; + }; + }; + var getAngle = function (posX, posY) { + return Math.atan2(posY, posX) * 180 / Math.PI; + }; + var isCssPropsFromAxes = function (originalCssProps) { + var same = true; + Object.keys(PREVENT_DRAG_CSSPROPS).forEach(function (prop) { + if (!originalCssProps || originalCssProps[prop] !== PREVENT_DRAG_CSSPROPS[prop]) { + same = false; + } + }); + return same; + }; + var setCssProps = function (element, option, direction) { + var _a; + + var touchActionMap = (_a = {}, _a[DIRECTION_NONE] = "auto", _a[DIRECTION_ALL] = "none", _a[DIRECTION_VERTICAL] = "pan-x", _a[DIRECTION_HORIZONTAL] = "pan-y", _a); + var oldCssProps = {}; + + if (element && element.style) { + var touchAction = option.touchAction ? option.touchAction : touchActionMap[direction]; + + var newCssProps_1 = __assign$1(__assign$1({}, PREVENT_DRAG_CSSPROPS), { + "touch-action": element.style["touch-action"] === "none" ? "none" : touchAction + }); + + Object.keys(newCssProps_1).forEach(function (prop) { + oldCssProps[prop] = element.style[prop]; + element.style[prop] = newCssProps_1[prop]; + }); + } + + return oldCssProps; + }; + var revertCssProps = function (element, originalCssProps) { + if (element && element.style && originalCssProps) { + Object.keys(originalCssProps).forEach(function (prop) { + element.style[prop] = originalCssProps[prop]; + }); + } + + return; + }; + + var EventManager = + /*#__PURE__*/ + function () { + function EventManager(_axes) { + this._axes = _axes; + } + /** + * This event is fired when a user holds an element on the screen of the device. + * @ko 사용자가 기기의 화면에 손을 대고 있을 때 발생하는 이벤트 + * @event Axes#hold + * @type {object} + * @property {Object.} pos coordinate 좌표 정보 + * @property {Object} input The instance of inputType where the event occurred이벤트가 발생한 inputType 인스턴스 + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("hold", function(event) { + * // event.pos + * // event.input + * // event.inputEvent + * // isTrusted + * }); + * ``` + */ + + + var __proto = EventManager.prototype; + + __proto.hold = function (pos, option) { + var roundPos = this._getRoundPos(pos).roundPos; + + this._axes.trigger(new ComponentEvent$1("hold", { + pos: roundPos, + input: option.input || null, + inputEvent: option.event || null, + isTrusted: true + })); + }; + /** + * Specifies the coordinates to move after the 'change' event. It works when the holding value of the change event is true. + * @ko 'change' 이벤트 이후 이동할 좌표를 지정한다. change이벤트의 holding 값이 true일 경우에 동작한다 + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("change", function(event) { + * event.holding && event.set({x: 10}); + * }); + * ``` + */ + + /** Specifies the animation coordinates to move after the 'release' or 'animationStart' events. + * @ko 'release' 또는 'animationStart' 이벤트 이후 이동할 좌표를 지정한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("animationStart", function(event) { + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + /** + * This event is fired when a user release an element on the screen of the device. + * @ko 사용자가 기기의 화면에서 손을 뗐을 때 발생하는 이벤트 + * @event Axes#release + * @type {object} + * @property {Object.} depaPos The coordinates when releasing an element손을 뗐을 때의 좌표 + * @property {Object.} destPos The coordinates to move to after releasing an element손을 뗀 뒤에 이동할 좌표 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Object.} bounceRatio If the coordinates at the time of release are in the bounce area, the current bounce value divided by the maximum bounce value 손을 뗐을 때의 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치. + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {Object} input The instance of inputType where the event occurred이벤트가 발생한 inputType 인스턴스 + * @property {setTo} setTo Specifies the animation coordinates to move after the event 이벤트 이후 이동할 애니메이션 좌표를 지정한다 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("release", function(event) { + * // event.depaPos + * // event.destPos + * // event.delta + * // event.input + * // event.inputEvent + * // event.setTo + * // event.isTrusted + * + * // if you want to change the animation coordinates to move after the 'release' event. + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + + __proto.triggerRelease = function (param) { + var _a = this._getRoundPos(param.destPos, param.depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + param.destPos = roundPos; + param.depaPos = roundDepa; + param.setTo = this._createUserControll(param.destPos, param.duration); + + this._axes.trigger(new ComponentEvent$1("release", __assign$1(__assign$1({}, param), { + bounceRatio: this._getBounceRatio(roundPos) + }))); + }; + /** + * This event is fired when coordinate changes. + * @ko 좌표가 변경됐을 때 발생하는 이벤트 + * @event Axes#change + * @type {object} + * @property {Object.} pos The coordinate 좌표 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Object.} bounceRatio If the current coordinates are in the bounce area, the current bounce value divided by the maximum bounce value 현재 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치. + * @property {Boolean} holding Indicates whether a user holds an element on the screen of the device.사용자가 기기의 화면을 누르고 있는지 여부 + * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {Object} inputEvent The event object received from inputType. If the value is changed by animation, it returns 'null'.inputType으로 부터 받은 이벤트 객체. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {set} set Specifies the coordinates to move after the event. It works when the holding value is true 이벤트 이후 이동할 좌표를 지정한다. holding 값이 true일 경우에 동작한다. + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("change", function(event) { + * // event.pos + * // event.delta + * // event.input + * // event.inputEvent + * // event.holding + * // event.set + * // event.isTrusted + * + * // if you want to change the coordinates to move after the 'change' event. + * // it works when the holding value of the change event is true. + * event.holding && event.set({x: 10}); + * }); + * ``` + */ + + + __proto.triggerChange = function (pos, depaPos, option, holding) { + if (holding === void 0) { + holding = false; + } + + var animationManager = this.animationManager; + var axisManager = animationManager.axisManager; + var eventInfo = animationManager.getEventInfo(); + + var _a = this._getRoundPos(pos, depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + var moveTo = axisManager.moveTo(roundPos, roundDepa); + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.event) || null; + var param = { + pos: moveTo.pos, + delta: moveTo.delta, + bounceRatio: this._getBounceRatio(moveTo.pos), + holding: holding, + inputEvent: inputEvent, + isTrusted: !!inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.input) || null, + set: inputEvent ? this._createUserControll(moveTo.pos) : function () {} + }; + var event = new ComponentEvent$1("change", param); + + this._axes.trigger(event); + + if (inputEvent) { + axisManager.set(param.set().destPos); + } + + return !event.isCanceled(); + }; + /** + * This event is fired when animation starts. + * @ko 에니메이션이 시작할 때 발생한다. + * @event Axes#animationStart + * @type {object} + * @property {Object.} depaPos The coordinates when animation starts애니메이션이 시작 되었을 때의 좌표 + * @property {Object.} destPos The coordinates to move to. If you change this value, you can run the animation이동할 좌표. 이값을 변경하여 애니메이션을 동작시킬수 있다 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Number} duration Duration of the animation (unit: ms). If you change this value, you can control the animation duration time.애니메이션 진행 시간(단위: ms). 이값을 변경하여 애니메이션의 이동시간을 조절할 수 있다. + * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {setTo} setTo Specifies the animation coordinates to move after the event 이벤트 이후 이동할 애니메이션 좌표를 지정한다 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("release", function(event) { + * // event.depaPos + * // event.destPos + * // event.delta + * // event.input + * // event.inputEvent + * // event.setTo + * // event.isTrusted + * + * // if you want to change the animation coordinates to move after the 'animationStart' event. + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + + __proto.triggerAnimationStart = function (param) { + var _a = this._getRoundPos(param.destPos, param.depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + param.destPos = roundPos; + param.depaPos = roundDepa; + param.setTo = this._createUserControll(param.destPos, param.duration); + var event = new ComponentEvent$1("animationStart", param); + + this._axes.trigger(event); + + return !event.isCanceled(); + }; + /** + * This event is fired when animation ends. + * @ko 에니메이션이 끝났을 때 발생한다. + * @event Axes#animationEnd + * @type {object} + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("animationEnd", function(event) { + * // event.isTrusted + * }); + * ``` + */ + + + __proto.triggerAnimationEnd = function (isTrusted) { + if (isTrusted === void 0) { + isTrusted = false; + } + + this._axes.trigger(new ComponentEvent$1("animationEnd", { + isTrusted: isTrusted + })); + }; + /** + * This event is fired when all actions have been completed. + * @ko 에니메이션이 끝났을 때 발생한다. + * @event Axes#finish + * @type {object} + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("finish", function(event) { + * // event.isTrusted + * }); + * ``` + */ + + + __proto.triggerFinish = function (isTrusted) { + if (isTrusted === void 0) { + isTrusted = false; + } + + this._axes.trigger(new ComponentEvent$1("finish", { + isTrusted: isTrusted + })); + }; + + __proto.setAnimationManager = function (animationManager) { + this.animationManager = animationManager; + }; + + __proto.destroy = function () { + this._axes.off(); + }; + + __proto._createUserControll = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } // to controll + + + var userControl = { + destPos: __assign$1({}, pos), + duration: duration + }; + return function (toPos, userDuration) { + if (toPos) { + userControl.destPos = __assign$1({}, toPos); + } + + if (userDuration !== undefined) { + userControl.duration = userDuration; + } + + return userControl; + }; + }; + + __proto._getRoundPos = function (pos, depaPos) { + // round value if round exist + var roundUnit = this._axes.options.round; // if (round == null) { + // return {pos, depaPos}; // undefined, undefined + // } + + return { + roundPos: roundNumbers(pos, roundUnit), + roundDepa: roundNumbers(depaPos, roundUnit) + }; + }; + + __proto._getBounceRatio = function (pos) { + return this._axes.axisManager.map(pos, function (v, opt) { + if (v < opt.range[0] && opt.bounce[0] !== 0) { + return (opt.range[0] - v) / opt.bounce[0]; + } else if (v > opt.range[1] && opt.bounce[1] !== 0) { + return (v - opt.range[1]) / opt.bounce[1]; + } else { + return 0; + } + }); + }; + + return EventManager; + }(); + + var InterruptManager = + /*#__PURE__*/ + function () { + function InterruptManager(_options) { + this._options = _options; + this._prevented = false; // check whether the animation event was prevented + } + + var __proto = InterruptManager.prototype; + + __proto.isInterrupting = function () { + // when interruptable is 'true', return value is always 'true'. + return this._options.interruptable || this._prevented; + }; + + __proto.isInterrupted = function () { + return !this._options.interruptable && this._prevented; + }; + + __proto.setInterrupt = function (prevented) { + if (!this._options.interruptable) { + this._prevented = prevented; + } + }; + + return InterruptManager; + }(); + + var getInsidePosition = function (destPos, range, circular, bounce) { + var toDestPos = destPos; + var targetRange = [circular[0] ? range[0] : bounce ? range[0] - bounce[0] : range[0], circular[1] ? range[1] : bounce ? range[1] + bounce[1] : range[1]]; + toDestPos = Math.max(targetRange[0], toDestPos); + toDestPos = Math.min(targetRange[1], toDestPos); + return toDestPos; + }; // determine outside + + var isOutside = function (pos, range) { + return pos < range[0] || pos > range[1]; + }; // determine whether position has reached the maximum moveable area + + var isEndofBounce = function (pos, range, bounce, circular) { + return !circular[0] && pos === range[0] - bounce[0] || !circular[1] && pos === range[1] + bounce[1]; + }; + var getDuration = function (distance, deceleration) { + var duration = Math.sqrt(distance / deceleration * 2); // when duration is under 100, then value is zero + + return duration < 100 ? 0 : duration; + }; + var isCircularable = function (destPos, range, circular) { + return circular[1] && destPos > range[1] || circular[0] && destPos < range[0]; + }; + var getCirculatedPos = function (pos, range, circular) { + var toPos = pos; + var min = range[0]; + var max = range[1]; + var length = max - min; + + if (circular[1] && pos > max) { + // right + toPos = (toPos - max) % length + min; + } + + if (circular[0] && pos < min) { + // left + toPos = (toPos - min) % length + max; + } + + return toPos; + }; + + var AxisManager = + /*#__PURE__*/ + function () { + function AxisManager(_axis) { + var _this = this; + + this._axis = _axis; + + this._complementOptions(); + + this._pos = Object.keys(this._axis).reduce(function (acc, v) { + acc[v] = _this._axis[v].range[0]; + return acc; + }, {}); + } + + var __proto = AxisManager.prototype; + + __proto.getDelta = function (depaPos, destPos) { + var fullDepaPos = this.get(depaPos); + return map(this.get(destPos), function (v, k) { + return v - fullDepaPos[k]; + }); + }; + + __proto.get = function (axes) { + var _this = this; + + if (axes && Array.isArray(axes)) { + return axes.reduce(function (acc, v) { + if (v && v in _this._pos) { + acc[v] = _this._pos[v]; + } + + return acc; + }, {}); + } else { + return __assign$1(__assign$1({}, this._pos), axes || {}); + } + }; + + __proto.moveTo = function (pos, depaPos) { + if (depaPos === void 0) { + depaPos = this._pos; + } + + var delta = map(this._pos, function (v, key) { + return key in pos && key in depaPos ? pos[key] - depaPos[key] : 0; + }); + this.set(this.map(pos, function (v, opt) { + return opt ? getCirculatedPos(v, opt.range, opt.circular) : 0; + })); + return { + pos: __assign$1({}, this._pos), + delta: delta + }; + }; + + __proto.set = function (pos) { + for (var k in pos) { + if (k && k in this._pos) { + this._pos[k] = pos[k]; + } + } + }; + + __proto.every = function (pos, callback) { + var axisOptions = this._axis; + return every(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.filter = function (pos, callback) { + var axisOptions = this._axis; + return filter(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.map = function (pos, callback) { + var axisOptions = this._axis; + return map(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.isOutside = function (axes) { + return !this.every(axes ? this.get(axes) : this._pos, function (v, opt) { + return !isOutside(v, opt.range); + }); + }; + + __proto.getAxisOptions = function (key) { + return this._axis[key]; + }; + /** + * set up 'css' expression + * @private + */ + + + __proto._complementOptions = function () { + var _this = this; + + Object.keys(this._axis).forEach(function (axis) { + _this._axis[axis] = __assign$1({ + range: [0, 100], + bounce: [0, 0], + circular: [false, false] + }, _this._axis[axis]); + ["bounce", "circular"].forEach(function (v) { + var axisOption = _this._axis; + var key = axisOption[axis][v]; + + if (/string|number|boolean/.test(typeof key)) { + axisOption[axis][v] = [key, key]; + } + }); + }); + }; + + return AxisManager; + }(); + + var SUPPORT_TOUCH$1 = ("ontouchstart" in win$1); + var SUPPORT_POINTER = ("PointerEvent" in win$1); + var SUPPORT_MSPOINTER = ("MSPointerEvent" in win$1); + var SUPPORT_POINTER_EVENTS = SUPPORT_POINTER || SUPPORT_MSPOINTER; + + var EventInput = + /*#__PURE__*/ + function () { + function EventInput() { + var _this = this; + + this._stopContextMenu = function (event) { + event.preventDefault(); + win$1.removeEventListener("contextmenu", _this._stopContextMenu); + }; + } + + var __proto = EventInput.prototype; + + __proto.extendEvent = function (event) { + var _a; + + var prevEvent = this.prevEvent; + + var center = this._getCenter(event); + + var movement = prevEvent ? this._getMovement(event) : { + x: 0, + y: 0 + }; + var scale = prevEvent ? this._getScale(event) : 1; + var angle = prevEvent ? getAngle(center.x - prevEvent.center.x, center.y - prevEvent.center.y) : 0; + var deltaX = prevEvent ? prevEvent.deltaX + movement.x : movement.x; + var deltaY = prevEvent ? prevEvent.deltaY + movement.y : movement.y; + var offsetX = movement.x; + var offsetY = movement.y; + var latestInterval = this._latestInterval; + var timeStamp = Date.now(); + var deltaTime = latestInterval ? timeStamp - latestInterval.timestamp : 0; + var velocityX = prevEvent ? prevEvent.velocityX : 0; + var velocityY = prevEvent ? prevEvent.velocityY : 0; + + if (!latestInterval || deltaTime >= VELOCITY_INTERVAL) { + if (latestInterval) { + _a = [(deltaX - latestInterval.deltaX) / deltaTime, (deltaY - latestInterval.deltaY) / deltaTime], velocityX = _a[0], velocityY = _a[1]; + } + + this._latestInterval = { + timestamp: timeStamp, + deltaX: deltaX, + deltaY: deltaY + }; + } + + return { + srcEvent: event, + scale: scale, + angle: angle, + center: center, + deltaX: deltaX, + deltaY: deltaY, + offsetX: offsetX, + offsetY: offsetY, + velocityX: velocityX, + velocityY: velocityY, + preventSystemEvent: true + }; + }; + + __proto._getDistance = function (start, end) { + var x = end.clientX - start.clientX; + var y = end.clientY - start.clientY; + return Math.sqrt(x * x + y * y); + }; + + __proto._getButton = function (event) { + var buttonCodeMap = { + 1: MOUSE_LEFT, + 2: MOUSE_RIGHT, + 4: MOUSE_MIDDLE + }; + var button = this._isTouchEvent(event) ? MOUSE_LEFT : buttonCodeMap[event.buttons]; + return button ? button : null; + }; + + __proto._isTouchEvent = function (event) { + return event.type.indexOf("touch") > -1; + }; + + __proto._isValidButton = function (button, inputButton) { + return inputButton.indexOf(button) > -1; + }; + + __proto._preventMouseButton = function (event, button) { + if (button === MOUSE_RIGHT) { + win$1.addEventListener("contextmenu", this._stopContextMenu); + } else if (button === MOUSE_MIDDLE) { + event.preventDefault(); + } + }; + + return EventInput; + }(); + + var MouseEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(MouseEventInput, _super); + + function MouseEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["mousedown"]; + _this.move = ["mousemove"]; + _this.end = ["mouseup"]; + return _this; + } + + var __proto = MouseEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function () { + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + return; + }; + + __proto.getTouches = function () { + return 0; + }; + + __proto._getScale = function () { + return 1; + }; + + __proto._getCenter = function (event) { + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + return { + x: event.clientX - prev.clientX, + y: event.clientY - prev.clientY + }; + }; + + return MouseEventInput; + }(EventInput); + + var TouchEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(TouchEventInput, _super); + + function TouchEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["touchstart"]; + _this.move = ["touchmove"]; + _this.end = ["touchend", "touchcancel"]; + return _this; + } + + var __proto = TouchEventInput.prototype; + + __proto.onEventStart = function (event) { + this._baseTouches = event.touches; + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event) { + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + this._baseTouches = event.touches; + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._baseTouches = null; + return; + }; + + __proto.getTouches = function (event) { + return event.touches.length; + }; + + __proto._getScale = function (event) { + if (event.touches.length !== 2 || this._baseTouches.length < 2) { + return null; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(event.touches[0], event.touches[1]) / this._getDistance(this._baseTouches[0], this._baseTouches[1]); + }; + + __proto._getCenter = function (event) { + return { + x: event.touches[0].clientX, + y: event.touches[0].clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + + if (event.touches[0].identifier !== prev.touches[0].identifier) { + return { + x: 0, + y: 0 + }; + } + + return { + x: event.touches[0].clientX - prev.touches[0].clientX, + y: event.touches[0].clientY - prev.touches[0].clientY + }; + }; + + return TouchEventInput; + }(EventInput); + + var PointerEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(PointerEventInput, _super); + + function PointerEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = SUPPORT_POINTER ? ["pointerdown"] : ["MSPointerDown"]; + _this.move = SUPPORT_POINTER ? ["pointermove"] : ["MSPointerMove"]; + _this.end = SUPPORT_POINTER ? ["pointerup", "pointercancel"] : ["MSPointerUp", "MSPointerCancel"]; // store first, recent inputs for each event id + + _this._firstInputs = []; + _this._recentInputs = []; + return _this; + } + + var __proto = PointerEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + this._updatePointerEvent(event); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + this._updatePointerEvent(event); + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + this._removePointerEvent(event); + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._firstInputs = []; + this._recentInputs = []; + return; + }; + + __proto.getTouches = function () { + return this._recentInputs.length; + }; + + __proto._getScale = function () { + if (this._recentInputs.length !== 2) { + return null; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(this._recentInputs[0], this._recentInputs[1]) / this._getDistance(this._firstInputs[0], this._firstInputs[1]); + }; + + __proto._getCenter = function (event) { + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + + if (event.pointerId !== prev.pointerId) { + return { + x: 0, + y: 0 + }; + } + + return { + x: event.clientX - prev.clientX, + y: event.clientY - prev.clientY + }; + }; + + __proto._updatePointerEvent = function (event) { + var _this = this; + + var addFlag = false; + + this._recentInputs.forEach(function (e, i) { + if (e.pointerId === event.pointerId) { + addFlag = true; + _this._recentInputs[i] = event; + } + }); + + if (!addFlag) { + this._firstInputs.push(event); + + this._recentInputs.push(event); + } + }; + + __proto._removePointerEvent = function (event) { + this._firstInputs = this._firstInputs.filter(function (x) { + return x.pointerId !== event.pointerId; + }); + this._recentInputs = this._recentInputs.filter(function (x) { + return x.pointerId !== event.pointerId; + }); + }; + + return PointerEventInput; + }(EventInput); + + var TouchMouseEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(TouchMouseEventInput, _super); + + function TouchMouseEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["mousedown", "touchstart"]; + _this.move = ["mousemove", "touchmove"]; + _this.end = ["mouseup", "touchend", "touchcancel"]; + return _this; + } + + var __proto = TouchMouseEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (this._isTouchEvent(event)) { + this._baseTouches = event.touches; + } + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + if (this._isTouchEvent(event)) { + this._baseTouches = event.touches; + } + + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._baseTouches = null; + return; + }; + + __proto.getTouches = function (event) { + return this._isTouchEvent(event) ? event.touches.length : 0; + }; + + __proto._getScale = function (event) { + if (this._isTouchEvent(event)) { + if (event.touches.length !== 2 || this._baseTouches.length < 2) { + return 1; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(event.touches[0], event.touches[1]) / this._getDistance(this._baseTouches[0], this._baseTouches[1]); + } + + return this.prevEvent.scale; + }; + + __proto._getCenter = function (event) { + if (this._isTouchEvent(event)) { + return { + x: event.touches[0].clientX, + y: event.touches[0].clientY + }; + } + + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var _this = this; + + var prev = this.prevEvent.srcEvent; + + var _a = [event, prev].map(function (e) { + if (_this._isTouchEvent(e)) { + return { + id: e.touches[0].identifier, + x: e.touches[0].clientX, + y: e.touches[0].clientY + }; + } + + return { + id: null, + x: e.clientX, + y: e.clientY + }; + }), + nextSpot = _a[0], + prevSpot = _a[1]; + + return nextSpot.id === prevSpot.id ? { + x: nextSpot.x - prevSpot.x, + y: nextSpot.y - prevSpot.y + } : { + x: 0, + y: 0 + }; + }; + + return TouchMouseEventInput; + }(EventInput); + + var toAxis = function (source, offset) { + return offset.reduce(function (acc, v, i) { + if (source[i]) { + acc[source[i]] = v; + } + + return acc; + }, {}); + }; + var convertInputType = function (inputType) { + if (inputType === void 0) { + inputType = []; + } + + var hasTouch = false; + var hasMouse = false; + var hasPointer = false; + inputType.forEach(function (v) { + switch (v) { + case "mouse": + hasMouse = true; + break; + + case "touch": + hasTouch = SUPPORT_TOUCH$1; + break; + + case "pointer": + hasPointer = SUPPORT_POINTER_EVENTS; + // no default + } + }); + + if (hasPointer) { + return new PointerEventInput(); + } else if (hasTouch && hasMouse) { + return new TouchMouseEventInput(); + } else if (hasTouch) { + return new TouchEventInput(); + } else if (hasMouse) { + return new MouseEventInput(); + } + + return null; + }; + + var InputObserver = + /*#__PURE__*/ + function () { + function InputObserver(_a) { + var options = _a.options, + interruptManager = _a.interruptManager, + eventManager = _a.eventManager, + axisManager = _a.axisManager, + animationManager = _a.animationManager; + this._isOutside = false; + this._moveDistance = null; + this._isStopped = false; + this.options = options; + this._interruptManager = interruptManager; + this._eventManager = eventManager; + this._axisManager = axisManager; + this._animationManager = animationManager; + } + + var __proto = InputObserver.prototype; + + __proto.get = function (input) { + return this._axisManager.get(input.axes); + }; + + __proto.hold = function (input, event) { + if (this._interruptManager.isInterrupted() || !input.axes.length) { + return; + } + + var changeOption = { + input: input, + event: event + }; + this._isStopped = false; + + this._interruptManager.setInterrupt(true); + + this._animationManager.stopAnimation(changeOption); + + if (!this._moveDistance) { + this._eventManager.hold(this._axisManager.get(), changeOption); + } + + this._isOutside = this._axisManager.isOutside(input.axes); + this._moveDistance = this._axisManager.get(input.axes); + }; + + __proto.change = function (input, event, offset, useAnimation) { + if (this._isStopped || !this._interruptManager.isInterrupting() || this._axisManager.every(offset, function (v) { + return v === 0; + })) { + return; + } + + var nativeEvent = event.srcEvent ? event.srcEvent : event; + + if (nativeEvent.__childrenAxesAlreadyChanged) { + return; + } + + var depaPos = this._moveDistance || this._axisManager.get(input.axes); + + var destPos; // for outside logic + + destPos = map(depaPos, function (v, k) { + return v + (offset[k] || 0); + }); + + if (this._moveDistance) { + this._moveDistance = this._axisManager.map(destPos, function (v, _a) { + var circular = _a.circular, + range = _a.range; + return circular && (circular[0] || circular[1]) ? getCirculatedPos(v, range, circular) : v; + }); + } // from outside to inside + + + if (this._isOutside && this._axisManager.every(depaPos, function (v, opt) { + return !isOutside(v, opt.range); + })) { + this._isOutside = false; + } + + depaPos = this._atOutside(depaPos); + destPos = this._atOutside(destPos); + + if (!this.options.nested || !this._isEndofAxis(offset, depaPos, destPos)) { + nativeEvent.__childrenAxesAlreadyChanged = true; + } + + var changeOption = { + input: input, + event: event + }; + + if (useAnimation) { + var duration = this._animationManager.getDuration(destPos, depaPos); + + this._animationManager.animateTo(destPos, duration, changeOption); + } else { + var isCanceled = !this._eventManager.triggerChange(destPos, depaPos, changeOption, true); + + if (isCanceled) { + this._isStopped = true; + this._moveDistance = null; + + this._animationManager.finish(false); + } + } + }; + + __proto.release = function (input, event, velocity, inputDuration) { + if (this._isStopped || !this._interruptManager.isInterrupting() || !this._moveDistance) { + return; + } + + var nativeEvent = event.srcEvent ? event.srcEvent : event; + + if (nativeEvent.__childrenAxesAlreadyReleased) { + velocity = velocity.map(function () { + return 0; + }); + } + + var pos = this._axisManager.get(input.axes); + + var depaPos = this._axisManager.get(); + + var displacement = this._animationManager.getDisplacement(velocity); + + var offset = toAxis(input.axes, displacement); + + var destPos = this._axisManager.get(this._axisManager.map(offset, function (v, opt, k) { + if (opt.circular && (opt.circular[0] || opt.circular[1])) { + return pos[k] + v; + } else { + return getInsidePosition(pos[k] + v, opt.range, opt.circular, opt.bounce); + } + })); + + nativeEvent.__childrenAxesAlreadyReleased = true; + + var duration = this._animationManager.getDuration(destPos, pos, inputDuration); + + if (duration === 0) { + destPos = __assign$1({}, depaPos); + } // prepare params + + + var param = { + depaPos: depaPos, + destPos: destPos, + duration: duration, + delta: this._axisManager.getDelta(depaPos, destPos), + inputEvent: event, + input: input, + isTrusted: true + }; + + this._eventManager.triggerRelease(param); + + this._moveDistance = null; // to contol + + var userWish = this._animationManager.getUserControl(param); + + var isEqual = equal(userWish.destPos, depaPos); + var changeOption = { + input: input, + event: event + }; + + if (isEqual || userWish.duration === 0) { + if (!isEqual) { + this._eventManager.triggerChange(userWish.destPos, depaPos, changeOption, true); + } + + this._interruptManager.setInterrupt(false); + + if (this._axisManager.isOutside()) { + this._animationManager.restore(changeOption); + } else { + this._eventManager.triggerFinish(true); + } + } else { + this._animationManager.animateTo(userWish.destPos, userWish.duration, changeOption); + } + }; // when move pointer is held in outside + + + __proto._atOutside = function (pos) { + var _this = this; + + if (this._isOutside) { + return this._axisManager.map(pos, function (v, opt) { + var tn = opt.range[0] - opt.bounce[0]; + var tx = opt.range[1] + opt.bounce[1]; + return v > tx ? tx : v < tn ? tn : v; + }); + } else { + return this._axisManager.map(pos, function (v, opt) { + var min = opt.range[0]; + var max = opt.range[1]; + var out = opt.bounce; + var circular = opt.circular; + + if (circular && (circular[0] || circular[1])) { + return v; + } else if (v < min) { + // left + return min - _this._animationManager.interpolate(min - v, out[0]); + } else if (v > max) { + // right + return max + _this._animationManager.interpolate(v - max, out[1]); + } + + return v; + }); + } + }; + + __proto._isEndofAxis = function (offset, depaPos, destPos) { + return this._axisManager.every(depaPos, function (value, option, key) { + return offset[key] === 0 || depaPos[key] === destPos[key] && isEndofBounce(value, option.range, option.bounce, option.circular); + }); + }; + + return InputObserver; + }(); + + var clamp = function (value, min, max) { + return Math.max(Math.min(value, max), min); + }; + + var AnimationManager = + /*#__PURE__*/ + function () { + function AnimationManager(_a) { + var options = _a.options, + interruptManager = _a.interruptManager, + eventManager = _a.eventManager, + axisManager = _a.axisManager; + this._options = options; + this.interruptManager = interruptManager; + this.eventManager = eventManager; + this.axisManager = axisManager; + this.animationEnd = this.animationEnd.bind(this); + } + + var __proto = AnimationManager.prototype; + + __proto.getDuration = function (depaPos, destPos, wishDuration) { + var _this = this; + + var duration; + + if (typeof wishDuration !== "undefined") { + duration = wishDuration; + } else { + var durations_1 = map(destPos, function (v, k) { + return getDuration(Math.abs(v - depaPos[k]), _this._options.deceleration); + }); + duration = Object.keys(durations_1).reduce(function (max, v) { + return Math.max(max, durations_1[v]); + }, -Infinity); + } + + return clamp(duration, this._options.minimumDuration, this._options.maximumDuration); + }; + + __proto.getDisplacement = function (velocity) { + var totalVelocity = Math.pow(velocity.reduce(function (total, v) { + return total + v * v; + }, 0), 1 / velocity.length); + var duration = Math.abs(totalVelocity / -this._options.deceleration); + return velocity.map(function (v) { + return v / 2 * duration; + }); + }; + + __proto.stopAnimation = function (option) { + if (this._animateParam) { + var orgPos_1 = this.axisManager.get(); + var pos = this.axisManager.map(orgPos_1, function (v, opt) { + return getCirculatedPos(v, opt.range, opt.circular); + }); + + if (!every(pos, function (v, k) { + return orgPos_1[k] === v; + })) { + this.eventManager.triggerChange(pos, orgPos_1, option, !!option); + } + + this._animateParam = null; + + if (this._raf) { + cancelAnimationFrame(this._raf); + } + + this._raf = null; + this.eventManager.triggerAnimationEnd(!!(option === null || option === void 0 ? void 0 : option.event)); + } + }; + + __proto.getEventInfo = function () { + if (this._animateParam && this._animateParam.input && this._animateParam.inputEvent) { + return { + input: this._animateParam.input, + event: this._animateParam.inputEvent + }; + } else { + return null; + } + }; + + __proto.restore = function (option) { + var pos = this.axisManager.get(); + var destPos = this.axisManager.map(pos, function (v, opt) { + return Math.min(opt.range[1], Math.max(opt.range[0], v)); + }); + this.stopAnimation(); + this.animateTo(destPos, this.getDuration(pos, destPos), option); + }; + + __proto.animationEnd = function () { + var beforeParam = this.getEventInfo(); + this._animateParam = null; // for Circular + + var circularTargets = this.axisManager.filter(this.axisManager.get(), function (v, opt) { + return isCircularable(v, opt.range, opt.circular); + }); + + if (Object.keys(circularTargets).length > 0) { + this.setTo(this.axisManager.map(circularTargets, function (v, opt) { + return getCirculatedPos(v, opt.range, opt.circular); + })); + } + + this.interruptManager.setInterrupt(false); + this.eventManager.triggerAnimationEnd(!!beforeParam); + + if (this.axisManager.isOutside()) { + this.restore(beforeParam); + } else { + this.finish(!!beforeParam); + } + }; + + __proto.finish = function (isTrusted) { + this._animateParam = null; + this.interruptManager.setInterrupt(false); + this.eventManager.triggerFinish(isTrusted); + }; + + __proto.getUserControl = function (param) { + var userWish = param.setTo(); + userWish.destPos = this.axisManager.get(userWish.destPos); + userWish.duration = clamp(userWish.duration, this._options.minimumDuration, this._options.maximumDuration); + return userWish; + }; + + __proto.animateTo = function (destPos, duration, option) { + var _this = this; + + this.stopAnimation(); + + var param = this._createAnimationParam(destPos, duration, option); + + var depaPos = __assign$1({}, param.depaPos); + + var retTrigger = this.eventManager.triggerAnimationStart(param); // to control + + var userWish = this.getUserControl(param); // You can't stop the 'animationStart' event when 'circular' is true. + + if (!retTrigger && this.axisManager.every(userWish.destPos, function (v, opt) { + return isCircularable(v, opt.range, opt.circular); + })) { + console.warn("You can't stop the 'animation' event when 'circular' is true."); + } + + if (retTrigger && !equal(userWish.destPos, depaPos)) { + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || null; + + this._animateLoop({ + depaPos: depaPos, + destPos: userWish.destPos, + duration: userWish.duration, + delta: this.axisManager.getDelta(depaPos, userWish.destPos), + isTrusted: !!inputEvent, + inputEvent: inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || null + }, function () { + return _this.animationEnd(); + }); + } + }; + + __proto.setTo = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + var axes = Object.keys(pos); + var orgPos = this.axisManager.get(axes); + + if (equal(pos, orgPos)) { + return this; + } + + this.interruptManager.setInterrupt(true); + var movedPos = filter(pos, function (v, k) { + return orgPos[k] !== v; + }); + + if (!Object.keys(movedPos).length) { + return this; + } + + movedPos = this.axisManager.map(movedPos, function (v, opt) { + var range = opt.range, + circular = opt.circular; + + if (circular && (circular[0] || circular[1])) { + return v; + } else { + return getInsidePosition(v, range, circular); + } + }); + + if (equal(movedPos, orgPos)) { + return this; + } + + if (duration > 0) { + this.animateTo(movedPos, duration); + } else { + this.stopAnimation(); + this.eventManager.triggerChange(movedPos); + this.finish(false); + } + + return this; + }; + + __proto.setBy = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + return this.setTo(map(this.axisManager.get(Object.keys(pos)), function (v, k) { + return v + pos[k]; + }), duration); + }; + + __proto._createAnimationParam = function (pos, duration, option) { + var depaPos = this.axisManager.get(); + var destPos = pos; + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || null; + return { + depaPos: depaPos, + destPos: destPos, + duration: clamp(duration, this._options.minimumDuration, this._options.maximumDuration), + delta: this.axisManager.getDelta(depaPos, destPos), + inputEvent: inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || null, + isTrusted: !!inputEvent, + done: this.animationEnd + }; + }; + + __proto._animateLoop = function (param, complete) { + var _this = this; + + if (param.duration) { + this._animateParam = __assign$1(__assign$1({}, param), { + startTime: new Date().getTime() + }); + var originalIntendedPos_1 = map(param.destPos, function (v) { + return v; + }); + + var state_1 = this._initState(this._animateParam); + + var loop_1 = function () { + _this._raf = null; + var animateParam = _this._animateParam; + + var nextState = _this._getNextState(state_1); + + var isCanceled = !_this.eventManager.triggerChange(nextState.pos, state_1.pos); + state_1 = nextState; + + if (nextState.finished) { + animateParam.destPos = _this._getFinalPos(animateParam.destPos, originalIntendedPos_1); + + if (!equal(animateParam.destPos, _this.axisManager.get(Object.keys(animateParam.destPos)))) { + _this.eventManager.triggerChange(animateParam.destPos, nextState.pos); + } + + complete(); + return; + } else if (isCanceled) { + _this.finish(false); + } else { + _this._raf = requestAnimationFrame(loop_1); + } + }; + + loop_1(); + } else { + this.eventManager.triggerChange(param.destPos); + complete(); + } + }; + /** + * Get estimated final value. + * + * If destPos is within the 'error range' of the original intended position, the initial intended position is returned. + * - eg. original intended pos: 100, destPos: 100.0000000004 ==> return 100; + * If dest Pos is outside the 'range of error' compared to the originally intended pos, it is returned rounded based on the originally intended pos. + * - eg. original intended pos: 100.123 destPos: 50.12345 => return 50.123 + * @param originalIntendedPos + * @param destPos + */ + + + __proto._getFinalPos = function (destPos, originalIntendedPos) { + var _this = this; // compare destPos and originalIntendedPos + // eslint-disable-next-line @typescript-eslint/naming-convention + + + var ERROR_LIMIT = 0.000001; + var finalPos = map(destPos, function (value, key) { + if (value >= originalIntendedPos[key] - ERROR_LIMIT && value <= originalIntendedPos[key] + ERROR_LIMIT) { + // In error range, return original intended + return originalIntendedPos[key]; + } else { + // Out of error range, return rounded pos. + var roundUnit = _this._getRoundUnit(value, key); + + var result = roundNumber(value, roundUnit); + return result; + } + }); + return finalPos; + }; + + __proto._getRoundUnit = function (val, key) { + var roundUnit = this._options.round; // manual mode + + var minRoundUnit = null; // auto mode + // auto mode + + if (!roundUnit) { + // Get minimum round unit + var options = this.axisManager.getAxisOptions(key); + minRoundUnit = inversePow(Math.max(getDecimalPlace(options.range[0]), getDecimalPlace(options.range[1]), getDecimalPlace(val))); + } + + return minRoundUnit || roundUnit; + }; + + return AnimationManager; + }(); + + var EasingManager = + /*#__PURE__*/ + function (_super) { + __extends$1(EasingManager, _super); + + function EasingManager() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this._useDuration = true; + return _this; + } + + var __proto = EasingManager.prototype; + + __proto.interpolate = function (displacement, threshold) { + var initSlope = this._easing(0.00001) / 0.00001; + return this._easing(displacement / (threshold * initSlope)) * threshold; + }; + + __proto.updateAnimation = function (options) { + var animateParam = this._animateParam; + + if (!animateParam) { + return; + } + + var diffTime = new Date().getTime() - animateParam.startTime; + var pos = (options === null || options === void 0 ? void 0 : options.destPos) || animateParam.destPos; + var duration = (options === null || options === void 0 ? void 0 : options.duration) || animateParam.duration; + + if ((options === null || options === void 0 ? void 0 : options.restart) || duration <= diffTime) { + this.setTo(pos, duration - diffTime); + return; + } + + if (options === null || options === void 0 ? void 0 : options.destPos) { + var currentPos = this.axisManager.get(); // When destination is changed, new delta should be calculated as remaining percent. + // For example, moving x:0, y:0 to x:200, y:200 and it has current easing percent of 92%. coordinate is x:184 and y:184 + // If destination changes to x:300, y:300. xdelta:200, ydelta:200 changes to xdelta:116, ydelta:116 and use remaining easingPer as 100%, not 8% as previous. + // Therefore, original easingPer by time is kept. And divided by (1 - self._initialEasingPer) which means new total easing percent. Like calculating 8% as 100%. + + this._initialEasingPer = this._prevEasingPer; + animateParam.delta = this.axisManager.getDelta(currentPos, pos); + animateParam.destPos = pos; + } + + if (options === null || options === void 0 ? void 0 : options.duration) { + var ratio = (diffTime + this._durationOffset) / animateParam.duration; // Use durationOffset for keeping animation ratio after duration is changed. + // newRatio = (diffTime + newDurationOffset) / newDuration = oldRatio + // newDurationOffset = oldRatio * newDuration - diffTime + + this._durationOffset = ratio * duration - diffTime; + animateParam.duration = duration; + } + }; + + __proto._initState = function (info) { + this._initialEasingPer = 0; + this._prevEasingPer = 0; + this._durationOffset = 0; + return { + pos: info.depaPos, + easingPer: 0, + finished: false + }; + }; + + __proto._getNextState = function (prevState) { + var _this = this; + + var animateParam = this._animateParam; + var prevPos = prevState.pos; + var destPos = animateParam.destPos; + var directions = map(prevPos, function (value, key) { + return value <= destPos[key] ? 1 : -1; + }); + var diffTime = new Date().getTime() - animateParam.startTime; + var ratio = (diffTime + this._durationOffset) / animateParam.duration; + + var easingPer = this._easing(ratio); + + var toPos = this.axisManager.map(prevPos, function (pos, options, key) { + var nextPos = ratio >= 1 ? destPos[key] : pos + animateParam.delta[key] * (easingPer - _this._prevEasingPer) / (1 - _this._initialEasingPer); // Subtract distance from distance already moved. + // Recalculate the remaining distance. + // Fix the bouncing phenomenon by changing the range. + + var circulatedPos = getCirculatedPos(nextPos, options.range, options.circular); + + if (nextPos !== circulatedPos) { + // circular + var rangeOffset = directions[key] * (options.range[1] - options.range[0]); + destPos[key] -= rangeOffset; + prevPos[key] -= rangeOffset; + } + + return circulatedPos; + }); + this._prevEasingPer = easingPer; + return { + pos: toPos, + easingPer: easingPer, + finished: easingPer >= 1 + }; + }; + + __proto._easing = function (p) { + return p > 1 ? 1 : this._options.easing(p); + }; + + return EasingManager; + }(AnimationManager); + + /** + * @typedef {Object} AxisOption The Axis information. The key of the axis specifies the name to use as the logical virtual coordinate system. + * @ko 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다. + * @param {Number[]} [range] The coordinate of range 좌표 범위 + * @param {Number} [range[0]=0] The coordinate of the minimum 최소 좌표 + * @param {Number} [range[1]=0] The coordinate of the maximum 최대 좌표 + * @param {Number[]} [bounce] The size of bouncing area. The coordinates can exceed the coordinate area as much as the bouncing area based on user action. If the coordinates does not exceed the bouncing area when an element is dragged, the coordinates where bouncing effects are applied are retuned back into the coordinate area바운스 영역의 크기. 사용자의 동작에 따라 좌표가 좌표 영역을 넘어 바운스 영역의 크기만큼 더 이동할 수 있다. 사용자가 끌어다 놓는 동작을 했을 때 좌표가 바운스 영역에 있으면, 바운스 효과가 적용된 좌표가 다시 좌표 영역 안으로 들어온다 + * @param {Number} [bounce[0]=0] The size of coordinate of the minimum area 최소 좌표 바운스 영역의 크기 + * @param {Number} [bounce[1]=0] The size of coordinate of the maximum area 최대 좌표 바운스 영역의 크기 + * @param {Boolean[]} [circular] Indicates whether a circular element is available. If it is set to "true" and an element is dragged outside the coordinate area, the element will appear on the other side.순환 여부. 'true'로 설정한 방향의 좌표 영역 밖으로 엘리먼트가 이동하면 반대 방향에서 엘리먼트가 나타난다 + * @param {Boolean} [circular[0]=false] Indicates whether to circulate to the coordinate of the minimum 최소 좌표 방향의 순환 여부 + * @param {Boolean} [circular[1]=false] Indicates whether to circulate to the coordinate of the maximum 최대 좌표 방향의 순환 여부 + **/ + + /** + * @typedef {Object} AxesOption The option object of the eg.Axes module + * @ko eg.Axes 모듈의 옵션 객체 + * @param {Function} [easing=easing.easeOutCubic] The easing function to apply to an animation 애니메이션에 적용할 easing 함수 + * @param {Number} [maximumDuration=Infinity] Maximum duration of the animation 가속도에 의해 애니메이션이 동작할 때의 최대 좌표 이동 시간 + * @param {Number} [minimumDuration=0] Minimum duration of the animation 가속도에 의해 애니메이션이 동작할 때의 최소 좌표 이동 시간 + * @param {Number} [deceleration=0.0006] Deceleration of the animation where acceleration is manually enabled by user. A higher value indicates shorter running time. 사용자의 동작으로 가속도가 적용된 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아진다 + * @param {Boolean} [interruptable=true] Indicates whether an animation is interruptible. + * - true: It can be paused or stopped by user action or the API. + * - false: It cannot be paused or stopped by user action or the API while it is running. + * 진행 중인 애니메이션 중지 가능 여부. + * - true: 사용자의 동작이나 API로 애니메이션을 중지할 수 있다. + * - false: 애니메이션이 진행 중일 때는 사용자의 동작이나 API가 적용되지 않는다 + * @param {Number} [round=null] Rounding unit. For example, 0.1 rounds to 0.1 decimal point(6.1234 => 6.1), 5 rounds to 5 (93 => 95) + * [Details](https://github.com/naver/egjs-axes/wiki/round-option)반올림 단위. 예를 들어 0.1 은 소숫점 0.1 까지 반올림(6.1234 => 6.1), 5 는 5 단위로 반올림(93 => 95). + * [상세내용](https://github.com/naver/egjs-axes/wiki/round-option) + * @param {Boolean} [nested=false] Whether the event propagates to other instances when the coordinates reach the end of the movable area 좌표가 이동 가능한 영역의 끝까지 도달했을 때 다른 인스턴스들로의 이벤트 전파 여부 + **/ + + /** + * A module used to change the information of user action entered by various input devices such as touch screen or mouse into the logical virtual coordinates. You can easily create a UI that responds to user actions. + * @ko 터치 입력 장치나 마우스와 같은 다양한 입력 장치를 통해 전달 받은 사용자의 동작을 논리적인 가상 좌표로 변경하는 모듈이다. 사용자 동작에 반응하는 UI를 손쉽게 만들수 있다. + * @extends eg.Component + * + * @param {Object.} axis Axis information managed by eg.Axes. The key of the axis specifies the name to use as the logical virtual coordinate system. eg.Axes가 관리하는 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다. + * @param {AxesOption} [options={}] The option object of the eg.Axes moduleeg.Axes 모듈의 옵션 객체 + * @param {Object.} [startPos=null] The coordinates to be moved when creating an instance. not triggering change event.인스턴스 생성시 이동할 좌표, change 이벤트는 발생하지 않음. + * + * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * ```js + * // 1. Initialize eg.Axes + * const axes = new eg.Axes({ + * something1: { + * range: [0, 150], + * bounce: 50 + * }, + * something2: { + * range: [0, 200], + * bounce: 100 + * }, + * somethingN: { + * range: [1, 10], + * } + * }, { + * deceleration : 0.0024 + * }); + * + * // 2. attach event handler + * axes.on({ + * "hold" : function(evt) { + * }, + * "release" : function(evt) { + * }, + * "animationStart" : function(evt) { + * }, + * "animationEnd" : function(evt) { + * }, + * "change" : function(evt) { + * } + * }); + * + * // 3. Initialize inputTypes + * const panInputArea = new eg.Axes.PanInput("#area", { + * scale: [0.5, 1] + * }); + * const panInputHmove = new eg.Axes.PanInput("#hmove"); + * const panInputVmove = new eg.Axes.PanInput("#vmove"); + * const pinchInputArea = new eg.Axes.PinchInput("#area", { + * scale: 1.5 + * }); + * + * // 4. Connect eg.Axes and InputTypes + * // [PanInput] When the mouse or touchscreen is down and moved. + * // Connect the 'something2' axis to the mouse or touchscreen x position and + * // connect the 'somethingN' axis to the mouse or touchscreen y position. + * axes.connect(["something2", "somethingN"], panInputArea); // or axes.connect("something2 somethingN", panInputArea); + * + * // Connect only one 'something1' axis to the mouse or touchscreen x position. + * axes.connect(["something1"], panInputHmove); // or axes.connect("something1", panInputHmove); + * + * // Connect only one 'something2' axis to the mouse or touchscreen y position. + * axes.connect(["", "something2"], panInputVmove); // or axes.connect(" something2", panInputVmove); + * + * // [PinchInput] Connect 'something2' axis when two pointers are moving toward (zoom-in) or away from each other (zoom-out). + * axes.connect("something2", pinchInputArea); + * ``` + */ + + var Axes = + /*#__PURE__*/ + function (_super) { + __extends$1(Axes, _super); + /** + * + */ + + + function Axes(axis, options, startPos) { + if (axis === void 0) { + axis = {}; + } + + if (options === void 0) { + options = {}; + } + + if (startPos === void 0) { + startPos = null; + } + + var _this = _super.call(this) || this; + + _this.axis = axis; + _this._inputs = []; + _this.options = __assign$1({ + easing: function (x) { + return 1 - Math.pow(1 - x, 3); + }, + interruptable: true, + maximumDuration: Infinity, + minimumDuration: 0, + deceleration: 0.0006, + round: null, + nested: false + }, options); + _this.interruptManager = new InterruptManager(_this.options); + _this.axisManager = new AxisManager(_this.axis); + _this.eventManager = new EventManager(_this); + _this.animationManager = new EasingManager(_this); + _this.inputObserver = new InputObserver(_this); + + _this.eventManager.setAnimationManager(_this.animationManager); + + if (startPos) { + _this.eventManager.triggerChange(startPos); + } + + return _this; + } + /** + * Connect the axis of eg.Axes to the inputType. + * @ko eg.Axes의 축과 inputType을 연결한다 + * @param {(String[]|String)} axes The name of the axis to associate with inputType inputType과 연결할 축의 이름 + * @param {Object} inputType The inputType instance to associate with the axis of eg.Axes eg.Axes의 축과 연결할 inputType 인스턴스 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * } + * }); + * + * axes.connect("x", new eg.Axes.PanInput("#area1")) + * .connect("x xOther", new eg.Axes.PanInput("#area2")) + * .connect(" xOther", new eg.Axes.PanInput("#area3")) + * .connect(["x"], new eg.Axes.PanInput("#area4")) + * .connect(["xOther", "x"], new eg.Axes.PanInput("#area5")) + * .connect(["", "xOther"], new eg.Axes.PanInput("#area6")); + * ``` + */ + + + var __proto = Axes.prototype; + + __proto.connect = function (axes, inputType) { + var mapped; + + if (typeof axes === "string") { + mapped = axes.split(" "); + } else { + mapped = axes.concat(); + } // check same instance + + + if (~this._inputs.indexOf(inputType)) { + this.disconnect(inputType); + } + + inputType.mapAxes(mapped); + inputType.connect(this.inputObserver); + + this._inputs.push(inputType); + + return this; + }; + /** + * Disconnect the axis of eg.Axes from the inputType. + * @ko eg.Axes의 축과 inputType의 연결을 끊는다. + * @param {Object} [inputType] An inputType instance associated with the axis of eg.Axes eg.Axes의 축과 연결한 inputType 인스턴스 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * } + * }); + * + * const input1 = new eg.Axes.PanInput("#area1"); + * const input2 = new eg.Axes.PanInput("#area2"); + * const input3 = new eg.Axes.PanInput("#area3"); + * + * axes.connect("x", input1); + * .connect("x xOther", input2) + * .connect(["xOther", "x"], input3); + * + * axes.disconnect(input1); // disconnects input1 + * axes.disconnect(); // disconnects all of them + * ``` + */ + + + __proto.disconnect = function (inputType) { + if (inputType) { + var index = this._inputs.indexOf(inputType); + + if (index >= 0) { + this._inputs[index].disconnect(); + + this._inputs.splice(index, 1); + } + } else { + this._inputs.forEach(function (v) { + return v.disconnect(); + }); + + this._inputs = []; + } + + return this; + }; + /** + * Returns the current position of the coordinates. + * @ko 좌표의 현재 위치를 반환한다 + * @param {Object} [axes] The names of the axis 축 이름들 + * @return {Object.} Axis coordinate information 축 좌표 정보 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.get(); // {"x": 0, "xOther": -100, "zoom": 50} + * axes.get(["x", "zoom"]); // {"x": 0, "zoom": 50} + * ``` + */ + + + __proto.get = function (axes) { + return this.axisManager.get(axes); + }; + /** + * Moves an axis to specific coordinates. + * @ko 좌표를 이동한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.setTo({"x": 30, "zoom": 60}); + * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60} + * + * axes.setTo({"x": 100, "xOther": 60}, 1000); // animatation + * + * // after 1000 ms + * axes.get(); // {"x": 100, "xOther": 60, "zoom": 60} + * ``` + */ + + + __proto.setTo = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + this.animationManager.setTo(pos, duration); + return this; + }; + /** + * Moves an axis from the current coordinates to specific coordinates. + * @ko 현재 좌표를 기준으로 좌표를 이동한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.setBy({"x": 30, "zoom": 10}); + * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60} + * + * axes.setBy({"x": 70, "xOther": 60}, 1000); // animatation + * + * // after 1000 ms + * axes.get(); // {"x": 100, "xOther": -40, "zoom": 60} + * ``` + */ + + + __proto.setBy = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + this.animationManager.setBy(pos, duration); + return this; + }; + /** + * Stop an animation in progress. + * @ko 재생 중인 애니메이션을 정지한다. + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * }); + * + * axes.setTo({"x": 10}, 1000); // start animatation + * + * // after 500 ms + * axes.stopAnimation(); // stop animation during movement. + * ``` + */ + + + __proto.stopAnimation = function () { + this.animationManager.stopAnimation(); + return this; + }; + /** + * Change the destination of an animation in progress. + * @ko 재생 중인 애니메이션의 목적지와 진행 시간을 변경한다. + * @param {UpdateAnimationOption} pos The coordinate to move to 이동할 좌표 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 200] + * }, + * "y": { + * range: [0, 200] + * } + * }); + * + * axes.setTo({"x": 50, "y": 50}, 1000); // trigger animation by setTo + * + * // after 500 ms + * axes.updateAnimation({destPos: {"x": 100, "y": 100}}); // animation will end after 500 ms, at {"x": 100, "y": 100} + * + * // after 500 ms + * axes.setTo({"x": 50, "y": 50}, 1000); // trigger animation by setTo + * + * // after 700 ms + * axes.updateAnimation({destPos: {"x": 100, "y": 100}, duration: 1500, restart: true}); // this works same as axes.setTo({"x": 100, "y": 100}, 800) since restart is true. + * ``` + */ + + + __proto.updateAnimation = function (options) { + this.animationManager.updateAnimation(options); + return this; + }; + /** + * Returns whether there is a coordinate in the bounce area of ​​the target axis. + * @ko 대상 축 중 bounce영역에 좌표가 존재하는지를 반환한다 + * @param {Object} [axes] The names of the axis 축 이름들 + * @return {Boolen} Whether the bounce area exists. bounce 영역 존재 여부 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.isBounceArea(["x"]); + * axes.isBounceArea(["x", "zoom"]); + * axes.isBounceArea(); + * ``` + */ + + + __proto.isBounceArea = function (axes) { + return this.axisManager.isOutside(axes); + }; + /** + * Destroys properties, and events used in a module and disconnect all connections to inputTypes. + * @ko 모듈에 사용한 속성, 이벤트를 해제한다. 모든 inputType과의 연결을 끊는다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.eventManager.destroy(); + }; + /** + * @name VERSION + * @desc Version info string + * @ko 버전정보 문자열 + * + * @constant + * @type {String} + * @example + * ```js + * eg.Axes.VERSION; // ex) 3.3.3 + * ``` + */ + + + Axes.VERSION = "3.3.0"; + /* eslint-enable */ + + /** + * @name TRANSFORM + * @desc Returns the transform attribute with CSS vendor prefixes. + * @ko CSS vendor prefixes를 붙인 transform 속성을 반환한다. + * + * @constant + * @type {String} + * @example + * ```js + * eg.Axes.TRANSFORM; // "transform" or "webkitTransform" + * ``` + */ + + Axes.TRANSFORM = TRANSFORM$1; + /** + * @name DIRECTION_NONE + * @constant + * @type {Number} + */ + + Axes.DIRECTION_NONE = DIRECTION_NONE; + /** + * @name DIRECTION_LEFT + * @constant + * @type {Number} + */ + + Axes.DIRECTION_LEFT = DIRECTION_LEFT; + /** + * @name DIRECTION_RIGHT + * @constant + * @type {Number} + */ + + Axes.DIRECTION_RIGHT = DIRECTION_RIGHT; + /** + * @name DIRECTION_UP + * @constant + * @type {Number} + */ + + Axes.DIRECTION_UP = DIRECTION_UP; + /** + * @name DIRECTION_DOWN + * @constant + * @type {Number} + */ + + Axes.DIRECTION_DOWN = DIRECTION_DOWN; + /** + * @name DIRECTION_HORIZONTAL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL; + /** + * @name DIRECTION_VERTICAL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_VERTICAL = DIRECTION_VERTICAL; + /** + * @name DIRECTION_ALL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_ALL = DIRECTION_ALL; + return Axes; + }(Component); + + /* eslint-disable @typescript-eslint/no-empty-function */ + + var getDirectionByAngle = function (angle, thresholdAngle) { + if (thresholdAngle < 0 || thresholdAngle > 90) { + return DIRECTION_NONE; + } + + var toAngle = Math.abs(angle); + return toAngle > thresholdAngle && toAngle < 180 - thresholdAngle ? DIRECTION_VERTICAL : DIRECTION_HORIZONTAL; + }; + var useDirection = function (checkType, direction, userDirection) { + if (userDirection) { + return !!(direction === DIRECTION_ALL || direction & checkType && userDirection & checkType); + } else { + return !!(direction & checkType); + } + }; + /** + * @typedef {Object} PanInputOption The option object of the eg.Axes.PanInput module. + * @ko eg.Axes.PanInput 모듈의 옵션 객체 + * @param {String[]} [inputType=["touch", "mouse", "pointer"]] Types of input devices + * - touch: Touch screen + * - mouse: Mouse + * - pointer: Mouse and touch 입력 장치 종류 + * - touch: 터치 입력 장치 + * - mouse: 마우스 + * - pointer: 마우스 및 터치 + * @param {String[]} [inputButton=["left"]] List of buttons to allow input + * - left: Left mouse button and normal touch + * - middle: Mouse wheel press + * - right: Right mouse button 입력을 허용할 버튼 목록 + * - left: 마우스 왼쪽 버튼 + * - middle: 마우스 휠 눌림 + * - right: 마우스 오른쪽 버튼 + * @param {Number[]} [scale] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [scale[0]=1] horizontal axis scale 수평축 배율 + * @param {Number} [scale[1]=1] vertical axis scale 수직축 배율 + * @param {Number} [thresholdAngle=45] The threshold value that determines whether user action is horizontal or vertical (0~90) 사용자의 동작이 가로 방향인지 세로 방향인지 판단하는 기준 각도(0~90) + * @param {Number} [threshold=0] Minimal pan distance required before recognizing 사용자의 Pan 동작을 인식하기 위해산 최소한의 거리 + * @param {Number} [iOSEdgeSwipeThreshold=30] Area (px) that can go to the next page when swiping the right edge in iOS safari iOS Safari에서 오른쪽 엣지를 스와이프 하는 경우 다음 페이지로 넘어갈 수 있는 영역(px) + * @param {String} [touchAction=null] Value that overrides the element's "touch-action" css property. If set to null, it is automatically set to prevent scrolling in the direction of the connected axis. 엘리먼트의 "touch-action" CSS 속성을 덮어쓰는 값. 만약 null로 설정된 경우, 연결된 축 방향으로의 스크롤을 방지하게끔 자동으로 설정된다. + **/ + + /** + * A module that passes the amount of change to eg.Axes when the mouse or touchscreen is down and moved. use less than two axes. + * @ko 마우스나 터치 스크린을 누르고 움직일때의 변화량을 eg.Axes에 전달하는 모듈. 두개 이하의 축을 사용한다. + * + * @example + * ```js + * const pan = new eg.Axes.PanInput("#area", { + * inputType: ["touch"], + * scale: [1, 1.3], + * }); + * + * // Connect the 'something2' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved. + * // Connect the 'somethingN' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved. + * axes.connect(["something2", "somethingN"], pan); // or axes.connect("something2 somethingN", pan); + * + * // Connect only one 'something1' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved. + * axes.connect(["something1"], pan); // or axes.connect("something1", pan); + * + * // Connect only one 'something2' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved. + * axes.connect(["", "something2"], pan); // or axes.connect(" something2", pan); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.PanInput module eg.Axes.PanInput 모듈을 사용할 엘리먼트 + * @param {PanInputOption} [options={}] The option object of the eg.Axes.PanInput moduleeg.Axes.PanInput 모듈의 옵션 객체 + */ + + var PanInput = + /*#__PURE__*/ + function () { + /** + * + */ + function PanInput(el, options) { + var _this = this; + + this.axes = []; + this.element = null; + this._enabled = false; + this._activeEvent = null; + this._atRightEdge = false; + this._rightEdgeTimer = 0; + + this._forceRelease = function () { + var activeEvent = _this._activeEvent; + var prevEvent = activeEvent.prevEvent; + activeEvent.onRelease(); + + _this._observer.release(_this, prevEvent, [0, 0]); + + _this._detachWindowEvent(activeEvent); + }; + + this._voidFunction = function () {}; + + this.element = $(el); + this.options = __assign$1({ + inputType: ["touch", "mouse", "pointer"], + inputButton: [MOUSE_LEFT], + scale: [1, 1], + thresholdAngle: 45, + threshold: 0, + iOSEdgeSwipeThreshold: IOS_EDGE_THRESHOLD, + releaseOnScroll: false, + touchAction: null + }, options); + this._onPanstart = this._onPanstart.bind(this); + this._onPanmove = this._onPanmove.bind(this); + this._onPanend = this._onPanend.bind(this); + } + + var __proto = PanInput.prototype; + + __proto.mapAxes = function (axes) { + var useHorizontal = !!axes[0]; + var useVertical = !!axes[1]; + + if (useHorizontal && useVertical) { + this._direction = DIRECTION_ALL; + } else if (useHorizontal) { + this._direction = DIRECTION_HORIZONTAL; + } else if (useVertical) { + this._direction = DIRECTION_VERTICAL; + } else { + this._direction = DIRECTION_NONE; + } + + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this._activeEvent) { + this._detachElementEvent(); + + this._detachWindowEvent(this._activeEvent); + } + + this._attachElementEvent(observer); + + this._originalCssProps = setCssProps(this.element, this.options, this._direction); + return this; + }; + + __proto.disconnect = function () { + this._detachElementEvent(); + + this._detachWindowEvent(this._activeEvent); + + if (!isCssPropsFromAxes(this._originalCssProps)) { + revertCssProps(this.element, this._originalCssProps); + } + + this._direction = DIRECTION_NONE; + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {PanInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {PanInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onPanstart = function (event) { + var activeEvent = this._activeEvent; + var panEvent = activeEvent.onEventStart(event, this.options.inputButton); + + if (!panEvent || !this._enabled || activeEvent.getTouches(event) > 1) { + return; + } + + if (panEvent.srcEvent.cancelable !== false) { + var edgeThreshold = this.options.iOSEdgeSwipeThreshold; + + this._observer.hold(this, panEvent); + + this._atRightEdge = IS_IOS_SAFARI && panEvent.center.x > window.innerWidth - edgeThreshold; + + this._attachWindowEvent(activeEvent); + + activeEvent.prevEvent = panEvent; + } + }; + + __proto._onPanmove = function (event) { + var _this = this; + + var activeEvent = this._activeEvent; + var panEvent = activeEvent.onEventMove(event, this.options.inputButton); + + if (!panEvent || !this._enabled || activeEvent.getTouches(event) > 1) { + return; + } + + var _a = this.options, + iOSEdgeSwipeThreshold = _a.iOSEdgeSwipeThreshold, + releaseOnScroll = _a.releaseOnScroll; + var userDirection = getDirectionByAngle(panEvent.angle, this.options.thresholdAngle); + + if (releaseOnScroll && !panEvent.srcEvent.cancelable) { + this._onPanend(event); + + return; + } + + if (activeEvent.prevEvent && IS_IOS_SAFARI) { + var swipeLeftToRight = panEvent.center.x < 0; + + if (swipeLeftToRight) { + // iOS swipe left => right + this._forceRelease(); + + return; + } else if (this._atRightEdge) { + clearTimeout(this._rightEdgeTimer); // - is right to left + + var swipeRightToLeft = panEvent.deltaX < -iOSEdgeSwipeThreshold; + + if (swipeRightToLeft) { + this._atRightEdge = false; + } else { + // iOS swipe right => left + this._rightEdgeTimer = window.setTimeout(function () { + return _this._forceRelease(); + }, 100); + } + } + } + + var offset = this._getOffset([panEvent.offsetX, panEvent.offsetY], [useDirection(DIRECTION_HORIZONTAL, this._direction, userDirection), useDirection(DIRECTION_VERTICAL, this._direction, userDirection)]); + + var prevent = offset.some(function (v) { + return v !== 0; + }); + + if (prevent) { + if (panEvent.srcEvent.cancelable !== false) { + panEvent.srcEvent.preventDefault(); + } + + panEvent.srcEvent.stopPropagation(); + } + + panEvent.preventSystemEvent = prevent; + + if (prevent) { + this._observer.change(this, panEvent, toAxis(this.axes, offset)); + } + + activeEvent.prevEvent = panEvent; + }; + + __proto._onPanend = function (event) { + var activeEvent = this._activeEvent; + activeEvent.onEventEnd(event); + + if (!this._enabled || activeEvent.getTouches(event) !== 0) { + return; + } + + this._detachWindowEvent(activeEvent); + + clearTimeout(this._rightEdgeTimer); + var prevEvent = activeEvent.prevEvent; + + var velocity = this._getOffset([Math.abs(prevEvent.velocityX) * (prevEvent.offsetX < 0 ? -1 : 1), Math.abs(prevEvent.velocityY) * (prevEvent.offsetY < 0 ? -1 : 1)], [useDirection(DIRECTION_HORIZONTAL, this._direction), useDirection(DIRECTION_VERTICAL, this._direction)]); + + activeEvent.onRelease(); + + this._observer.release(this, prevEvent, velocity); + }; + + __proto._attachWindowEvent = function (activeEvent) { + var _this = this; + + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + window.addEventListener(event, _this._onPanmove, { + passive: false + }); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) { + window.addEventListener(event, _this._onPanend, { + passive: false + }); + }); + }; + + __proto._detachWindowEvent = function (activeEvent) { + var _this = this; + + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + window.removeEventListener(event, _this._onPanmove); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) { + window.removeEventListener(event, _this._onPanend); + }); + }; + + __proto._getOffset = function (properties, direction) { + var offset = [0, 0]; + var scale = this.options.scale; + + if (direction[0]) { + offset[0] = properties[0] * scale[0]; + } + + if (direction[1]) { + offset[1] = properties[1] * scale[1]; + } + + return offset; + }; + + __proto._attachElementEvent = function (observer) { + var _this = this; + + var activeEvent = convertInputType(this.options.inputType); + + if (!activeEvent) { + return; + } + + this._observer = observer; + this._enabled = true; + this._activeEvent = activeEvent; + activeEvent.start.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.addEventListener(event, _this._onPanstart); + }); // adding event listener to element prevents invalid behavior in iOS Safari + + activeEvent.move.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.addEventListener(event, _this._voidFunction); + }); + }; + + __proto._detachElementEvent = function () { + var _this = this; + + var activeEvent = this._activeEvent; + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.start.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, _this._onPanstart); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, _this._voidFunction); + }); + this._enabled = false; + this._observer = null; + }; + + return PanInput; + }(); + + /** + * @typedef {Object} PinchInputOption The option object of the eg.Axes.PinchInput module + * @ko eg.Axes.PinchInput 모듈의 옵션 객체 + * @param {Number} [scale=1] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [threshold=0] Minimal scale before recognizing 사용자의 Pinch 동작을 인식하기 위해산 최소한의 배율 + * @param {String[]} [inputType=["touch", "pointer"]] Types of input devices + * - touch: Touch screen + * - pointer: Mouse and touch 입력 장치 종류 + * - touch: 터치 입력 장치 + * - pointer: 마우스 및 터치 + * @param {String} [touchAction="none"] Value that overrides the element's "touch-action" css property. It is set to "none" to prevent scrolling during touch. 엘리먼트의 "touch-action" CSS 속성을 덮어쓰는 값. 터치 도중 스크롤을 방지하기 위해 "none" 으로 설정되어 있다. + **/ + + /** + * A module that passes the amount of change to eg.Axes when two pointers are moving toward (zoom-in) or away from each other (zoom-out). use one axis. + * @ko 2개의 pointer를 이용하여 zoom-in하거나 zoom-out 하는 동작의 변화량을 eg.Axes에 전달하는 모듈. 한 개 의 축을 사용한다. + * @example + * ```js + * const pinch = new eg.Axes.PinchInput("#area", { + * scale: 1 + * }); + * + * // Connect 'something' axis when two pointers are moving toward (zoom-in) or away from each other (zoom-out). + * axes.connect("something", pinch); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.PinchInput module eg.Axes.PinchInput 모듈을 사용할 엘리먼트 + * @param {PinchInputOption} [options] The option object of the eg.Axes.PinchInput moduleeg.Axes.PinchInput 모듈의 옵션 객체 + */ + + var PinchInput = + /*#__PURE__*/ + function () { + /** + * + */ + function PinchInput(el, options) { + this.axes = []; + this.element = null; + this._pinchFlag = false; + this._enabled = false; + this._activeEvent = null; + this.element = $(el); + this.options = __assign$1({ + scale: 1, + threshold: 0, + inputType: ["touch", "pointer"], + touchAction: "none" + }, options); + this._onPinchStart = this._onPinchStart.bind(this); + this._onPinchMove = this._onPinchMove.bind(this); + this._onPinchEnd = this._onPinchEnd.bind(this); + } + + var __proto = PinchInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this._activeEvent) { + this._detachEvent(); + } + + this._attachEvent(observer); + + this._originalCssProps = setCssProps(this.element, this.options, DIRECTION_ALL); + return this; + }; + + __proto.disconnect = function () { + this._detachEvent(); + + if (!isCssPropsFromAxes(this._originalCssProps)) { + revertCssProps(this.element, this._originalCssProps); + } + + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {PinchInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {PinchInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onPinchStart = function (event) { + var activeEvent = this._activeEvent; + var pinchEvent = activeEvent.onEventStart(event); + + if (!pinchEvent || !this._enabled || activeEvent.getTouches(event) !== 2) { + return; + } + + this._baseValue = this._observer.get(this)[this.axes[0]]; + + this._observer.hold(this, event); + + this._pinchFlag = true; + activeEvent.prevEvent = pinchEvent; + }; + + __proto._onPinchMove = function (event) { + var activeEvent = this._activeEvent; + var pinchEvent = activeEvent.onEventMove(event); + + if (!pinchEvent || !this._pinchFlag || !this._enabled || activeEvent.getTouches(event) !== 2) { + return; + } + + var offset = this._getOffset(pinchEvent.scale, activeEvent.prevEvent.scale); + + this._observer.change(this, event, toAxis(this.axes, [offset])); + + activeEvent.prevEvent = pinchEvent; + }; + + __proto._onPinchEnd = function (event) { + var activeEvent = this._activeEvent; + activeEvent.onEventEnd(event); + + if (!this._pinchFlag || !this._enabled || activeEvent.getTouches(event) >= 2) { + return; + } + + activeEvent.onRelease(); + + this._observer.release(this, event, [0], 0); + + this._baseValue = null; + this._pinchFlag = false; + }; + + __proto._attachEvent = function (observer) { + var _this = this; + + var activeEvent = convertInputType(this.options.inputType); + + if (!activeEvent) { + return; + } + + this._observer = observer; + this._enabled = true; + this._activeEvent = activeEvent; + activeEvent.start.forEach(function (event) { + _this.element.addEventListener(event, _this._onPinchStart, false); + }); + activeEvent.move.forEach(function (event) { + _this.element.addEventListener(event, _this._onPinchMove, false); + }); + activeEvent.end.forEach(function (event) { + _this.element.addEventListener(event, _this._onPinchEnd, false); + }); + }; + + __proto._detachEvent = function () { + var _this = this; + + var activeEvent = this._activeEvent; + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.start.forEach(function (event) { + _this.element.removeEventListener(event, _this._onPinchStart, false); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + _this.element.removeEventListener(event, _this._onPinchMove, false); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) { + _this.element.removeEventListener(event, _this._onPinchEnd, false); + }); + this._enabled = false; + this._observer = null; + }; + + __proto._getOffset = function (pinchScale, prev) { + if (prev === void 0) { + prev = 1; + } + + return this._baseValue * (pinchScale - prev) * this.options.scale; + }; + + return PinchInput; + }(); + + /** + * @typedef {Object} WheelInputOption The option object of the eg.Axes.WheelInput module + * @ko eg.Axes.WheelInput 모듈의 옵션 객체 + * @param {Number} [scale=1] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [releaseDelay=300] Millisecond that trigger release event after last input마지막 입력 이후 release 이벤트가 트리거되기까지의 밀리초 + * @param {Boolean} [useNormalized=true] Whether to calculate scroll speed the same in all browsers모든 브라우저에서 스크롤 속도를 동일하게 처리할지 여부 + * @param {Boolean} [useAnimation=false] Whether to process coordinate changes through the mouse wheel as a continuous animation마우스 휠을 통한 좌표 변화를 연속적인 애니메이션으로 처리할지 여부 + **/ + + /** + * A module that passes the amount of change to eg.Axes when the mouse wheel is moved. use one axis. + * @ko 마우스 휠이 움직일때의 변화량을 eg.Axes에 전달하는 모듈. 한 개 의 축을 사용한다. + * + * @example + * ```js + * const wheel = new eg.Axes.WheelInput("#area", { + * scale: 1 + * }); + * + * // Connect 'something' axis when the mousewheel is moved. + * axes.connect("something", wheel); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.WheelInput module eg.Axes.WheelInput 모듈을 사용할 엘리먼트 + * @param {WheelInputOption} [options] The option object of the eg.Axes.WheelInput moduleeg.Axes.WheelInput 모듈의 옵션 객체 + */ + + var WheelInput = + /*#__PURE__*/ + function () { + /** + * + */ + function WheelInput(el, options) { + this.axes = []; + this.element = null; + this._enabled = false; + this._holding = false; + this._timer = null; + this.element = $(el); + this.options = __assign$1({ + scale: 1, + releaseDelay: 300, + useNormalized: true, + useAnimation: false + }, options); + this._onWheel = this._onWheel.bind(this); + } + + var __proto = WheelInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + this._detachEvent(); + + this._attachEvent(observer); + + return this; + }; + + __proto.disconnect = function () { + this._detachEvent(); + + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {WheelInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {WheelInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onWheel = function (event) { + var _this = this; + + if (!this._enabled) { + return; + } + + event.preventDefault(); + + if (event.deltaY === 0) { + return; + } + + if (!this._holding) { + this._observer.hold(this, event); + + this._holding = true; + } + + var offset = (event.deltaY > 0 ? -1 : 1) * this.options.scale * (this.options.useNormalized ? 1 : Math.abs(event.deltaY)); + + this._observer.change(this, event, toAxis(this.axes, [offset]), this.options.useAnimation); + + clearTimeout(this._timer); + this._timer = setTimeout(function () { + if (_this._holding) { + _this._holding = false; + + _this._observer.release(_this, event, [0]); + } + }, this.options.releaseDelay); + }; + + __proto._attachEvent = function (observer) { + this._observer = observer; + this.element.addEventListener("wheel", this._onWheel); + this._enabled = true; + }; + + __proto._detachEvent = function () { + this.element.removeEventListener("wheel", this._onWheel); + this._enabled = false; + this._observer = null; + + if (this._timer) { + clearTimeout(this._timer); + this._timer = null; + } + }; + + return WheelInput; + }(); + + var KEY_LEFT_ARROW = 37; + var KEY_A = 65; + var KEY_UP_ARROW = 38; + var KEY_W = 87; + var KEY_RIGHT_ARROW = 39; + var KEY_D = 68; + var KEY_DOWN_ARROW = 40; + var KEY_S = 83; + /* eslint-disable */ + + var DIRECTION_REVERSE = -1; + var DIRECTION_FORWARD = 1; + var DIRECTION_HORIZONTAL$1 = -1; + var DIRECTION_VERTICAL$1 = 1; + var DELAY = 80; + /** + * @typedef {Object} MoveKeyInputOption The option object of the eg.Axes.MoveKeyInput module + * @ko eg.Axes.MoveKeyInput 모듈의 옵션 객체 + * @param {Array} [scale] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [scale[0]=1] Coordinate scale for the first axis첫번째 축의 배율 + * @param {Number} [scale[1]=1] Coordinate scale for the decond axis두번째 축의 배율 + **/ + + /** + * A module that passes the amount of change to eg.Axes when the move key stroke is occured. use two axis. + * @ko 이동키 입력이 발생했을 때의 변화량을 eg.Axes에 전달하는 모듈. 두 개 의 축을 사용한다. + * + * @example + * ```js + * const moveKey = new eg.Axes.MoveKeyInput("#area", { + * scale: [1, 1] + * }); + * + * // Connect 'x', 'y' axes when the moveKey is pressed. + * axes.connect(["x", "y"], moveKey); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.MoveKeyInput module eg.Axes.MoveKeyInput 모듈을 사용할 엘리먼트 + * @param {MoveKeyInputOption} [options] The option object of the eg.Axes.MoveKeyInput moduleeg.Axes.MoveKeyInput 모듈의 옵션 객체 + */ + + var MoveKeyInput = + /*#__PURE__*/ + function () { + /** + * + */ + function MoveKeyInput(el, options) { + this.axes = []; + this.element = null; + this._enabled = false; + this._holding = false; + this._timer = null; + this.element = $(el); + this.options = __assign$1({ + scale: [1, 1] + }, options); + this._onKeydown = this._onKeydown.bind(this); + this._onKeyup = this._onKeyup.bind(this); + } + + var __proto = MoveKeyInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + this._detachEvent(); // add tabindex="0" to the container for making it focusable + + + if (this.element.getAttribute("tabindex") !== "0") { + this.element.setAttribute("tabindex", "0"); + } + + this._attachEvent(observer); + + return this; + }; + + __proto.disconnect = function () { + this._detachEvent(); + + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {MoveKeyInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {MoveKeyInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onKeydown = function (event) { + if (!this._enabled) { + return; + } + + var isMoveKey = true; + var direction = DIRECTION_FORWARD; + var move = DIRECTION_HORIZONTAL$1; + + switch (event.keyCode) { + case KEY_LEFT_ARROW: + case KEY_A: + direction = DIRECTION_REVERSE; + break; + + case KEY_RIGHT_ARROW: + case KEY_D: + break; + + case KEY_DOWN_ARROW: + case KEY_S: + direction = DIRECTION_REVERSE; + move = DIRECTION_VERTICAL$1; + break; + + case KEY_UP_ARROW: + case KEY_W: + move = DIRECTION_VERTICAL$1; + break; + + default: + isMoveKey = false; + } + + if (move === DIRECTION_HORIZONTAL$1 && !this.axes[0] || move === DIRECTION_VERTICAL$1 && !this.axes[1]) { + isMoveKey = false; + } + + if (!isMoveKey) { + return; + } + + event.preventDefault(); + var offsets = move === DIRECTION_HORIZONTAL$1 ? [+this.options.scale[0] * direction, 0] : [0, +this.options.scale[1] * direction]; + + if (!this._holding) { + this._observer.hold(this, event); + + this._holding = true; + } + + clearTimeout(this._timer); + + this._observer.change(this, event, toAxis(this.axes, offsets)); + }; + + __proto._onKeyup = function (event) { + var _this = this; + + if (!this._holding) { + return; + } + + clearTimeout(this._timer); + this._timer = setTimeout(function () { + _this._observer.release(_this, event, [0, 0]); + + _this._holding = false; + }, DELAY); + }; + + __proto._attachEvent = function (observer) { + this._observer = observer; + this.element.addEventListener("keydown", this._onKeydown, false); + this.element.addEventListener("keypress", this._onKeydown, false); + this.element.addEventListener("keyup", this._onKeyup, false); + this._enabled = true; + }; + + __proto._detachEvent = function () { + this.element.removeEventListener("keydown", this._onKeydown, false); + this.element.removeEventListener("keypress", this._onKeydown, false); + this.element.removeEventListener("keyup", this._onKeyup, false); + this._enabled = false; + this._observer = null; + }; + + return MoveKeyInput; + }(); + + /** + * Common utilities + * @module glMatrix + */ + // Configuration Constants + var EPSILON = 0.000001; + var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; + var degree = Math.PI / 180; + /** + * Convert Degree To Radian + * + * @param {Number} a Angle in Degrees + */ + + function toRadian(a) { + return a * degree; + } + if (!Math.hypot) Math.hypot = function () { + var y = 0, + i = arguments.length; + + while (i--) { + y += arguments[i] * arguments[i]; + } + + return Math.sqrt(y); + }; + + /** + * 3x3 Matrix + * @module mat3 + */ + + /** + * Creates a new identity mat3 + * + * @returns {mat3} a new 3x3 matrix + */ + + function create() { + var out = new ARRAY_TYPE(9); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + } + + out[0] = 1; + out[4] = 1; + out[8] = 1; + return out; + } + /** + * Copies the upper-left 3x3 values into the given mat3. + * + * @param {mat3} out the receiving 3x3 matrix + * @param {ReadonlyMat4} a the source 4x4 matrix + * @returns {mat3} out + */ + + function fromMat4(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[4]; + out[4] = a[5]; + out[5] = a[6]; + out[6] = a[8]; + out[7] = a[9]; + out[8] = a[10]; + return out; + } + /** + * Inverts a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function invert(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b01 = a22 * a11 - a12 * a21; + var b11 = -a22 * a10 + a12 * a20; + var b21 = a21 * a10 - a11 * a20; // Calculate the determinant + + var det = a00 * b01 + a01 * b11 + a02 * b21; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = b01 * det; + out[1] = (-a22 * a01 + a02 * a21) * det; + out[2] = (a12 * a01 - a02 * a11) * det; + out[3] = b11 * det; + out[4] = (a22 * a00 - a02 * a20) * det; + out[5] = (-a12 * a00 + a02 * a10) * det; + out[6] = b21 * det; + out[7] = (-a21 * a00 + a01 * a20) * det; + out[8] = (a11 * a00 - a01 * a10) * det; + return out; + } + + /** + * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. + * @module mat4 + */ + + /** + * Creates a new identity mat4 + * + * @returns {mat4} a new 4x4 matrix + */ + + function create$1() { + var out = new ARRAY_TYPE(16); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + } + + out[0] = 1; + out[5] = 1; + out[10] = 1; + out[15] = 1; + return out; + } + /** + * Set a mat4 to the identity matrix + * + * @param {mat4} out the receiving matrix + * @returns {mat4} out + */ + + function identity(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Rotates a matrix by the given angle around the X axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateX(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[4] = a10 * c + a20 * s; + out[5] = a11 * c + a21 * s; + out[6] = a12 * c + a22 * s; + out[7] = a13 * c + a23 * s; + out[8] = a20 * c - a10 * s; + out[9] = a21 * c - a11 * s; + out[10] = a22 * c - a12 * s; + out[11] = a23 * c - a13 * s; + return out; + } + /** + * Rotates a matrix by the given angle around the Y axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateY(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[0] = a00 * c - a20 * s; + out[1] = a01 * c - a21 * s; + out[2] = a02 * c - a22 * s; + out[3] = a03 * c - a23 * s; + out[8] = a00 * s + a20 * c; + out[9] = a01 * s + a21 * c; + out[10] = a02 * s + a22 * c; + out[11] = a03 * s + a23 * c; + return out; + } + /** + * Calculates a 4x4 matrix from the given quaternion + * + * @param {mat4} out mat4 receiving operation result + * @param {ReadonlyQuat} q Quaternion to create matrix from + * + * @returns {mat4} out + */ + + function fromQuat(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[1] = yx + wz; + out[2] = zx - wy; + out[3] = 0; + out[4] = yx - wz; + out[5] = 1 - xx - zz; + out[6] = zy + wx; + out[7] = 0; + out[8] = zx + wy; + out[9] = zy - wx; + out[10] = 1 - xx - yy; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Generates a perspective projection matrix with the given bounds. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + + function perspective(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2), + nf; + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + nf = 1 / (near - far); + out[10] = (far + near) * nf; + out[14] = 2 * far * near * nf; + } else { + out[10] = -1; + out[14] = -2 * near; + } + + return out; + } + + /** + * 3 Dimensional Vector + * @module vec3 + */ + + /** + * Creates a new, empty vec3 + * + * @returns {vec3} a new 3D vector + */ + + function create$2() { + var out = new ARRAY_TYPE(3); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + return out; + } + /** + * Calculates the length of a vec3 + * + * @param {ReadonlyVec3} a vector to calculate length of + * @returns {Number} length of a + */ + + function length(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return Math.hypot(x, y, z); + } + /** + * Creates a new vec3 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} a new 3D vector + */ + + function fromValues(x, y, z) { + var out = new ARRAY_TYPE(3); + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Copy the values from one vec3 to another + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the source vector + * @returns {vec3} out + */ + + function copy(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Set the components of a vec3 to the given values + * + * @param {vec3} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} out + */ + + function set(out, x, y, z) { + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function subtract(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + return out; + } + /** + * Scales a vec3 by a scalar number + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec3} out + */ + + function scale(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + return out; + } + /** + * Normalize a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to normalize + * @returns {vec3} out + */ + + function normalize(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var len = x * x + y * y + z * z; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + out[2] = a[2] * len; + return out; + } + /** + * Calculates the dot product of two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + /** + * Computes the cross product of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function cross(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2]; + var bx = b[0], + by = b[1], + bz = b[2]; + out[0] = ay * bz - az * by; + out[1] = az * bx - ax * bz; + out[2] = ax * by - ay * bx; + return out; + } + /** + * Transforms the vec3 with a mat3. + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat3} m the 3x3 matrix to transform with + * @returns {vec3} out + */ + + function transformMat3(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + out[0] = x * m[0] + y * m[3] + z * m[6]; + out[1] = x * m[1] + y * m[4] + z * m[7]; + out[2] = x * m[2] + y * m[5] + z * m[8]; + return out; + } + /** + * Transforms the vec3 with a quat + * Can also be used for dual quaternions. (Multiply it with the real part) + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec3} out + */ + + function transformQuat(out, a, q) { + // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; + var x = a[0], + y = a[1], + z = a[2]; // var qvec = [qx, qy, qz]; + // var uv = vec3.cross([], qvec, a); + + var uvx = qy * z - qz * y, + uvy = qz * x - qx * z, + uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); + + var uuvx = qy * uvz - qz * uvy, + uuvy = qz * uvx - qx * uvz, + uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); + + var w2 = qw * 2; + uvx *= w2; + uvy *= w2; + uvz *= w2; // vec3.scale(uuv, uuv, 2); + + uuvx *= 2; + uuvy *= 2; + uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); + + out[0] = x + uvx + uuvx; + out[1] = y + uvy + uuvy; + out[2] = z + uvz + uuvz; + return out; + } + /** + * Alias for {@link vec3.length} + * @function + */ + + var len = length; + /** + * Perform some operation over an array of vec3s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach = function () { + var vec = create$2(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 3; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + } + + return a; + }; + }(); + + /** + * 4 Dimensional Vector + * @module vec4 + */ + + /** + * Creates a new, empty vec4 + * + * @returns {vec4} a new 4D vector + */ + + function create$3() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 0; + } + + return out; + } + /** + * Creates a new vec4 initialized with values from an existing vector + * + * @param {ReadonlyVec4} a vector to clone + * @returns {vec4} a new 4D vector + */ + + function clone(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a new vec4 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} a new 4D vector + */ + + function fromValues$1(x, y, z, w) { + var out = new ARRAY_TYPE(4); + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Copy the values from one vec4 to another + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the source vector + * @returns {vec4} out + */ + + function copy$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Normalize a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to normalize + * @returns {vec4} out + */ + + function normalize$1(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + var len = x * x + y * y + z * z + w * w; + + if (len > 0) { + len = 1 / Math.sqrt(len); + } + + out[0] = x * len; + out[1] = y * len; + out[2] = z * len; + out[3] = w * len; + return out; + } + /** + * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function exactEquals(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Perform some operation over an array of vec4s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach$1 = function () { + var vec = create$3(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 4; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + vec[3] = a[i + 3]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + a[i + 3] = vec[3]; + } + + return a; + }; + }(); + + /** + * Quaternion + * @module quat + */ + + /** + * Creates a new identity quat + * + * @returns {quat} a new quaternion + */ + + function create$4() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + out[3] = 1; + return out; + } + /** + * Sets a quat from the given angle and rotation axis, + * then returns it. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyVec3} axis the axis around which to rotate + * @param {Number} rad the angle in radians + * @returns {quat} out + **/ + + function setAxisAngle(out, axis, rad) { + rad = rad * 0.5; + var s = Math.sin(rad); + out[0] = s * axis[0]; + out[1] = s * axis[1]; + out[2] = s * axis[2]; + out[3] = Math.cos(rad); + return out; + } + /** + * Multiplies two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {quat} out + */ + + function multiply(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + out[0] = ax * bw + aw * bx + ay * bz - az * by; + out[1] = ay * bw + aw * by + az * bx - ax * bz; + out[2] = az * bw + aw * bz + ax * by - ay * bx; + out[3] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Performs a spherical linear interpolation between two quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + function slerp(out, a, b, t) { + // benchmarks: + // http://jsperf.com/quaternion-slerp-implementations + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + var omega, cosom, sinom, scale0, scale1; // calc cosine + + cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) + + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } // calculate coefficients + + + if (1.0 - cosom > EPSILON) { + // standard case (slerp) + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } else { + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + scale0 = 1.0 - t; + scale1 = t; + } // calculate final values + + + out[0] = scale0 * ax + scale1 * bx; + out[1] = scale0 * ay + scale1 * by; + out[2] = scale0 * az + scale1 * bz; + out[3] = scale0 * aw + scale1 * bw; + return out; + } + /** + * Calculates the conjugate of a quat + * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate conjugate of + * @returns {quat} out + */ + + function conjugate(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a quaternion from the given 3x3 rotation matrix. + * + * NOTE: The resultant quaternion is not normalized, so you should be sure + * to renormalize the quaternion yourself where necessary. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyMat3} m rotation matrix + * @returns {quat} out + * @function + */ + + function fromMat3(out, m) { + // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + // article "Quaternion Calculus and Fast Animation". + var fTrace = m[0] + m[4] + m[8]; + var fRoot; + + if (fTrace > 0.0) { + // |w| > 1/2, may as well choose w > 1/2 + fRoot = Math.sqrt(fTrace + 1.0); // 2w + + out[3] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; // 1/(4w) + + out[0] = (m[5] - m[7]) * fRoot; + out[1] = (m[6] - m[2]) * fRoot; + out[2] = (m[1] - m[3]) * fRoot; + } else { + // |w| <= 1/2 + var i = 0; + if (m[4] > m[0]) i = 1; + if (m[8] > m[i * 3 + i]) i = 2; + var j = (i + 1) % 3; + var k = (i + 2) % 3; + fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); + out[i] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; + out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; + out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; + } + + return out; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {ReadonlyQuat} a quaternion to clone + * @returns {quat} a new quaternion + * @function + */ + + var clone$1 = clone; + /** + * Creates a new quat initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} a new quaternion + * @function + */ + + var fromValues$2 = fromValues$1; + /** + * Copy the values from one quat to another + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the source quaternion + * @returns {quat} out + * @function + */ + + var copy$2 = copy$1; + /** + * Normalize a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quaternion to normalize + * @returns {quat} out + * @function + */ + + var normalize$2 = normalize$1; + /** + * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyQuat} a The first quaternion. + * @param {ReadonlyQuat} b The second quaternion. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + var exactEquals$1 = exactEquals; + /** + * Returns whether or not the quaternions have approximately the same elements in the same position. + * + * @param {ReadonlyQuat} a The first vector. + * @param {ReadonlyQuat} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + var equals$1 = equals; + /** + * Sets a quaternion to represent the shortest rotation from one + * vector to another. + * + * Both vectors are assumed to be unit length. + * + * @param {quat} out the receiving quaternion. + * @param {ReadonlyVec3} a the initial vector + * @param {ReadonlyVec3} b the destination vector + * @returns {quat} out + */ + + var rotationTo = function () { + var tmpvec3 = create$2(); + var xUnitVec3 = fromValues(1, 0, 0); + var yUnitVec3 = fromValues(0, 1, 0); + return function (out, a, b) { + var dot$1 = dot(a, b); + + if (dot$1 < -0.999999) { + cross(tmpvec3, xUnitVec3, a); + if (len(tmpvec3) < 0.000001) cross(tmpvec3, yUnitVec3, a); + normalize(tmpvec3, tmpvec3); + setAxisAngle(out, tmpvec3, Math.PI); + return out; + } else if (dot$1 > 0.999999) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } else { + cross(tmpvec3, a, b); + out[0] = tmpvec3[0]; + out[1] = tmpvec3[1]; + out[2] = tmpvec3[2]; + out[3] = 1 + dot$1; + return normalize$2(out, out); + } + }; + }(); + /** + * Performs a spherical linear interpolation with two control points + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {ReadonlyQuat} c the third operand + * @param {ReadonlyQuat} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + var sqlerp = function () { + var temp1 = create$4(); + var temp2 = create$4(); + return function (out, a, b, c, d, t) { + slerp(temp1, a, d, t); + slerp(temp2, b, c, t); + slerp(out, temp1, temp2, 2 * t * (1 - t)); + return out; + }; + }(); + /** + * Sets the specified quaternion with values corresponding to the given + * axes. Each axis is a vec3 and is expected to be unit length and + * perpendicular to all other specified axes. + * + * @param {ReadonlyVec3} view the vector representing the viewing direction + * @param {ReadonlyVec3} right the vector representing the local "right" direction + * @param {ReadonlyVec3} up the vector representing the local "up" direction + * @returns {quat} out + */ + + var setAxes = function () { + var matr = create(); + return function (out, view, right, up) { + matr[0] = right[0]; + matr[3] = right[1]; + matr[6] = right[2]; + matr[1] = up[0]; + matr[4] = up[1]; + matr[7] = up[2]; + matr[2] = -view[0]; + matr[5] = -view[1]; + matr[8] = -view[2]; + return normalize$2(out, fromMat3(out, matr)); + }; + }(); + + /** + * 2 Dimensional Vector + * @module vec2 + */ + + /** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */ + + function create$5() { + var out = new ARRAY_TYPE(2); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + } + + return out; + } + /** + * Creates a new vec2 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} a new 2D vector + */ + + function fromValues$3(x, y) { + var out = new ARRAY_TYPE(2); + out[0] = x; + out[1] = y; + return out; + } + /** + * Copy the values from one vec2 to another + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the source vector + * @returns {vec2} out + */ + + function copy$3(out, a) { + out[0] = a[0]; + out[1] = a[1]; + return out; + } + /** + * Normalize a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to normalize + * @returns {vec2} out + */ + + function normalize$3(out, a) { + var x = a[0], + y = a[1]; + var len = x * x + y * y; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + return out; + } + /** + * Calculates the dot product of two vec2's + * + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot$1(a, b) { + return a[0] * b[0] + a[1] * b[1]; + } + /** + * Perform some operation over an array of vec2s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach$2 = function () { + var vec = create$5(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 2; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + } + + return a; + }; + }(); + + /** + * Original Code + * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js + * Math Util + * modified by egjs + */ + + var quatToVec3 = function (quaternion) { + var baseV = fromValues(0, 0, 1); + transformQuat(baseV, baseV, quaternion); + return baseV; + }; + + var toDegree = function (a) { + return a * 180 / Math.PI; + }; + + var util = {}; + + util.isPowerOfTwo = function (n) { + return n && (n & n - 1) === 0; + }; + + util.extractPitchFromQuat = function (quaternion) { + var baseV = quatToVec3(quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + }; + + util.hypot = Math.hypot || function (x, y) { + return Math.sqrt(x * x + y * y); + }; // implement reference + // the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식 + // calculating angle between two vectors : http://darkpgmr.tistory.com/121 + + + var ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] + }; + + var getRotationDelta = function (prevQ, curQ, rotateKind) { + var targetAxis = fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + var meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + var prevQuaternion = clone$1(prevQ); + var curQuaternion = clone$1(curQ); + normalize$2(prevQuaternion, prevQuaternion); + normalize$2(curQuaternion, curQuaternion); + var prevPoint = fromValues(0, 0, 1); + var curPoint = fromValues(0, 0, 1); + transformQuat(prevPoint, prevPoint, prevQuaternion); + transformQuat(curPoint, curPoint, curQuaternion); + transformQuat(targetAxis, targetAxis, curQuaternion); + var rotateDistance = dot(targetAxis, cross(create$2(), prevPoint, curPoint)); + var rotateDirection = rotateDistance > 0 ? 1 : -1; // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + + var meshPoint2 = fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + var meshPoint3; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = fromValues(rotateDirection, 0, 0); + } + + transformQuat(meshPoint2, meshPoint2, curQuaternion); + transformQuat(meshPoint3, meshPoint3, curQuaternion); + var vecU = meshPoint2; + var vecV = meshPoint3; + var vecN = create$2(); + cross(vecN, vecU, vecV); + normalize(vecN, vecN); + var coefficientA = vecN[0]; + var coefficientB = vecN[1]; + var coefficientC = vecN[2]; // const coefficientD = -1 * vec3.dot(vecN, meshPoint1); + // a point on the plane + + curPoint = fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + transformQuat(curPoint, curPoint, curQuaternion); // a point should project on the plane + + prevPoint = fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + transformQuat(prevPoint, prevPoint, prevQuaternion); // distance between prevPoint and the plane + + var distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + var projectedPrevPoint = create$2(); + subtract(projectedPrevPoint, prevPoint, scale(create$2(), vecN, distance)); + var trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (length(projectedPrevPoint) * length(curPoint)); // defensive block + + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + + var theta = Math.acos(trigonometricRatio); + var crossVec = cross(create$2(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + var thetaDirection; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + + var deltaRadian = theta * thetaDirection * rotateDirection; + return toDegree(deltaRadian); + }; + + var angleBetweenVec2 = function (v1, v2) { + var det = v1[0] * v2[1] - v2[0] * v1[1]; + var theta = -Math.atan2(det, dot$1(v1, v2)); + return theta; + }; + + util.yawOffsetBetween = function (viewDir, targetDir) { + var viewDirXZ = fromValues$3(viewDir[0], viewDir[2]); + var targetDirXZ = fromValues$3(targetDir[0], targetDir[2]); + normalize$3(viewDirXZ, viewDirXZ); + normalize$3(targetDirXZ, targetDirXZ); + var theta = -angleBetweenVec2(viewDirXZ, targetDirXZ); + return theta; + }; + + util.sign = function (x) { + return Math.sign ? Math.sign(x) : Number(x > 0) - Number(x < 0) || +x; + }; + + util.toDegree = toDegree; + util.getRotationDelta = getRotationDelta; + util.angleBetweenVec2 = angleBetweenVec2; + + var toAxis$1 = function (source, offset) { + return offset.reduce(function (acc, v, i) { + if (source[i]) { + acc[source[i]] = v; + } + + return acc; + }, {}); + }; + + /** + * Returns a number value indiciating the version of Chrome being used, + * or otherwise `null` if not on Chrome. + * + * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19 + */ + + /** + * In Chrome m65, `devicemotion` events are broken but subsequently fixed + * in 65.0.3325.148. Since many browsers use Chromium, ensure that + * we scope this detection by branch and build numbers to provide + * a proper fallback. + * https://github.com/immersive-web/webvr-polyfill/issues/307 + */ + + var version = -1; // It should not be null because it will be compared with number + + var branch = null; + var build = null; + var match = /Chrome\/([0-9]+)\.(?:[0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(userAgent); + + if (match) { + version = parseInt(match[1], 10); + branch = match[2]; + build = match[3]; + } + + var CHROME_VERSION = version; + var IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === "3325" && parseInt(build, 10) < 148; + var IS_ANDROID = /Android/i.test(userAgent); + var CONTROL_MODE_VR = 1; + var CONTROL_MODE_YAWPITCH = 2; + var TOUCH_DIRECTION_NONE = 1; + var TOUCH_DIRECTION_YAW = 2; + var TOUCH_DIRECTION_PITCH = 4; + var TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH; + /* Const for MovableCoord */ + + var MC_DECELERATION = 0.0014; + var MC_MAXIMUM_DURATION = 1000; + var MC_BIND_SCALE = [0.20, 0.20]; + var MAX_FIELD_OF_VIEW = 110; + var PAN_SCALE = 320; // const DELTA_THRESHOLD = 0.015; + + var YAW_RANGE_HALF = 180; + var PITCH_RANGE_HALF = 90; + var CIRCULAR_PITCH_RANGE_HALF = 180; + var GYRO_MODE = { + NONE: "none", + YAWPITCH: "yawPitch", + VR: "VR" + }; + + /* eslint-disable */ + var MathUtil = win.MathUtil || {}; + MathUtil.degToRad = Math.PI / 180; + MathUtil.radToDeg = 180 / Math.PI; // Some minimal math functionality borrowed from THREE.Math and stripped down + // for the purposes of this library. + + MathUtil.Vector2 = function (x, y) { + this.x = x || 0; + this.y = y || 0; + }; + + MathUtil.Vector2.prototype = { + constructor: MathUtil.Vector2, + set: function (x, y) { + this.x = x; + this.y = y; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + return this; + }, + subVectors: function (a, b) { + this.x = a.x - b.x; + this.y = a.y - b.y; + return this; + } + }; + + MathUtil.Vector3 = function (x, y, z) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + }; + + MathUtil.Vector3.prototype = { + constructor: MathUtil.Vector3, + set: function (x, y, z) { + this.x = x; + this.y = y; + this.z = z; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + return this; + }, + length: function () { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + }, + normalize: function () { + var scalar = this.length(); + + if (scalar !== 0) { + var invScalar = 1 / scalar; + this.multiplyScalar(invScalar); + } else { + this.x = 0; + this.y = 0; + this.z = 0; + } + + return this; + }, + multiplyScalar: function (scalar) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + }, + applyQuaternion: function (q) { + var x = this.x; + var y = this.y; + var z = this.z; + var qx = q.x; + var qy = q.y; + var qz = q.z; + var qw = q.w; // calculate quat * vector + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + + this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return this; + }, + dot: function (v) { + return this.x * v.x + this.y * v.y + this.z * v.z; + }, + crossVectors: function (a, b) { + var ax = a.x; + var ay = a.y; + var az = a.z; + var bx = b.x; + var by = b.y; + var bz = b.z; + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; + return this; + } + }; + + MathUtil.Quaternion = function (x, y, z, w) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w !== undefined ? w : 1; + }; + + MathUtil.Quaternion.prototype = { + constructor: MathUtil.Quaternion, + set: function (x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + return this; + }, + copy: function (quaternion) { + this.x = quaternion.x; + this.y = quaternion.y; + this.z = quaternion.z; + this.w = quaternion.w; + return this; + }, + setFromEulerXYZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + return this; + }, + setFromEulerYXZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + return this; + }, + setFromAxisAngle: function (axis, angle) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // assumes axis is normalized + var halfAngle = angle / 2; + var s = Math.sin(halfAngle); + this.x = axis.x * s; + this.y = axis.y * s; + this.z = axis.z * s; + this.w = Math.cos(halfAngle); + return this; + }, + multiply: function (q) { + return this.multiplyQuaternions(this, q); + }, + multiplyQuaternions: function (a, b) { + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + var qax = a.x; + var qay = a.y; + var qaz = a.z; + var qaw = a.w; + var qbx = b.x; + var qby = b.y; + var qbz = b.z; + var qbw = b.w; + this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; + return this; + }, + inverse: function () { + this.x *= -1; + this.y *= -1; + this.z *= -1; + this.normalize(); + return this; + }, + normalize: function () { + var l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + + if (l === 0) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 1; + } else { + l = 1 / l; + this.x = this.x * l; + this.y = this.y * l; + this.z = this.z * l; + this.w = this.w * l; + } + + return this; + }, + slerp: function (qb, t) { + if (t === 0) return this; + if (t === 1) return this.copy(qb); + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + + var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z; + + if (cosHalfTheta < 0) { + this.w = -qb.w; + this.x = -qb.x; + this.y = -qb.y; + this.z = -qb.z; + cosHalfTheta = -cosHalfTheta; + } else { + this.copy(qb); + } + + if (cosHalfTheta >= 1.0) { + this.w = w; + this.x = x; + this.y = y; + this.z = z; + return this; + } + + var halfTheta = Math.acos(cosHalfTheta); + var sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta); + + if (Math.abs(sinHalfTheta) < 0.001) { + this.w = 0.5 * (w + this.w); + this.x = 0.5 * (x + this.x); + this.y = 0.5 * (y + this.y); + this.z = 0.5 * (z + this.z); + return this; + } + + var ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta; + var ratioB = Math.sin(t * halfTheta) / sinHalfTheta; + this.w = w * ratioA + this.w * ratioB; + this.x = x * ratioA + this.x * ratioB; + this.y = y * ratioA + this.y * ratioB; + this.z = z * ratioA + this.z * ratioB; + return this; + }, + setFromUnitVectors: function () { + // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final + // assumes direction vectors vFrom and vTo are normalized + var v1; + var r; + var EPS = 0.000001; + return function (vFrom, vTo) { + if (v1 === undefined) v1 = new MathUtil.Vector3(); + r = vFrom.dot(vTo) + 1; + + if (r < EPS) { + r = 0; + + if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { + v1.set(-vFrom.y, vFrom.x, 0); + } else { + v1.set(0, -vFrom.z, vFrom.y); + } + } else { + v1.crossVectors(vFrom, vTo); + } + + this.x = v1.x; + this.y = v1.y; + this.z = v1.z; + this.w = r; + this.normalize(); + return this; + }; + }() + }; + + /* eslint-disable */ + + /* + * Copyright 2015 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + var _a; // tslint:disable: only-arrow-functions + var userAgent$1 = (_a = nav === null || nav === void 0 ? void 0 : nav.userAgent) !== null && _a !== void 0 ? _a : ""; + var Util = win.Util || {}; + Util.MIN_TIMESTEP = 0.001; + Util.MAX_TIMESTEP = 1; + + Util.base64 = function (mimeType, base64) { + return "data:" + mimeType + ";base64," + base64; + }; + + Util.clamp = function (value, min, max) { + return Math.min(Math.max(min, value), max); + }; + + Util.lerp = function (a, b, t) { + return a + (b - a) * t; + }; + + Util.isIOS = function () { + var isIOS = /iPad|iPhone|iPod/.test(nav === null || nav === void 0 ? void 0 : nav.platform); + return function () { + return isIOS; + }; + }(); + + Util.isWebViewAndroid = function () { + var isWebViewAndroid = userAgent$1.indexOf("Version") !== -1 && userAgent$1.indexOf("Android") !== -1 && userAgent$1.indexOf("Chrome") !== -1; + return function () { + return isWebViewAndroid; + }; + }(); + + Util.isSafari = function () { + var isSafari = /^((?!chrome|android).)*safari/i.test(userAgent$1); + return function () { + return isSafari; + }; + }(); + + Util.isFirefoxAndroid = function () { + var isFirefoxAndroid = userAgent$1.indexOf("Firefox") !== -1 && userAgent$1.indexOf("Android") !== -1; + return function () { + return isFirefoxAndroid; + }; + }(); + + Util.isR7 = function () { + var isR7 = userAgent$1.indexOf("R7 Build") !== -1; + return function () { + return isR7; + }; + }(); + + Util.isLandscapeMode = function () { + var rtn = win.orientation === 90 || win.orientation === -90; + return Util.isR7() ? !rtn : rtn; + }; // Helper method to validate the time steps of sensor timestamps. + + + Util.isTimestampDeltaValid = function (timestampDeltaS) { + if (isNaN(timestampDeltaS)) { + return false; + } + + if (timestampDeltaS <= Util.MIN_TIMESTEP) { + return false; + } + + if (timestampDeltaS > Util.MAX_TIMESTEP) { + return false; + } + + return true; + }; + + Util.getScreenWidth = function () { + return Math.max(win.screen.width, win.screen.height) * win.devicePixelRatio; + }; + + Util.getScreenHeight = function () { + return Math.min(win.screen.width, win.screen.height) * win.devicePixelRatio; + }; + + Util.requestFullscreen = function (element) { + if (Util.isWebViewAndroid()) { + return false; + } + + if (element.requestFullscreen) { + element.requestFullscreen(); + } else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } else { + return false; + } + + return true; + }; + + Util.exitFullscreen = function () { + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else if (doc.webkitExitFullscreen) { + doc.webkitExitFullscreen(); + } else if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } else { + return false; + } + + return true; + }; + + Util.getFullscreenElement = function () { + return doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement; + }; + + Util.linkProgram = function (gl, vertexSource, fragmentSource, attribLocationMap) { + // No error checking for brevity. + var vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vertexSource); + gl.compileShader(vertexShader); + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + for (var attribName in attribLocationMap) gl.bindAttribLocation(program, attribLocationMap[attribName], attribName); + + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + return program; + }; + + Util.getProgramUniforms = function (gl, program) { + var uniforms = {}; + var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + var uniformName = ""; + + for (var i = 0; i < uniformCount; i++) { + var uniformInfo = gl.getActiveUniform(program, i); + uniformName = uniformInfo.name.replace("[0]", ""); + uniforms[uniformName] = gl.getUniformLocation(program, uniformName); + } + + return uniforms; + }; + + Util.orthoMatrix = function (out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 2 * nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = (far + near) * nf; + out[15] = 1; + return out; + }; + + Util.copyArray = function (source, dest) { + for (var i = 0, n = source.length; i < n; i++) { + dest[i] = source[i]; + } + }; + + Util.isMobile = function () { + var check = false; + + (function (a) { + if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; + })(userAgent$1 || (nav === null || nav === void 0 ? void 0 : nav.vendor) || win.opera); + + return check; + }; + + Util.extend = function (dest, src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dest[key] = src[key]; + } + } + + return dest; + }; + + Util.safariCssSizeWorkaround = function (canvas) { + // TODO(smus): Remove this workaround when Safari for iOS is fixed. + // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556). + // + // "To the last I grapple with thee; + // from hell's heart I stab at thee; + // for hate's sake I spit my last breath at thee." + // -- Moby Dick, by Herman Melville + if (Util.isIOS()) { + var width_1 = canvas.style.width; + var height_1 = canvas.style.height; + canvas.style.width = parseInt(width_1) + 1 + "px"; + canvas.style.height = parseInt(height_1) + "px"; + setTimeout(function () { + canvas.style.width = width_1; + canvas.style.height = height_1; + }, 100); + } // Debug only. + + + win.Util = Util; + win.canvas = canvas; + }; + + Util.isDebug = function () { + return Util.getQueryParameter("debug"); + }; + + Util.getQueryParameter = function (name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"); + var results = regex.exec(location.search); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); + }; + + Util.frameDataFromPose = function () { + var piOver180 = Math.PI / 180.0; + var rad45 = Math.PI * 0.25; // Borrowed from glMatrix. + + function mat4_perspectiveFromFieldOfView(out, fov, near, far) { + var upTan = Math.tan(fov ? fov.upDegrees * piOver180 : rad45); + var downTan = Math.tan(fov ? fov.downDegrees * piOver180 : rad45); + var leftTan = Math.tan(fov ? fov.leftDegrees * piOver180 : rad45); + var rightTan = Math.tan(fov ? fov.rightDegrees * piOver180 : rad45); + var xScale = 2.0 / (leftTan + rightTan); + var yScale = 2.0 / (upTan + downTan); + out[0] = xScale; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + out[4] = 0.0; + out[5] = yScale; + out[6] = 0.0; + out[7] = 0.0; + out[8] = -((leftTan - rightTan) * xScale * 0.5); + out[9] = (upTan - downTan) * yScale * 0.5; + out[10] = far / (near - far); + out[11] = -1.0; + out[12] = 0.0; + out[13] = 0.0; + out[14] = far * near / (near - far); + out[15] = 0.0; + return out; + } + + function mat4_fromRotationTranslation(out, q, v) { + // Quaternion math + var x = q[0]; + var y = q[1]; + var z = q[2]; + var w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - (yy + zz); + out[1] = xy + wz; + out[2] = xz - wy; + out[3] = 0; + out[4] = xy - wz; + out[5] = 1 - (xx + zz); + out[6] = yz + wx; + out[7] = 0; + out[8] = xz + wy; + out[9] = yz - wx; + out[10] = 1 - (xx + yy); + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + + function mat4_translate(out, a, v) { + var x = v[0]; + var y = v[1]; + var z = v[2]; + var a00; + var a01; + var a02; + var a03; + var a10; + var a11; + var a12; + var a13; + var a20; + var a21; + var a22; + var a23; + + if (a === out) { + out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; + out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; + out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; + out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; + } else { + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a03; + out[4] = a10; + out[5] = a11; + out[6] = a12; + out[7] = a13; + out[8] = a20; + out[9] = a21; + out[10] = a22; + out[11] = a23; + out[12] = a00 * x + a10 * y + a20 * z + a[12]; + out[13] = a01 * x + a11 * y + a21 * z + a[13]; + out[14] = a02 * x + a12 * y + a22 * z + a[14]; + out[15] = a03 * x + a13 * y + a23 * z + a[15]; + } + + return out; + } + + function mat4_invert(out, a) { + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + var a30 = a[12]; + var a31 = a[13]; + var a32 = a[14]; + var a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + return out; + } + + var defaultOrientation = new Float32Array([0, 0, 0, 1]); + var defaultPosition = new Float32Array([0, 0, 0]); + + function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) { + mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar); + var orientation = pose.orientation || defaultOrientation; + var position = pose.position || defaultPosition; + mat4_fromRotationTranslation(view, orientation, position); + if (parameters) mat4_translate(view, view, parameters.offset); + mat4_invert(view, view); + } + + return function (frameData, pose, vrDisplay) { + if (!frameData || !pose) return false; + frameData.pose = pose; + frameData.timestamp = pose.timestamp; + updateEyeMatrices(frameData.leftProjectionMatrix, frameData.leftViewMatrix, pose, vrDisplay.getEyeParameters("left"), vrDisplay); + updateEyeMatrices(frameData.rightProjectionMatrix, frameData.rightViewMatrix, pose, vrDisplay.getEyeParameters("right"), vrDisplay); + return true; + }; + }(); + + Util.isInsideCrossDomainIFrame = function () { + var isFramed = win.self !== win.top; + var refDomain = Util.getDomainFromUrl(doc.referrer); + var thisDomain = Util.getDomainFromUrl(win.location.href); + return isFramed && refDomain !== thisDomain; + }; // From http://stackoverflow.com/a/23945027. + + + Util.getDomainFromUrl = function (url) { + var domain; // Find & remove protocol (http, ftp, etc.) and get domain. + + if (url.indexOf("://") > -1) { + domain = url.split("/")[2]; + } else { + domain = url.split("/")[0]; + } // find & remove port number + + + domain = domain.split(":")[0]; + return domain; + }; + + /* eslint-disable */ + /** + * Given an orientation and the gyroscope data, predicts the future orientation + * of the head. This makes rendering appear faster. + * + * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf + * @param {Number} predictionTimeS time from head movement to the appearance of + * the corresponding image. + */ + + var PosePredictor = + /*#__PURE__*/ + function () { + function PosePredictor(predictionTimeS) { + this.predictionTimeS = predictionTimeS; // The quaternion corresponding to the previous state. + + this.previousQ = new MathUtil.Quaternion(); // Previous time a prediction occurred. + + this.previousTimestampS = null; // The delta quaternion that adjusts the current pose. + + this.deltaQ = new MathUtil.Quaternion(); // The output quaternion. + + this.outQ = new MathUtil.Quaternion(); + } + + var __proto = PosePredictor.prototype; + + __proto.getPrediction = function (currentQ, gyro, timestampS) { + if (!this.previousTimestampS) { + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return currentQ; + } // Calculate axis and angle based on gyroscope rotation rate data. + + + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + var angularSpeed = gyro.length(); // If we're rotating slowly, don't do prediction. + + if (angularSpeed < MathUtil.degToRad * 20) { + if (Util.isDebug()) { + console.log("Moving slowly, at %s deg/s: no prediction", (MathUtil.radToDeg * angularSpeed).toFixed(1)); + } + + this.outQ.copy(currentQ); + this.previousQ.copy(currentQ); + return this.outQ; + } // Get the predicted angle based on the time delta and latency. + + + var deltaT = timestampS - this.previousTimestampS; + var predictAngle = angularSpeed * this.predictionTimeS; + this.deltaQ.setFromAxisAngle(axis, predictAngle); + this.outQ.copy(this.previousQ); + this.outQ.multiply(this.deltaQ); + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return this.outQ; + }; + + return PosePredictor; + }(); + + var STILLNESS_THRESHOLD = 200; // millisecond + + var DeviceMotion = + /*#__PURE__*/ + function (_super) { + __extends(DeviceMotion, _super); + + function DeviceMotion() { + var _this = _super.call(this) || this; + + _this._onDeviceMotion = _this._onDeviceMotion.bind(_this); + _this._onDeviceOrientation = _this._onDeviceOrientation.bind(_this); + _this._onChromeWithoutDeviceMotion = _this._onChromeWithoutDeviceMotion.bind(_this); + _this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION; + _this.isAndroid = IS_ANDROID; + _this.stillGyroVec = create$2(); + _this.rawGyroVec = create$2(); + _this.adjustedGyroVec = create$2(); + _this._timer = -1; + _this.lastDevicemotionTimestamp = 0; + _this._isEnabled = false; + + _this.enable(); + + return _this; + } + + var __proto = DeviceMotion.prototype; + + __proto.enable = function () { + if (this.isAndroid) { + win.addEventListener("deviceorientation", this._onDeviceOrientation); + } + + if (this.isWithoutDeviceMotion) { + win.addEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + } else { + win.addEventListener("devicemotion", this._onDeviceMotion); + } + + this._isEnabled = true; + }; + + __proto.disable = function () { + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + win.removeEventListener("devicemotion", this._onDeviceMotion); + this._isEnabled = false; + }; + + __proto._onChromeWithoutDeviceMotion = function (e) { + var alpha = e.alpha, + beta = e.beta, + gamma = e.gamma; // There is deviceorientation event trigged with empty values + // on Headless Chrome. + + if (alpha === null) { + return; + } // convert to radian + + + alpha = (alpha || 0) * Math.PI / 180; + beta = (beta || 0) * Math.PI / 180; + gamma = (gamma || 0) * Math.PI / 180; + this.trigger(new ComponentEvent$1("devicemotion", { + inputEvent: { + deviceorientation: { + alpha: alpha, + beta: beta, + gamma: -gamma + } + } + })); + }; + + __proto._onDeviceOrientation = function () { + var _this = this; + + if (this._timer) { + clearTimeout(this._timer); + } + + this._timer = win.setTimeout(function () { + if (new Date().getTime() - _this.lastDevicemotionTimestamp < STILLNESS_THRESHOLD) { + copy(_this.stillGyroVec, _this.rawGyroVec); + } + }, STILLNESS_THRESHOLD); + }; + + __proto._onDeviceMotion = function (e) { + // desktop chrome triggers devicemotion event with empthy sensor values. + // Those events should ignored. + var isGyroSensorAvailable = !(e.rotationRate.alpha == null); + var isGravitySensorAvailable = !(e.accelerationIncludingGravity.x == null); + + if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) { + return; + } + + var devicemotionEvent = __assign({}, e); + + devicemotionEvent.interval = e.interval; + devicemotionEvent.timeStamp = e.timeStamp; + devicemotionEvent.type = e.type; + devicemotionEvent.rotationRate = { + alpha: e.rotationRate.alpha, + beta: e.rotationRate.beta, + gamma: e.rotationRate.gamma + }; + devicemotionEvent.accelerationIncludingGravity = { + x: e.accelerationIncludingGravity.x, + y: e.accelerationIncludingGravity.y, + z: e.accelerationIncludingGravity.z + }; + devicemotionEvent.acceleration = { + x: e.acceleration.x, + y: e.acceleration.y, + z: e.acceleration.z + }; + + if (this.isAndroid) { + set(this.rawGyroVec, e.rotationRate.alpha || 0, e.rotationRate.beta || 0, e.rotationRate.gamma || 0); + subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec); + this.lastDevicemotionTimestamp = new Date().getTime(); + devicemotionEvent.adjustedRotationRate = { + alpha: this.adjustedGyroVec[0], + beta: this.adjustedGyroVec[1], + gamma: this.adjustedGyroVec[2] + }; + } + + this.trigger(new ComponentEvent$1("devicemotion", { + inputEvent: devicemotionEvent + })); + }; + + return DeviceMotion; + }(Component); + + var SensorSample = + /*#__PURE__*/ + function () { + function SensorSample(sample, timestampS) { + this.set(sample, timestampS); + } + + var __proto = SensorSample.prototype; + + __proto.set = function (sample, timestampS) { + this.sample = sample; + this.timestampS = timestampS; + }; + + __proto.copy = function (sensorSample) { + this.set(sensorSample.sample, sensorSample.timestampS); + }; + + return SensorSample; + }(); + + /* eslint-disable */ + /** + * An implementation of a simple complementary filter, which fuses gyroscope and + * accelerometer data from the 'devicemotion' event. + * + * Accelerometer data is very noisy, but stable over the long term. + * Gyroscope data is smooth, but tends to drift over the long term. + * + * This fusion is relatively simple: + * 1. Get orientation estimates from accelerometer by applying a low-pass filter + * on that data. + * 2. Get orientation estimates from gyroscope by integrating over time. + * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the + * short term. + */ + + var ComplementaryFilter = + /*#__PURE__*/ + function () { + function ComplementaryFilter(kFilter) { + this.addGyroMeasurement = function (vector, timestampS) { + this.currentGyroMeasurement.set(vector, timestampS); + var deltaT = timestampS - this.previousGyroMeasurement.timestampS; + + if (Util.isTimestampDeltaValid(deltaT)) { + this.run_(); + } + + this.previousGyroMeasurement.copy(this.currentGyroMeasurement); + }; + + this.kFilter = kFilter; // Raw sensor measurements. + + this.currentAccelMeasurement = new SensorSample(); + this.currentGyroMeasurement = new SensorSample(); + this.previousGyroMeasurement = new SensorSample(); // Set default look direction to be in the correct direction. + + if (Util.isIOS()) { + this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1); + } else { + this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1); + } + + this.previousFilterQ = new MathUtil.Quaternion(); + this.previousFilterQ.copy(this.filterQ); // Orientation based on the accelerometer. + + this.accelQ = new MathUtil.Quaternion(); // Whether or not the orientation has been initialized. + + this.isOrientationInitialized = false; // Running estimate of gravity based on the current orientation. + + this.estimatedGravity = new MathUtil.Vector3(); // Measured gravity based on accelerometer. + + this.measuredGravity = new MathUtil.Vector3(); // Debug only quaternion of gyro-based orientation. + + this.gyroIntegralQ = new MathUtil.Quaternion(); + } + + var __proto = ComplementaryFilter.prototype; + + __proto.addAccelMeasurement = function (vector, timestampS) { + this.currentAccelMeasurement.set(vector, timestampS); + }; + + __proto.getOrientation = function () { + return this.filterQ; + }; + + __proto.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); + + if (Util.isDebug()) { + console.log("Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)", MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ), this.estimatedGravity.x.toFixed(1), this.estimatedGravity.y.toFixed(1), this.estimatedGravity.z.toFixed(1), this.measuredGravity.x.toFixed(1), this.measuredGravity.y.toFixed(1), this.measuredGravity.z.toFixed(1)); + } // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + }; + + __proto.accelToQuaternion_ = function (accel) { + var normAccel = new MathUtil.Vector3(); + normAccel.copy(accel); + normAccel.normalize(); + var quat = new MathUtil.Quaternion(); + quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel); + quat.inverse(); + return quat; + }; + + __proto.gyroToQuaternionDelta_ = function (gyro, dt) { + // Extract axis and angle from the gyroscope data. + var quat = new MathUtil.Quaternion(); + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + quat.setFromAxisAngle(axis, gyro.length() * dt); + return quat; + }; + + return ComplementaryFilter; + }(); + + ComplementaryFilter.prototype.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + + if (!this.isFilterQuaternionInitialized) { + this.isFilterQuaternionInitialized = true; + } + }; + + ComplementaryFilter.prototype.getOrientation = function () { + if (this.isFilterQuaternionInitialized) { + return this.filterQ; + } else { + return null; + } + }; + + var K_FILTER = 0.98; + var PREDICTION_TIME_S = 0.040; + + var FusionPoseSensor = + /*#__PURE__*/ + function (_super) { + __extends(FusionPoseSensor, _super); + + function FusionPoseSensor() { + var _this = _super.call(this) || this; + + _this.deviceMotion = new DeviceMotion(); + _this.accelerometer = new MathUtil.Vector3(); + _this.gyroscope = new MathUtil.Vector3(); + _this._onDeviceMotionChange = _this._onDeviceMotionChange.bind(_this); + _this._onScreenOrientationChange = _this._onScreenOrientationChange.bind(_this); + _this.filter = new ComplementaryFilter(K_FILTER); + _this.posePredictor = new PosePredictor(PREDICTION_TIME_S); + _this.filterToWorldQ = new MathUtil.Quaternion(); + _this.isFirefoxAndroid = Util.isFirefoxAndroid(); // This includes iPhone & iPad(both desktop and mobile mode) ref #326 + + _this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP; // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18 + + _this.isChromeUsingDegrees = CHROME_VERSION >= 66; + _this._isEnabled = false; // Set the filter to world transform, depending on OS. + + if (_this.isIOS) { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2); + } else { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2); + } + + _this.inverseWorldToScreenQ = new MathUtil.Quaternion(); + _this.worldToScreenQ = new MathUtil.Quaternion(); + _this.originalPoseAdjustQ = new MathUtil.Quaternion(); + + _this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -win.orientation * Math.PI / 180); + + _this._setScreenTransform(); // Adjust this filter for being in landscape mode. + + + if (Util.isLandscapeMode()) { + _this.filterToWorldQ.multiply(_this.inverseWorldToScreenQ); + } // Keep track of a reset transform for resetSensor. + + + _this.resetQ = new MathUtil.Quaternion(); + + _this.deviceMotion.on("devicemotion", _this._onDeviceMotionChange); + + _this.enable(); + + return _this; + } + + var __proto = FusionPoseSensor.prototype; + + __proto.enable = function () { + if (this.isEnabled()) { + return; + } + + this.deviceMotion.enable(); + this._isEnabled = true; + win.addEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.disable = function () { + if (!this.isEnabled()) { + return; + } + + this.deviceMotion.disable(); + this._isEnabled = false; + win.removeEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.isEnabled = function () { + return this._isEnabled; + }; + + __proto.destroy = function () { + this.disable(); + this.deviceMotion = null; + }; + + __proto.getOrientation = function () { + var _this = this; + + var orientation; // Hack around using deviceorientation instead of devicemotion + + if (this.deviceMotion.isWithoutDeviceMotion && this._deviceOrientationQ) { + this.deviceOrientationFixQ = this.deviceOrientationFixQ || function () { + var y = new MathUtil.Quaternion().setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -_this._alpha); + return y; + }(); + + orientation = this._deviceOrientationQ; + var out = new MathUtil.Quaternion(); + out.copy(orientation); + out.multiply(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.worldToScreenQ); + out.multiplyQuaternions(this.deviceOrientationFixQ, out); // return quaternion as glmatrix quaternion object + + var outQuat = fromValues$2(out.x, out.y, out.z, out.w); + return normalize$2(outQuat, outQuat); + } else { + // Convert from filter space to the the same system used by the + // deviceorientation event. + orientation = this.filter.getOrientation(); + + if (!orientation) { + return null; + } + + var out = this._convertFusionToPredicted(orientation); // return quaternion as glmatrix quaternion object + + + var outQuat = fromValues$2(out.x, out.y, out.z, out.w); + return normalize$2(outQuat, outQuat); + } + }; + + __proto._triggerChange = function () { + var orientation = this.getOrientation(); // if orientation is not prepared. don't trigger change event + + if (!orientation) { + return; + } + + if (!this._prevOrientation) { + this._prevOrientation = orientation; + return; + } + + if (equals$1(this._prevOrientation, orientation)) { + return; + } + + this.trigger(new ComponentEvent$1("change", { + quaternion: orientation + })); + }; + + __proto._convertFusionToPredicted = function (orientation) { + // Predict orientation. + this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS); // Convert to THREE coordinate system: -Z forward, Y up, X right. + + var out = new MathUtil.Quaternion(); + out.copy(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.predictedQ); + out.multiply(this.worldToScreenQ); + return out; + }; + + __proto._onDeviceMotionChange = function (_a) { + var inputEvent = _a.inputEvent; + var deviceorientation = inputEvent.deviceorientation; + var deviceMotion = inputEvent; + var accGravity = deviceMotion.accelerationIncludingGravity; + var rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate; + var timestampS = deviceMotion.timeStamp / 1000; + + if (deviceorientation) { + if (!this._alpha) { + this._alpha = deviceorientation.alpha; + } + + this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion(); + + this._deviceOrientationQ.setFromEulerYXZ(deviceorientation.beta, deviceorientation.alpha, deviceorientation.gamma); + + this._triggerChange(); + } else { + // Firefox Android timeStamp returns one thousandth of a millisecond. + if (this.isFirefoxAndroid) { + timestampS /= 1000; + } + + this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z); + this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma); // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate` + // is reported in degrees, so we first convert to radians. + + if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) { + this.gyroscope.multiplyScalar(Math.PI / 180); + } + + this.filter.addAccelMeasurement(this.accelerometer, timestampS); + this.filter.addGyroMeasurement(this.gyroscope, timestampS); + + this._triggerChange(); + + this.previousTimestampS = timestampS; + } + }; + + __proto._onScreenOrientationChange = function () { + this._setScreenTransform(); + }; + + __proto._setScreenTransform = function () { + this.worldToScreenQ.set(0, 0, 0, 1); + var orientation = win.orientation; + + switch (orientation) { + case 0: + break; + + case 90: + case -90: + case 180: + this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI); + break; + } + + this.inverseWorldToScreenQ.copy(this.worldToScreenQ); + this.inverseWorldToScreenQ.inverse(); + }; + + return FusionPoseSensor; + }(Component); + + var getDeltaYaw = function (prvQ, curQ) { + var yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + var yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(util.extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + }; + + var getDeltaPitch = function (prvQ, curQ) { + var pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + return pitchDelta; + }; // eslint-disable-next-line @typescript-eslint/ban-types + + + var TiltMotionInput = + /*#__PURE__*/ + function (_super) { + __extends(TiltMotionInput, _super); + + function TiltMotionInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.element = el; + _this._prevQuaternion = null; + _this._quaternion = null; + _this.fusionPoseSensor = null; + _this.options = __assign({ + scale: 1, + threshold: 0 + }, options); + _this._onPoseChange = _this._onPoseChange.bind(_this); + return _this; + } + + var __proto = TiltMotionInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this.observer) { + return this; + } + + this.observer = observer; + this.fusionPoseSensor = new FusionPoseSensor(); + this.fusionPoseSensor.enable(); + + this._attachEvent(); + + return this; + }; + + __proto.disconnect = function () { + if (!this.observer) { + return this; + } + + this._dettachEvent(); + + this.fusionPoseSensor.disable(); + this.fusionPoseSensor.destroy(); + this.fusionPoseSensor = null; + this.observer = null; + return this; + }; + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + this.options = null; + this.axes = null; + this._prevQuaternion = null; + this._quaternion = null; + }; + + __proto._onPoseChange = function (event) { + if (!this._prevQuaternion) { + this._prevQuaternion = clone$1(event.quaternion); + this._quaternion = clone$1(event.quaternion); + return; + } + + copy$2(this._prevQuaternion, this._quaternion); + copy$2(this._quaternion, event.quaternion); + this.observer.change(this, event, toAxis$1(this.axes, [getDeltaYaw(this._prevQuaternion, this._quaternion), getDeltaPitch(this._prevQuaternion, this._quaternion)])); + }; + + __proto._attachEvent = function () { + this.fusionPoseSensor.on("change", this._onPoseChange); + }; + + __proto._dettachEvent = function () { + this.fusionPoseSensor.off("change", this._onPoseChange); + }; + + return TiltMotionInput; + }(Component); + + var screenRotationAngleInst = null; + var refCount = 0; + + var ScreenRotationAngle = + /*#__PURE__*/ + function () { + function ScreenRotationAngle() { + refCount++; + + if (screenRotationAngleInst) { + return screenRotationAngleInst; + } + /* eslint-disable */ + + + screenRotationAngleInst = this; + /* eslint-enable */ + + this._onDeviceOrientation = this._onDeviceOrientation.bind(this); + this._onOrientationChange = this._onOrientationChange.bind(this); + this._spinR = 0; + this._screenOrientationAngle = 0; + win.addEventListener("deviceorientation", this._onDeviceOrientation); + win.addEventListener("orientationchange", this._onOrientationChange); + } + + var __proto = ScreenRotationAngle.prototype; + + __proto.getRadian = function () { + // Join with screen orientation + // this._testVal = this._spinR + ", " + this._screenOrientationAngle + ", " + window.orientation; + return this._spinR + toRadian(this._screenOrientationAngle); + }; + + __proto.unref = function () { + if (--refCount > 0) { + return; + } + + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("orientationchange", this._onOrientationChange); + this._spinR = 0; + this._screenOrientationAngle = 0; + /* eslint-disable */ + + screenRotationAngleInst = null; + /* eslint-enable */ + + refCount = 0; + }; + + __proto._onDeviceOrientation = function (e) { + if (e.beta === null || e.gamma === null) { + // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it. + return; + } // Radian + + + var betaR = toRadian(e.beta); + var gammaR = toRadian(e.gamma); + /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */ + + this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR)); + }; + + __proto._onOrientationChange = function () { + if (win.screen && win.screen.orientation && win.screen.orientation.angle !== undefined) { + this._screenOrientationAngle = screen.orientation.angle; + } else if (win.orientation !== undefined) { + /* iOS */ + this._screenOrientationAngle = win.orientation >= 0 ? win.orientation : 360 + win.orientation; + } + }; + + return ScreenRotationAngle; + }(); + + /** + * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle. + * + * The reason for using this function is that in VR mode, + * the roll angle is adjusted in the direction opposite to the screen rotation angle. + * + * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move. + * @extends PanInput + */ + + var RotationPanInput = + /*#__PURE__*/ + function (_super) { + __extends(RotationPanInput, _super); + /** + * Constructor + * @private + * @param {HTMLElement} el target element + * @param {Object} [options] The option object + * @param {Boolean} [options.useRotation] Whether to use rotation(or VR) + */ + + + function RotationPanInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this, el, options) || this; + + _this._useRotation = false; + _this._screenRotationAngle = null; + + _this.setUseRotation(!!(options && options.useRotation)); + + _this._userDirection = Axes.DIRECTION_ALL; + return _this; + } + + var __proto = RotationPanInput.prototype; + + __proto.setUseRotation = function (useRotation) { + this._useRotation = useRotation; + + if (this._screenRotationAngle) { + this._screenRotationAngle.unref(); + + this._screenRotationAngle = null; + } + + if (this._useRotation) { + this._screenRotationAngle = new ScreenRotationAngle(); + } + }; + + __proto.connect = function (observer) { + // User intetened direction + this._userDirection = this._direction; // In VR Mode, Use ALL direction if direction is not none + // Because horizontal and vertical is changed dynamically by screen rotation. + // this._direction is used to initialize hammerjs + + if (this._useRotation && this._direction & Axes.DIRECTION_ALL) { + this._direction = Axes.DIRECTION_HORIZONTAL; + } + + return _super.prototype.connect.call(this, observer); + }; + + __proto.destroy = function () { + if (this._useRotation && this._screenRotationAngle) { + this._screenRotationAngle.unref(); + } + + _super.prototype.destroy.call(this); + }; + + __proto._getOffset = function (properties, useDirection) { + if (this._useRotation === false) { + return _super.prototype._getOffset.call(this, properties, useDirection); + } + + var offset = _super.prototype._getOffset.call(this, properties, [true, true]); + + var newOffset = [0, 0]; + + var theta = this._screenRotationAngle.getRadian(); + + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); // RotateZ + + newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta; + newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta; // Use only user allowed direction. + + if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) { + newOffset[0] = 0; + } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) { + newOffset[1] = 0; + } + + return newOffset; + }; + + return RotationPanInput; + }(PanInput); + /** + * Override getDirectionByAngle to return DIRECTION_ALL + * Ref: https://github.com/naver/egjs-axes/issues/99 + * + * But we obey axes's rule. If axes's rule is problem, let's apply following code. + */ + // PanInput.getDirectionByAngle = function (angle, thresholdAngle) { + // return DIRECTION_ALL; + // }; + + var Y_AXIS_VECTOR = fromValues(0, 1, 0); + + var DeviceQuaternion = + /*#__PURE__*/ + function (_super) { + __extends(DeviceQuaternion, _super); + + function DeviceQuaternion() { + var _this = _super.call(this) || this; + + _this._fusionPoseSensor = new FusionPoseSensor(); + _this._quaternion = create$4(); + + _this._fusionPoseSensor.enable(); + + _this._fusionPoseSensor.on("change", function (e) { + _this._quaternion = e.quaternion; + + _this.trigger(new ComponentEvent$1("change", { + isTrusted: true + })); + }); + + return _this; + } + + var __proto = DeviceQuaternion.prototype; + + __proto.getCombinedQuaternion = function (yaw) { + var yawQ = setAxisAngle(create$4(), Y_AXIS_VECTOR, toRadian(-yaw)); + var conj = conjugate(create$4(), this._quaternion); // Multiply pitch quaternion -> device quaternion -> yaw quaternion + + var outQ = multiply(create$4(), conj, yawQ); + return outQ; + }; + + __proto.destroy = function () { + // detach all event handler + this.off(); + + if (this._fusionPoseSensor) { + this._fusionPoseSensor.off(); + + this._fusionPoseSensor.destroy(); + + this._fusionPoseSensor = null; + } + }; + + return DeviceQuaternion; + }(Component); + + var DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF]; + var DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF]; + var CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF]; + /** + * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates. + * @alias eg.YawPitchControl + * @extends eg.Component + * + * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + */ + + var YawPitchControl = + /*#__PURE__*/ + function (_super) { + __extends(YawPitchControl, _super); + /** + * @param {object} options The option object of the eg.YawPitch module + * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module + * @param {number} [options.yaw=0] initial yaw (degree) + * @param {number} [options.pitch=0] initial pitch (degree) + * @param {number} [options.fov=65] initial field of view (degree) + * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown + * @param {boolean} [options.useZoom=true] Indicates whether zoom is available + * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled + * @param {string} [config.gyroMode=yawPitch] Enables control through device motion. + * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move) + * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw + * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch + * @param {number[]} [options.fovRange=[30, 110] Range of FOV + * @param {number} [options.aspectRatio=1] Aspect Ratio + */ + + + function YawPitchControl(options) { + var _this = _super.call(this) || this; + + _this.options = {}; + + var opt = __assign({ + element: null, + yaw: 0, + pitch: 0, + fov: 65, + showPolePoint: false, + useZoom: true, + useKeyboard: true, + gyroMode: GYRO_MODE.YAWPITCH, + touchDirection: TOUCH_DIRECTION_ALL, + yawRange: DEFAULT_YAW_RANGE, + pitchRange: DEFAULT_PITCH_RANGE, + fovRange: [30, 110], + aspectRatio: 1 + /* TODO: Need Mandatory? */ + + }, options); + + _this._element = opt.element; + _this._initialFov = opt.fov; + _this._enabled = false; + _this._isAnimating = false; + _this._deviceQuaternion = null; + + _this._initAxes(opt); + + _this.option(opt); + + return _this; + } + /** + * Update Pan Scale + * + * Scale(Sensitivity) values of panning is related with fov and height. + * If at least one of them is changed, this function need to be called. + * @param {*} param + */ + + + var __proto = YawPitchControl.prototype; + + __proto.updatePanScale = function (param) { + if (param === void 0) { + param = {}; + } + + var fov = this._axes.get().fov; + + var areaHeight = param.height || parseInt(window.getComputedStyle(this._element).height, 10); + var scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight; + this._axesPanInput.options.scale = [scale, scale]; + this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW; + return this; + }; + /* + * Override component's option method + * to call method for updating values which is affected by option change. + * + * @param {*} args + */ + + + __proto.option = function (key, newValue) { + // Getter + if (!key) { + return this._getOptions(); + } else if (key && typeof key === "string" && typeof newValue === "undefined") { + return this._getOptions(key); + } // Setter + + + var newOptions = {}; + var changedKeyList = []; // TODO: if value is not changed, then do not push on changedKeyList. + + if (typeof key === "string") { + changedKeyList.push(key); + newOptions[key] = newValue; + } else { + var options = key; // Retrieving object here + + changedKeyList = Object.keys(options); + newOptions = __assign({}, options); + } + + this._setOptions(this._getValidatedOptions(newOptions)); + + this._applyOptions(changedKeyList); + + return this; + }; + /** + * Enable YawPitch functionality + * @method eg.YawPitch#enable + */ + + + __proto.enable = function () { + if (this._enabled) { + return this; + } + + this._enabled = true; // touchDirection is decided by parameter is valid string (Ref. Axes.connect) + + this._applyOptions(Object.keys(this.options)); // TODO: Is this code is needed? Check later. + + + this.updatePanScale(); + return this; + }; + /** + * Disable YawPitch functionality + * @method eg.YawPitch#disable + */ + + + __proto.disable = function (persistOrientation) { + if (persistOrientation === void 0) { + persistOrientation = false; + } + + if (!this._enabled) { + return this; + } // TODO: Check peristOrientation is needed! + + + if (!persistOrientation) { + this._resetOrientation(); + } + + this._axes.disconnect(); + + this._enabled = false; + return this; + }; + /** + * Set one or more of yaw, pitch, fov + * @param {Object} coordinate yaw, pitch, fov + * @param {Number} duration Animation duration. if it is above 0 then it's animated. + */ + + + __proto.lookAt = function (_a, duration) { + var yaw = _a.yaw, + pitch = _a.pitch, + fov = _a.fov; + + var pos = this._axes.get(); + + var y = yaw === undefined ? 0 : yaw - pos.yaw; + var p = pitch === undefined ? 0 : pitch - pos.pitch; + var f = fov === undefined ? 0 : fov - pos.fov; // Allow duration of animation to have more than MC_MAXIMUM_DURATION. + + this._axes.options.maximumDuration = Infinity; + + this._axes.setBy({ + yaw: y, + pitch: p, + fov: f + }, duration); + }; + + __proto.getYawPitch = function () { + var yawPitch = this._axes.get(); + + return { + yaw: yawPitch.yaw, + pitch: yawPitch.pitch + }; + }; + + __proto.getFov = function () { + return this._axes.get().fov; + }; + + __proto.getQuaternion = function () { + var pos = this._axes.get(); + + return this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + }; + + __proto.shouldRenderWithQuaternion = function () { + return this.options.gyroMode === GYRO_MODE.VR; + }; + /** + * Destroys objects + */ + + + __proto.destroy = function () { + /* eslint-disable @typescript-eslint/no-unused-expressions */ + this._axes && this._axes.destroy(); + this._axesPanInput && this._axesPanInput.destroy(); + this._axesWheelInput && this._axesWheelInput.destroy(); + this._axesTiltMotionInput && this._axesTiltMotionInput.destroy(); + this._axesPinchInput && this._axesPinchInput.destroy(); + this._axesMoveKeyInput && this._axesMoveKeyInput.destroy(); + this._deviceQuaternion && this._deviceQuaternion.destroy(); + /* eslint-enable @typescript-eslint/no-unused-expressions */ + }; + + __proto._initAxes = function (opt) { + var _this = this; + + var yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio); + + var pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint); + + var useRotation = opt.gyroMode === GYRO_MODE.VR; + this._axesPanInput = new RotationPanInput(this._element, { + useRotation: useRotation + }); + this._axesWheelInput = new WheelInput(this._element, { + scale: -4 + }); + this._axesTiltMotionInput = null; + this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, { + scale: -1 + }) : null; + this._axesMoveKeyInput = new MoveKeyInput(this._element, { + scale: [-6, 6] + }); + this._axes = new Axes({ + yaw: { + range: yRange, + circular: this._isCircular(yRange), + bounce: [0, 0] + }, + pitch: { + range: pRange, + circular: this._isCircular(pRange), + bounce: [0, 0] + }, + fov: { + range: opt.fovRange, + circular: [false, false], + bounce: [0, 0] + } + }, { + deceleration: MC_DECELERATION, + maximumDuration: MC_MAXIMUM_DURATION + }, { + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }).on({ + // TODO: change event type after Axes event type inference update + hold: function (evt) { + // Restore maximumDuration not to be spin too mush. + _this._axes.options.maximumDuration = MC_MAXIMUM_DURATION; + + _this.trigger(new ComponentEvent$1("hold", { + isTrusted: evt.isTrusted + })); + }, + change: function (evt) { + if (evt.delta.fov !== 0) { + _this._updateControlScale(evt); + + _this.updatePanScale(); + } + + _this._triggerChange(evt); + }, + release: function (evt) { + _this._triggerChange(evt); + }, + animationEnd: function (evt) { + _this.trigger(new ComponentEvent$1("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + }; + + __proto._getValidatedOptions = function (newOptions) { + if (newOptions.yawRange) { + newOptions.yawRange = this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio); + } + + if (newOptions.pitchRange) { + newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov); + } + + return newOptions; + }; + + __proto._getOptions = function (key) { + var value; + + if (typeof key === "string") { + value = this.options[key]; + } else if (arguments.length === 0) { + value = this.options; + } + + return value; + }; + + __proto._setOptions = function (options) { + for (var key in options) { + this.options[key] = options[key]; + } + }; + + __proto._applyOptions = function (keys) { + var options = this.options; + var axes = this._axes; + var isVR = options.gyroMode === GYRO_MODE.VR; + var isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH; // If it's VR mode, restrict user interaction to yaw direction only + + var touchDirection = isVR ? TOUCH_DIRECTION_YAW & options.touchDirection : options.touchDirection; // If one of below is changed, call updateControlScale() + + if (keys.some(function (key) { + return key === "showPolePoint" || key === "fov" || key === "aspectRatio" || key === "yawRange" || key === "pitchRange"; + })) { + // If fov is changed, update pan scale + if (keys.indexOf("fov") >= 0) { + axes.setTo({ + "fov": options.fov + }); + this.updatePanScale(); + } + + this._updateControlScale(); + } + + if (keys.some(function (key) { + return key === "fovRange"; + })) { + var fovRange = options.fovRange; + var prevFov = axes.get().fov; + var nextFov = axes.get().fov; + copy$3(axes.axis.fov.range, fovRange); + + if (nextFov < fovRange[0]) { + nextFov = fovRange[0]; + } else if (prevFov > fovRange[1]) { + nextFov = fovRange[1]; + } + + if (prevFov !== nextFov) { + axes.setTo({ + fov: nextFov + }, 0); + + this._updateControlScale(); + + this.updatePanScale(); + } + } + + if (keys.some(function (key) { + return key === "gyroMode"; + }) && SUPPORT_DEVICEMOTION) { + // Disconnect first + if (this._axesTiltMotionInput) { + this._axes.disconnect(this._axesTiltMotionInput); + + this._axesTiltMotionInput.destroy(); + + this._axesTiltMotionInput = null; + } + + if (this._deviceQuaternion) { + this._deviceQuaternion.destroy(); + + this._deviceQuaternion = null; + } + + if (isVR) { + this._initDeviceQuaternion(); + } else if (isYawPitch) { + this._axesTiltMotionInput = new TiltMotionInput(this._element); + + this._axes.connect(["yaw", "pitch"], this._axesTiltMotionInput); + } + + this._axesPanInput.setUseRotation(isVR); + } + + if (keys.some(function (key) { + return key === "useKeyboard"; + })) { + var useKeyboard = options.useKeyboard; + + if (useKeyboard) { + axes.connect(["yaw", "pitch"], this._axesMoveKeyInput); + } else { + axes.disconnect(this._axesMoveKeyInput); + } + } + + if (keys.some(function (key) { + return key === "useZoom"; + })) { + var useZoom = options.useZoom; // Disconnect first + + axes.disconnect(this._axesWheelInput); + + if (useZoom) { + axes.connect(["fov"], this._axesWheelInput); + } + } + + this._togglePinchInputByOption(options.touchDirection, options.useZoom); + + if (keys.some(function (key) { + return key === "touchDirection"; + }) && this._enabled) { + this._enableTouch(touchDirection); + } + }; + + __proto._togglePinchInputByOption = function (touchDirection, useZoom) { + if (this._axesPinchInput) { + // disconnect first + this._axes.disconnect(this._axesPinchInput); // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll. + + + if (useZoom && touchDirection === TOUCH_DIRECTION_ALL && // TODO: Get rid of using private property of axes instance. + this._axes._inputs.indexOf(this._axesPinchInput) === -1) { + this._axes.connect(["fov"], this._axesPinchInput); + } + } + }; + + __proto._enableTouch = function (direction) { + // Disconnect first + if (this._axesPanInput) { + this._axes.disconnect(this._axesPanInput); + } + + var yawEnabled = direction & TOUCH_DIRECTION_YAW ? "yaw" : null; + var pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? "pitch" : null; + + this._axes.connect([yawEnabled, pitchEnabled], this._axesPanInput); + }; + + __proto._initDeviceQuaternion = function () { + var _this = this; + + this._deviceQuaternion = new DeviceQuaternion(); + + this._deviceQuaternion.on("change", function (e) { + _this._triggerChange(e); + }); + }; + + __proto._getValidYawRange = function (newYawRange, newFov, newAspectRatio) { + var ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1); + + var fov = newFov || this._axes.get().fov; + + var horizontalFov = fov * ratio; + var isValid = newYawRange[1] - newYawRange[0] >= horizontalFov; + + if (isValid) { + return newYawRange; + } else { + return this.options.yawRange || DEFAULT_YAW_RANGE; + } + }; + + __proto._getValidPitchRange = function (newPitchRange, newFov) { + var fov = newFov || this._axes.get().fov; + + var isValid = newPitchRange[1] - newPitchRange[0] >= fov; + + if (isValid) { + return newPitchRange; + } else { + return this.options.pitchRange || DEFAULT_PITCH_RANGE; + } + }; + + __proto._isCircular = function (range) { + return range[1] - range[0] < 360 ? [false, false] : [true, true]; + }; + /** + * Update yaw/pitch min/max by 5 factor + * + * 1. showPolePoint + * 2. fov + * 3. yawRange + * 4. pitchRange + * 5. aspectRatio + * + * If one of above is changed, call this function + */ + + + __proto._updateControlScale = function (changeEvt) { + var opt = this.options; + + var fov = this._axes.get().fov; + + var pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint); + + var yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio); // TODO: If not changed!? + + + var pos = this._axes.get(); + + var y = pos.yaw; + var p = pos.pitch; + copy$3(this._axes.axis.yaw.range, yRange); + copy$3(this._axes.axis.pitch.range, pRange); + this._axes.axis.yaw.circular = this._isCircular(yRange); + this._axes.axis.pitch.circular = this._isCircular(pRange); + /** + * update yaw/pitch by it's range. + */ + + if (y < yRange[0]) { + y = yRange[0]; + } else if (y > yRange[1]) { + y = yRange[1]; + } + + if (p < pRange[0]) { + p = pRange[0]; + } else if (p > pRange[1]) { + p = pRange[1]; + } + + if (changeEvt) { + changeEvt.set({ + yaw: y, + pitch: p + }); + } + + this._axes.setTo({ + yaw: y, + pitch: p + }, 0); + + return this; + }; + + __proto._updatePitchRange = function (pitchRange, fov, showPolePoint) { + if (this.options.gyroMode === GYRO_MODE.VR) { + // Circular pitch on VR + return CIRCULAR_PITCH_RANGE; + } + + var verticalAngle = pitchRange[1] - pitchRange[0]; + var halfFov = fov / 2; + var isPanorama = verticalAngle < 180; + + if (showPolePoint && !isPanorama) { + // Use full pinch range + return pitchRange.concat(); + } // Round value as movableCood do. + + + return [pitchRange[0] + halfFov, pitchRange[1] - halfFov]; + }; + + __proto._updateYawRange = function (yawRange, fov, aspectRatio) { + if (this.options.gyroMode === GYRO_MODE.VR) { + return DEFAULT_YAW_RANGE; + } + + var horizontalAngle = yawRange[1] - yawRange[0]; + /** + * Full 360 Mode + */ + + if (horizontalAngle >= 360) { + // Don't limit yaw range on Full 360 mode. + return yawRange.concat(); + } + /** + * Panorama mode + */ + // Ref : https://github.com/naver/egjs-view360/issues/290 + + + var halfHorizontalFov = util.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(toRadian(fov / 2)))); // Round value as movableCood do. + + return [yawRange[0] + halfHorizontalFov, yawRange[1] - halfHorizontalFov]; + }; // TODO: update param type after Axes event type inference update + + + __proto._triggerChange = function (evt) { + var pos = this._axes.get(); + + var opt = this.options; + var event = { + targetElement: opt.element, + isTrusted: evt.isTrusted, + yaw: pos.yaw, + pitch: pos.pitch, + fov: pos.fov, + quaternion: null + }; + + if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) { + event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + } + + this.trigger(new ComponentEvent$1("change", event)); + }; // TODO: makes constant to be logic + + + __proto._adjustAspectRatio = function (input) { + var inputRange = [0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670, 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19, 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26, 2.30, 2.60, 3.00, 5.00, 6.00]; + var outputRange = [0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710, 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15, 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72, 1.82, 1.92, 2.00, 2.24, 2.30]; + var rangeIdx = -1; + + for (var i = 0; i < inputRange.length - 1; i++) { + if (inputRange[i] <= input && inputRange[i + 1] >= input) { + rangeIdx = i; + break; + } + } + + if (rangeIdx === -1) { + if (inputRange[0] > input) { + return outputRange[0]; + } else { + // FIXME: this looks definitely wrong + return outputRange[outputRange[0].length - 1]; + } + } + + var inputA = inputRange[rangeIdx]; + var inputB = inputRange[rangeIdx + 1]; + var outputA = outputRange[rangeIdx]; + var outputB = outputRange[rangeIdx + 1]; + return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA)); + }; + + __proto._lerp = function (a, b, fraction) { + return a + fraction * (b - a); + }; + + __proto._resetOrientation = function () { + var opt = this.options; + + this._axes.setTo({ + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }, 0); + + return this; + }; + + YawPitchControl.VERSION = VERSION; // Expose DeviceOrientationControls sub module for test purpose + + YawPitchControl.CONTROL_MODE_VR = CONTROL_MODE_VR; + YawPitchControl.CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH; + YawPitchControl.TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL; + YawPitchControl.TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW; + YawPitchControl.TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH; + YawPitchControl.TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE; + return YawPitchControl; + }(Component); + + /* + Copyright (c) NAVER Corp. + name: @egjs/component + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-component + version: 2.2.2 + */ + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __values$2(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + function isUndefined$1(value) { + return typeof value === "undefined"; + } + /** + * A class used to manage events in a component + * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스 + * @alias eg.Component + */ + + + var Component$1 = + /*#__PURE__*/ + function () { + /** + * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"} + */ + function Component() { + /** + * @deprecated + * @private + */ + this.options = {}; + this._eventHandler = {}; + } + /** + * Triggers a custom event. + * @ko 커스텀 이벤트를 발생시킨다 + * @param {string} eventName The name of the custom event to be triggered 발생할 커스텀 이벤트의 이름 + * @param {object} customEvent Event data to be sent when triggering a custom event 커스텀 이벤트가 발생할 때 전달할 데이터 + * @param {any[]} restParam Additional parameters when triggering a custom event 커스텀 이벤트가 발생할 때 필요시 추가적으로 전달할 데이터 + * @return Indicates whether the event has occurred. If the stop() method is called by a custom event handler, it will return false and prevent the event from occurring. Ref 이벤트 발생 여부. 커스텀 이벤트 핸들러에서 stop() 메서드를 호출하면 'false'를 반환하고 이벤트 발생을 중단한다. 참고 + * @example + * ``` + * class Some extends eg.Component { + * some(){ + * if(this.trigger("beforeHi")){ // When event call to stop return false. + * this.trigger("hi");// fire hi event. + * } + * } + * } + * + * const some = new Some(); + * some.on("beforeHi", (e) => { + * if(condition){ + * e.stop(); // When event call to stop, `hi` event not call. + * } + * }); + * some.on("hi", (e) => { + * // `currentTarget` is component instance. + * console.log(some === e.currentTarget); // true + * }); + * // If you want to more know event design. You can see article. + * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F + * ``` + */ + + + var __proto = Component.prototype; + + __proto.trigger = function (eventName) { + var _this = this; + + var params = []; + + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + + var handlerList = this._eventHandler[eventName] || []; + var hasHandlerList = handlerList.length > 0; + + if (!hasHandlerList) { + return true; + } + + var customEvent = params[0] || {}; + var restParams = params.slice(1); // If detach method call in handler in first time then handler list calls. + + handlerList = handlerList.concat(); + var isCanceled = false; // This should be done like this to pass previous tests + + customEvent.eventType = eventName; + + customEvent.stop = function () { + isCanceled = true; + }; + + customEvent.currentTarget = this; + var arg = [customEvent]; + + if (restParams.length >= 1) { + arg = arg.concat(restParams); + } + + handlerList.forEach(function (handler) { + handler.apply(_this, arg); + }); + return !isCanceled; + }; + /** + * Executed event just one time. + * @ko 이벤트가 한번만 실행된다. + * @param {string} eventName The name of the event to be attached 등록할 이벤트의 이름 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ``` + * class Some extends eg.Component { + * hi() { + * alert("hi"); + * } + * thing() { + * this.once("hi", this.hi); + * } + * + * var some = new Some(); + * some.thing(); + * some.trigger("hi"); + * // fire alert("hi"); + * some.trigger("hi"); + * // Nothing happens + * ``` + */ + + + __proto.once = function (eventName, handlerToAttach) { + var _this = this; + + if (typeof eventName === "object" && isUndefined$1(handlerToAttach)) { + var eventHash = eventName; + + for (var key in eventHash) { + this.once(key, eventHash[key]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var listener_1 = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + handlerToAttach.apply(_this, args); + + _this.off(eventName, listener_1); + }; + + this.on(eventName, listener_1); + } + + return this; + }; + /** + * Checks whether an event has been attached to a component. + * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다. + * @param {string} eventName The name of the event to be attached 등록 여부를 확인할 이벤트의 이름 + * @return {boolean} Indicates whether the event is attached. 이벤트 등록 여부 + * @example + * ``` + * class Some extends eg.Component { + * some() { + * this.hasOn("hi");// check hi event. + * } + * } + * ``` + */ + + + __proto.hasOn = function (eventName) { + return !!this._eventHandler[eventName]; + }; + /** + * Attaches an event to a component. + * @ko 컴포넌트에 이벤트를 등록한다. + * @param {string} eventName The name of the event to be attached 등록할 이벤트의 이름 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ``` + * class Some extends eg.Component { + * hi() { + * console.log("hi"); + * } + * some() { + * this.on("hi",this.hi); //attach event + * } + * } + * ``` + */ + + + __proto.on = function (eventName, handlerToAttach) { + if (typeof eventName === "object" && isUndefined$1(handlerToAttach)) { + var eventHash = eventName; + + for (var name in eventHash) { + this.on(name, eventHash[name]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var handlerList = this._eventHandler[eventName]; + + if (isUndefined$1(handlerList)) { + this._eventHandler[eventName] = []; + handlerList = this._eventHandler[eventName]; + } + + handlerList.push(handlerToAttach); + } + + return this; + }; + /** + * Detaches an event from the component. + * @ko 컴포넌트에 등록된 이벤트를 해제한다 + * @param {string} eventName The name of the event to be detached 해제할 이벤트의 이름 + * @param {function} handlerToDetach The handler function of the event to be detached 해제할 이벤트의 핸들러 함수 + * @return An instance of a component itself 컴포넌트 자신의 인스턴스 + * @example + * ``` + * class Some extends eg.Component { + * hi() { + * console.log("hi"); + * } + * some() { + * this.off("hi",this.hi); //detach event + * } + * } + * ``` + */ + + + __proto.off = function (eventName, handlerToDetach) { + var e_1, _a; // Detach all event handlers. + + + if (isUndefined$1(eventName)) { + this._eventHandler = {}; + return this; + } // Detach all handlers for eventname or detach event handlers by object. + + + if (isUndefined$1(handlerToDetach)) { + if (typeof eventName === "string") { + delete this._eventHandler[eventName]; + return this; + } else { + var eventHash = eventName; + + for (var name in eventHash) { + this.off(name, eventHash[name]); + } + + return this; + } + } // Detach single event handler + + + var handlerList = this._eventHandler[eventName]; + + if (handlerList) { + var idx = 0; + + try { + for (var handlerList_1 = __values$2(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) { + var handlerFunction = handlerList_1_1.value; + + if (handlerFunction === handlerToDetach) { + handlerList.splice(idx, 1); + break; + } + + idx++; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1); + } finally { + if (e_1) throw e_1.error; + } + } + } + + return this; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @example + * eg.Component.VERSION; // ex) 2.0.0 + * @memberof eg.Component + */ + + + Component.VERSION = "2.2.2"; + return Component; + }(); + + /* + Copyright (c) 2020-present NAVER Corp. + name: @egjs/imready + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-imready + version: 1.1.2 + */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics$2 = function (d, b) { + extendStatics$2 = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + }; + + return extendStatics$2(d, b); + }; + + function __extends$2(d, b) { + extendStatics$2(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign$2 = function () { + __assign$2 = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign$2.apply(this, arguments); + }; + function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + + for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; + + return r; + } + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + var isWindow = typeof window !== "undefined"; + var ua = isWindow ? window.navigator.userAgent : ""; + var SUPPORT_COMPUTEDSTYLE = isWindow ? !!("getComputedStyle" in window) : false; + var IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua); + var SUPPORT_ADDEVENTLISTENER = isWindow ? !!("addEventListener" in document) : false; + var WIDTH = "width"; + var HEIGHT = "height"; + + function getAttribute(el, name) { + return el.getAttribute(name) || ""; + } + function toArray$1(arr) { + return [].slice.call(arr); + } + function hasSizeAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return !!target.getAttribute(prefix + "width"); + } + function hasLoadingAttribute(target) { + return "loading" in target && target.getAttribute("loading") === "lazy"; + } + function hasSkipAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return !!target.getAttribute(prefix + "skip"); + } + function addEvent(element, type, handler) { + if (SUPPORT_ADDEVENTLISTENER) { + element.addEventListener(type, handler, false); + } else if (element.attachEvent) { + element.attachEvent("on" + type, handler); + } else { + element["on" + type] = handler; + } + } + function removeEvent(element, type, handler) { + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else if (element.detachEvent) { + element.detachEvent("on" + type, handler); + } else { + element["on" + type] = null; + } + } + function innerWidth(el) { + return getSize(el, "Width"); + } + function innerHeight(el) { + return getSize(el, "Height"); + } + function getStyles(el) { + return (SUPPORT_COMPUTEDSTYLE ? window.getComputedStyle(el) : el.currentStyle) || {}; + } + + function getSize(el, name) { + var size = el["client" + name] || el["offset" + name]; + return parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0; + } + + function getContentElements(element, tags, prefix) { + var skipElements = toArray$1(element.querySelectorAll(__spreadArrays(["[" + prefix + "skip] [" + prefix + "width]"], tags.map(function (tag) { + return ["[" + prefix + "skip] " + tag, tag + "[" + prefix + "skip]", "[" + prefix + "width] " + tag].join(", "); + })).join(", "))); + return toArray$1(element.querySelectorAll("[" + prefix + "width], " + tags.join(", "))).filter(function (el) { + return skipElements.indexOf(el) === -1; + }); + } + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + var elements = []; + function addAutoSizer(element, prefix) { + !elements.length && addEvent(window, "resize", resizeAllAutoSizers); + element.__PREFIX__ = prefix; + elements.push(element); + resize(element); + } + function removeAutoSizer(element, prefix) { + var index = elements.indexOf(element); + + if (index < 0) { + return; + } + + var fixed = getAttribute(element, prefix + "fixed"); + delete element.__PREFIX__; + element.style[fixed === HEIGHT ? WIDTH : HEIGHT] = ""; + elements.splice(index, 1); + !elements.length && removeEvent(window, "resize", resizeAllAutoSizers); + } + + function resize(element, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + var elementPrefix = element.__PREFIX__ || prefix; + var dataWidth = parseInt(getAttribute(element, "" + elementPrefix + WIDTH), 10) || 0; + var dataHeight = parseInt(getAttribute(element, "" + elementPrefix + HEIGHT), 10) || 0; + var fixed = getAttribute(element, elementPrefix + "fixed"); + + if (fixed === HEIGHT) { + var size = innerHeight(element) || dataHeight; + element.style[WIDTH] = dataWidth / dataHeight * size + "px"; + } else { + var size = innerWidth(element) || dataWidth; + element.style[HEIGHT] = dataHeight / dataWidth * size + "px"; + } + } + + function resizeAllAutoSizers() { + elements.forEach(function (element) { + resize(element); + }); + } + + var Loader = + /*#__PURE__*/ + function (_super) { + __extends$2(Loader, _super); + + function Loader(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.isReady = false; + _this.isPreReady = false; + _this.hasDataSize = false; + _this.hasLoading = false; + _this.isSkip = false; + + _this.onCheck = function (e) { + _this.clear(); + + if (e && e.type === "error") { + _this.onError(_this.element); + } // I'm pre-ready and ready! + + + var withPreReady = !_this.hasDataSize && !_this.hasLoading; + + _this.onReady(withPreReady); + }; + + _this.options = __assign$2({ + prefix: "data-" + }, options); + _this.element = element; + _this.hasDataSize = hasSizeAttribute(element, _this.options.prefix); + _this.hasLoading = hasLoadingAttribute(element); + _this.isSkip = hasSkipAttribute(_this.element); + return _this; + } + + var __proto = Loader.prototype; + + __proto.check = function () { + if (this.isSkip || !this.checkElement()) { + // I'm Ready + this.onAlreadyReady(true); + return false; + } + + if (this.hasDataSize) { + addAutoSizer(this.element, this.options.prefix); + } + + if (this.hasDataSize || this.hasLoading) { + // I'm Pre Ready + this.onAlreadyPreReady(); + } // Wati Pre Ready, Ready + + + return true; + }; + + __proto.addEvents = function () { + var _this = this; + + var element = this.element; + this.constructor.EVENTS.forEach(function (name) { + addEvent(element, name, _this.onCheck); + }); + }; + + __proto.clear = function () { + var _this = this; + + var element = this.element; + this.constructor.EVENTS.forEach(function (name) { + removeEvent(element, name, _this.onCheck); + }); + this.removeAutoSizer(); + }; + + __proto.destroy = function () { + this.clear(); + this.off(); + }; + + __proto.removeAutoSizer = function () { + if (this.hasDataSize) { + // I'm already ready. + var prefix = this.options.prefix; + removeAutoSizer(this.element, prefix); + } + }; + + __proto.onError = function (target) { + this.trigger("error", { + element: this.element, + target: target + }); + }; + + __proto.onPreReady = function () { + if (this.isPreReady) { + return; + } + + this.isPreReady = true; + this.trigger("preReady", { + element: this.element, + hasLoading: this.hasLoading, + isSkip: this.isSkip + }); + }; + + __proto.onReady = function (withPreReady) { + if (this.isReady) { + return; + } + + if (withPreReady) { + this.isPreReady = true; + } + + this.removeAutoSizer(); + this.isReady = true; + this.trigger("ready", { + element: this.element, + withPreReady: withPreReady, + hasLoading: this.hasLoading, + isSkip: this.isSkip + }); + }; + + __proto.onAlreadyError = function (target) { + var _this = this; + + setTimeout(function () { + _this.onError(target); + }); + }; + + __proto.onAlreadyPreReady = function () { + var _this = this; + + setTimeout(function () { + _this.onPreReady(); + }); + }; + + __proto.onAlreadyReady = function (withPreReady) { + var _this = this; + + setTimeout(function () { + _this.onReady(withPreReady); + }); + }; + + Loader.EVENTS = []; + return Loader; + }(Component$1); + + var ElementLoader = + /*#__PURE__*/ + function (_super) { + __extends$2(ElementLoader, _super); + + function ElementLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = ElementLoader.prototype; + + __proto.setHasLoading = function (hasLoading) { + this.hasLoading = hasLoading; + }; + + __proto.check = function () { + if (this.isSkip) { + // I'm Ready + this.onAlreadyReady(true); + return false; + } + + if (this.hasDataSize) { + addAutoSizer(this.element, this.options.prefix); + this.onAlreadyPreReady(); + } else { + // has not data size + this.trigger("requestChildren"); + } + + return true; + }; + + __proto.checkElement = function () { + return true; + }; + + __proto.destroy = function () { + this.clear(); + this.trigger("requestDestroy"); + this.off(); + }; + + __proto.onAlreadyPreReady = function () { + // has data size + _super.prototype.onAlreadyPreReady.call(this); + + this.trigger("reqeustReadyChildren"); + }; + + ElementLoader.EVENTS = []; + return ElementLoader; + }(Loader); + + /** + * @alias eg.ImReady + * @extends eg.Component + */ + + var ImReadyManager = + /*#__PURE__*/ + function (_super) { + __extends$2(ImReadyManager, _super); + /** + * @param - ImReady's options + */ + + + function ImReadyManager(options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.readyCount = 0; + _this.preReadyCount = 0; + _this.totalCount = 0; + _this.totalErrorCount = 0; + _this.isPreReadyOver = true; + _this.elementInfos = []; + _this.options = __assign$2({ + loaders: {}, + prefix: "data-" + }, options); + return _this; + } + /** + * Checks whether elements are in the ready state. + * @ko 엘리먼트가 준비 상태인지 체크한다. + * @elements - Elements to check ready status. 준비 상태를 체크할 엘리먼트들. + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReadyElement: e => { + * // 1, 3 + * // 2, 3 + * // 3, 3 + * console.log(e.preReadyCount, e.totalCount), + * }, + * }); + * ``` + */ + + + var __proto = ImReadyManager.prototype; + + __proto.check = function (elements) { + var _this = this; + + var prefix = this.options.prefix; + this.clear(); + this.elementInfos = toArray$1(elements).map(function (element, index) { + var loader = _this.getLoader(element, { + prefix: prefix + }); + + loader.check(); + loader.on("error", function (e) { + _this.onError(index, e.target); + }).on("preReady", function (e) { + var info = _this.elementInfos[index]; + info.hasLoading = e.hasLoading; + info.isSkip = e.isSkip; + + var isPreReady = _this.checkPreReady(index); + + _this.onPreReadyElement(index); + + isPreReady && _this.onPreReady(); + }).on("ready", function (_a) { + var withPreReady = _a.withPreReady, + hasLoading = _a.hasLoading, + isSkip = _a.isSkip; + var info = _this.elementInfos[index]; + info.hasLoading = hasLoading; + info.isSkip = isSkip; + + var isPreReady = withPreReady && _this.checkPreReady(index); + + var isReady = _this.checkReady(index); // Pre-ready and ready occur simultaneously + + + withPreReady && _this.onPreReadyElement(index); + + _this.onReadyElement(index); + + isPreReady && _this.onPreReady(); + isReady && _this.onReady(); + }); + return { + loader: loader, + element: element, + hasLoading: false, + hasError: false, + isPreReady: false, + isReady: false, + isSkip: false + }; + }); + var length = this.elementInfos.length; + this.totalCount = length; + + if (!length) { + setTimeout(function () { + _this.onPreReady(); + + _this.onReady(); + }); + } + + return this; + }; + /** + * Gets the total count of elements to be checked. + * @ko 체크하는 element의 총 개수를 가져온다. + */ + + + __proto.getTotalCount = function () { + return this.totalCount; + }; + /** + * Whether the elements are all pre-ready. (all sizes are known) + * @ko 엘리먼트들이 모두 사전 준비가 됐는지 (사이즈를 전부 알 수 있는지) 여부. + */ + + + __proto.isPreReady = function () { + return this.elementInfos.every(function (info) { + return info.isPreReady; + }); + }; + /** + * Whether the elements are all ready. + * @ko 엘리먼트들이 모두 준비가 됐는지 여부. + */ + + + __proto.isReady = function () { + return this.elementInfos.every(function (info) { + return info.isReady; + }); + }; + /** + * Whether an error has occurred in the elements in the current state. + * @ko 현재 상태에서 엘리먼트들이 에러가 발생했는지 여부. + */ + + + __proto.hasError = function () { + return this.totalErrorCount > 0; + }; + /** + * Clears events of elements being checked. + * @ko 체크 중인 엘리먼트들의 이벤트를 해제 한다. + */ + + + __proto.clear = function () { + this.isPreReadyOver = false; + this.totalCount = 0; + this.preReadyCount = 0; + this.readyCount = 0; + this.totalErrorCount = 0; + this.elementInfos.forEach(function (info) { + if (!info.isReady && info.loader) { + info.loader.destroy(); + } + }); + this.elementInfos = []; + }; + /** + * Destory all events. + * @ko 모든 이벤트를 해제 한다. + */ + + + __proto.destroy = function () { + this.clear(); + this.off(); + }; + + __proto.getLoader = function (element, options) { + var _this = this; + + var tagName = element.tagName.toLowerCase(); + var loaders = this.options.loaders; + var tags = Object.keys(loaders); + + if (loaders[tagName]) { + return new loaders[tagName](element, options); + } + + var loader = new ElementLoader(element, options); + var children = toArray$1(element.querySelectorAll(tags.join(", "))); + loader.setHasLoading(children.some(function (el) { + return hasLoadingAttribute(el); + })); + var withPreReady = false; + var childrenImReady = this.clone().on("error", function (e) { + loader.onError(e.target); + }).on("ready", function () { + loader.onReady(withPreReady); + }); + loader.on("requestChildren", function () { + // has not data size + var contentElements = getContentElements(element, tags, _this.options.prefix); + childrenImReady.check(contentElements).on("preReady", function (e) { + withPreReady = e.isReady; + + if (!withPreReady) { + loader.onPreReady(); + } + }); + }).on("reqeustReadyChildren", function () { + // has data size + // loader call preReady + // check only video, image elements + childrenImReady.check(children); + }).on("requestDestroy", function () { + childrenImReady.destroy(); + }); + return loader; + }; + + __proto.clone = function () { + return new ImReadyManager(__assign$2({}, this.options)); + }; + + __proto.checkPreReady = function (index) { + this.elementInfos[index].isPreReady = true; + ++this.preReadyCount; + + if (this.preReadyCount < this.totalCount) { + return false; + } + + return true; + }; + + __proto.checkReady = function (index) { + this.elementInfos[index].isReady = true; + ++this.readyCount; + + if (this.readyCount < this.totalCount) { + return false; + } + + return true; + }; + + __proto.onError = function (index, target) { + var info = this.elementInfos[index]; + info.hasError = true; + /** + * An event occurs if the image, video fails to load. + * @ko 이미지, 비디오가 로딩에 실패하면 이벤트가 발생한다. + * @event eg.ImReady#error + * @param {eg.ImReady.OnError} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {HTMLElement} [e.element] - The element with error images.오류난 이미지가 있는 엘리먼트 + * @param {number} [e.index] - The item's index with error images. 오류난 이미지가 있는 엘리먼트의 인덱스 + * @param {HTMLElement} [e.target] - Error image target in element 엘리먼트의 오류난 이미지 타겟 + * @param {number} [e.errorCount] - The number of elements with errors 에러가 있는 엘리먼트들의 개수 + * @param {number} [e.totalErrorCount] - The total number of targets with errors 에러가 있는 타겟들의 총 개수 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check([document.querySelector("div")]).on({ + * error: e => { + * //
...
, 0, + * console.log(e.element, e.index, e.target), + * }, + * }); + * ``` + */ + + this.trigger("error", { + element: info.element, + index: index, + target: target, + errorCount: this.getErrorCount(), + totalErrorCount: ++this.totalErrorCount + }); + }; + + __proto.onPreReadyElement = function (index) { + var info = this.elementInfos[index]; + /** + * An event occurs when the element is pre-ready (when the loading attribute is applied or the size is known) + * @ko 해당 엘리먼트가 사전 준비되었을 때(loading 속성이 적용되었거나 사이즈를 알 수 있을 때) 이벤트가 발생한다. + * @event eg.ImReady#preReadyElement + * @param {eg.ImReady.OnPreReadyElement} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {HTMLElement} [e.element] - The pre-ready element.사전 준비된 엘리먼트 + * @param {number} [e.index] - The index of the pre-ready element. 사전 준비된 엘리먼트의 인덱스 + * @param {number} [e.preReadyCount] - Number of elements pre-ready 사전 준비된 엘리먼트들의 개수 + * @param {number} [e.readyCount] - Number of elements ready 준비된 엘리먼트들의 개수 + * @param {number} [e.totalCount] - Total number of elements 엘리먼트들의 총 개수 + * @param {boolean} [e.isPreReady] - Whether all elements are pre-ready 모든 엘리먼트가 사전 준비가 끝났는지 여부 + * @param {boolean} [e.isReady] - Whether all elements are ready 모든 엘리먼트가 준비가 끝났는지 여부 + * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied loading 속성이 적용되었는지 여부 + * @param {boolean} [e.isSkip] - Whether the check is omitted due to skip attribute skip 속성으로 인하여 체크가 생략됐는지 여부 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReadyElement: e => { + * // 1, 3 + * // 2, 3 + * // 3, 3 + * console.log(e.preReadyCount, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger("preReadyElement", { + element: info.element, + index: index, + preReadyCount: this.preReadyCount, + readyCount: this.readyCount, + totalCount: this.totalCount, + isPreReady: this.isPreReady(), + isReady: this.isReady(), + hasLoading: info.hasLoading, + isSkip: info.isSkip + }); + }; + + __proto.onPreReady = function () { + this.isPreReadyOver = true; + /** + * An event occurs when all element are pre-ready (When all elements have the loading attribute applied or the size is known) + * @ko 모든 엘리먼트들이 사전 준비된 경우 (모든 엘리먼트들이 loading 속성이 적용되었거나 사이즈를 알 수 있는 경우) 이벤트가 발생한다. + * @event eg.ImReady#preReady + * @param {eg.ImReady.OnPreReady} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {number} [e.readyCount] - Number of elements ready 준비된 엘리먼트들의 개수 + * @param {number} [e.totalCount] - Total number of elements 엘리먼트들의 총 개수 + * @param {boolean} [e.isReady] - Whether all elements are ready 모든 엘리먼트가 준비가 끝났는지 여부 + * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied loading 속성이 적용되었는지 여부 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReady: e => { + * // 0, 3 + * console.log(e.readyCount, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger("preReady", { + readyCount: this.readyCount, + totalCount: this.totalCount, + isReady: this.isReady(), + hasLoading: this.hasLoading() + }); + }; + + __proto.onReadyElement = function (index) { + var info = this.elementInfos[index]; + /** + * An event occurs when the element is ready + * @ko 해당 엘리먼트가 준비가 되었을 때 이벤트가 발생한다. + * @event eg.ImReady#readyElement + * @param {eg.ImReady.OnReadyElement} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {HTMLElement} [e.element] - The ready element.준비된 엘리먼트 + * @param {number} [e.index] - The index of the ready element. 준비된 엘리먼트의 인덱스 + * @param {boolean} [e.hasError] - Whether there is an error in the element 해당 엘리먼트에 에러가 있는지 여부 + * @param {number} [e.errorCount] - The number of elements with errors 에러가 있는 엘리먼트들의 개수 + * @param {number} [e.totalErrorCount] - The total number of targets with errors 에러가 있는 타겟들의 총 개수 + * @param {number} [e.preReadyCount] - Number of elements pre-ready 사전 준비된 엘리먼트들의 개수 + * @param {number} [e.readyCount] - Number of elements ready 준비된 엘리먼트들의 개수 + * @param {number} [e.totalCount] - Total number of elements 엘리먼트들의 총 개수 + * @param {boolean} [e.isPreReady] - Whether all elements are pre-ready 모든 엘리먼트가 사전 준비가 끝났는지 여부 + * @param {boolean} [e.isReady] - Whether all elements are ready 모든 엘리먼트가 준비가 끝났는지 여부 + * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied loading 속성이 적용되었는지 여부 + * @param {boolean} [e.isPreReadyOver] - Whether pre-ready is over 사전 준비가 끝났는지 여부 + * @param {boolean} [e.isSkip] - Whether the check is omitted due to skip attribute skip 속성으로 인하여 체크가 생략됐는지 여부 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * readyElement: e => { + * // 1, 0, false, 3 + * // 2, 1, false, 3 + * // 3, 2, true, 3 + * console.log(e.readyCount, e.index, e.hasError, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger("readyElement", { + index: index, + element: info.element, + hasError: info.hasError, + errorCount: this.getErrorCount(), + totalErrorCount: this.totalErrorCount, + preReadyCount: this.preReadyCount, + readyCount: this.readyCount, + totalCount: this.totalCount, + isPreReady: this.isPreReady(), + isReady: this.isReady(), + hasLoading: info.hasLoading, + isPreReadyOver: this.isPreReadyOver, + isSkip: info.isSkip + }); + }; + + __proto.onReady = function () { + /** + * An event occurs when all element are ready + * @ko 모든 엘리먼트들이 준비된 경우 이벤트가 발생한다. + * @event eg.ImReady#ready + * @param {eg.ImReady.OnReady} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {number} [e.errorCount] - The number of elements with errors 에러가 있는 엘리먼트들의 개수 + * @param {number} [e.totalErrorCount] - The total number of targets with errors 에러가 있는 타겟들의 총 개수 + * @param {number} [e.totalCount] - Total number of elements 엘리먼트들의 총 개수 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReady: e => { + * // 0, 3 + * console.log(e.readyCount, e.totalCount), + * }, + * ready: e => { + * // 1, 3 + * console.log(e.errorCount, e.totalCount), + * }, + * }); + * ``` + */ + this.trigger("ready", { + errorCount: this.getErrorCount(), + totalErrorCount: this.totalErrorCount, + totalCount: this.totalCount + }); + }; + + __proto.getErrorCount = function () { + return this.elementInfos.filter(function (info) { + return info.hasError; + }).length; + }; + + __proto.hasLoading = function () { + return this.elementInfos.some(function (info) { + return info.hasLoading; + }); + }; + + return ImReadyManager; + }(Component$1); + + var ImageLoader = + /*#__PURE__*/ + function (_super) { + __extends$2(ImageLoader, _super); + + function ImageLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = ImageLoader.prototype; + + __proto.checkElement = function () { + var element = this.element; + var src = element.getAttribute("src"); + + if (element.complete && src) { + if (!element.naturalWidth) { + this.onAlreadyError(element); + } + + return false; + } + + this.addEvents(); + IS_IE && element.setAttribute("src", src); + return true; + }; + + ImageLoader.EVENTS = ["load", "error"]; + return ImageLoader; + }(Loader); + + var VideoLoader = + /*#__PURE__*/ + function (_super) { + __extends$2(VideoLoader, _super); + + function VideoLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = VideoLoader.prototype; + + __proto.checkElement = function () { + var element = this.element; // HAVE_NOTHING: 0, no information whether or not the audio/video is ready + // HAVE_METADATA: 1, HAVE_METADATA - metadata for the audio/video is ready + // HAVE_CURRENT_DATA: 2, data for the current playback position is available, but not enough data to play next frame/millisecond + // HAVE_FUTURE_DATA: 3, data for the current and at least the next frame is available + // HAVE_ENOUGH_DATA: 4, enough data available to start playing + + if (element.readyState >= 1) { + return false; + } + + if (element.error) { + this.onAlreadyError(element); + return false; + } + + this.addEvents(); + return true; + }; + + VideoLoader.EVENTS = ["loadedmetadata", "error"]; + return VideoLoader; + }(Loader); + + var ImReady = + /*#__PURE__*/ + function (_super) { + __extends$2(ImReady, _super); + + function ImReady(options) { + if (options === void 0) { + options = {}; + } + + return _super.call(this, __assign$2({ + loaders: { + img: ImageLoader, + video: VideoLoader + } + }, options)) || this; + } + + return ImReady; + }(ImReadyManager); + + /** + * Constant value for errors + * @ko 에러에 대한 상수 값 + * @namespace + * @name ERROR_TYPE + * @memberof eg.view360.PanoViewer + */ + + var ERROR_TYPE = { + /** + * Unsupported device + * @ko 미지원 기기 + * @name INVALID_DEVICE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 10 + */ + INVALID_DEVICE: 10, + + /** + * Webgl not support + * @ko WEBGL 미지원 + * @name NO_WEBGL + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 11 + */ + NO_WEBGL: 11, + + /** + * Failed to load image + * @ko 이미지 로드 실패 + * @name FAIL_IMAGE_LOAD + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 12 + */ + FAIL_IMAGE_LOAD: 12, + + /** + * Failed to bind texture + * @ko 텍스쳐 바인딩 실패 + * @name FAIL_BIND_TEXTURE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 13 + */ + FAIL_BIND_TEXTURE: 13, + + /** + * Only one resource(image or video) should be specified + * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함) + * @name INVALID_RESOURCE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 14 + */ + INVALID_RESOURCE: 14, + + /** + * WebGL context lost occurred + * @ko WebGL context lost 발생 + * @name RENDERING_CONTEXT_LOST + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 15 + */ + RENDERING_CONTEXT_LOST: 15 + }; + /** + * Constant value for events + * @ko 이벤트에 대한 상수 값 + * @namespace + * @name EVENTS + * @memberof eg.view360.PanoViewer + */ + + var PANOVIEWER_EVENTS = { + /** + * Events that is fired when PanoViewer is ready to show image and handle user interaction. + * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트 + * @name READY + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default ready + */ + READY: "ready", + + /** + * Events that is fired when direction or fov is changed. + * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트 + * @name VIEW_CHANGE + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default viewChange + */ + VIEW_CHANGE: "viewChange", + + /** + * Events that is fired when animation which is triggered by inertia is ended. + * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트 + * @name ANIMATION_END + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default animationEnd + */ + ANIMATION_END: "animationEnd", + + /** + * Events that is fired when error occurs + * @ko 에러 발생 시 발생하는 이벤트 + * @name ERROR + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default error + */ + ERROR: "error" + }; + /** + * Constant value for projection type + * @ko 프로젝션 타입 대한 상수 값 + * @namespace + * @name PROJECTION_TYPE + * @memberof eg.view360.PanoViewer + */ + + var PROJECTION_TYPE = { + /** + * Constant value for equirectangular type. + * @ko equirectangular 에 대한 상수 값. + * @name EQUIRECTANGULAR + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default equirectangular + */ + EQUIRECTANGULAR: "equirectangular", + + /** + * Constant value for cubemap type. + * @ko cubemap 에 대한 상수 값. + * @name CUBEMAP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubemap + */ + CUBEMAP: "cubemap", + + /** + * Constant value for cubestrip type. + * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC. + * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다. + * @name CUBESTRIP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubestrip + */ + CUBESTRIP: "cubestrip", + + /** + * Constant value for PANORAMA type. + * + * PANORAMA is a format for a panorma image which is taken from smartphone. + * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다. + * + * @name PANORAMA + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default panorama + */ + PANORAMA: "panorama", + + /** + * Constant value for EQUI_STEREOSCOPY type. + * + * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present. + * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다. + * + * @name STEREOSCOPIC_EQUI + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default stereoequi + */ + STEREOSCOPIC_EQUI: "stereoequi" + }; + /** + * A constant value for the format of the stereoscopic equirectangular projection type. + * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값 + * @namespace + * @name STEREO_FORMAT + * @memberof eg.view360.PanoViewer + */ + + var STEREO_FORMAT = { + /** + * A constant value for format of top bottom stereoscopic 360 equirectangular projection. + * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name TOP_BOTTOM + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dv" + */ + TOP_BOTTOM: "3dv", + + /** + * A constant value for format of left right stereoscopic 360 equirectangular projection. + * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name LEFT_RIGHT + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dh" + */ + LEFT_RIGHT: "3dh", + + /** + * A constant value specifying media is not in stereoscopic format. + * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값. + * @name NONE + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "" + */ + NONE: "" + }; // eslint-disable-next-line @typescript-eslint/no-unused-vars + + var PANOVIEWER_OPTIONS = { + image: true, + video: true, + projectionType: true, + cubemapConfig: true, + stereoFormat: true, + width: true, + height: true, + yaw: true, + pitch: true, + fov: true, + showPolePoint: true, + useZoom: true, + useKeyboard: true, + gyroMode: true, + yawRange: true, + pitchRange: true, + fovRange: true, + touchDirection: true, + canvasClass: true + }; + var DEFAULT_CANVAS_CLASS = "view360-canvas"; + + var Constants = { + __proto__: null, + GYRO_MODE: GYRO_MODE, + PANOVIEWER_EVENTS: PANOVIEWER_EVENTS, + ERROR_TYPE: ERROR_TYPE, + PROJECTION_TYPE: PROJECTION_TYPE, + STEREO_FORMAT: STEREO_FORMAT, + PANOVIEWER_OPTIONS: PANOVIEWER_OPTIONS, + DEFAULT_CANVAS_CLASS: DEFAULT_CANVAS_CLASS + }; + + var WEBGL_ERROR_CODE = { + "0": "NO_ERROR", + "1280": "INVALID_ENUM", + "1281": "INVALID_VALUE", + "1282": "INVALID_OPERATION", + "1285": "OUT_OF_MEMORY", + "1286": "INVALID_FRAMEBUFFER_OPERATION", + "37442": "CONTEXT_LOST_WEBGL" + }; + var webglAvailability = null; // eslint-disable-next-line @typescript-eslint/naming-convention + + var WebGLUtils = + /*#__PURE__*/ + function () { + function WebGLUtils() {} + + WebGLUtils.createShader = function (gl, type, source) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + + if (success) { + return shader; + } // eslint-disable-next-line + + + console.error(gl.getShaderInfoLog(shader)); + return null; + }; + + WebGLUtils.createProgram = function (gl, vertexShader, fragmentShader) { + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + var success = gl.getProgramParameter(program, gl.LINK_STATUS); + + if (success) { + return program; + } + + gl.deleteProgram(program); + return null; + }; + + WebGLUtils.initBuffer = function (gl, target + /* bind point */ + , data, itemSize, attr) { + var buffer = gl.createBuffer(); + gl.bindBuffer(target, buffer); + gl.bufferData(target, data, gl.STATIC_DRAW); + + if (buffer) { + buffer.itemSize = itemSize; + buffer.numItems = data.length / itemSize; + } + + if (attr !== undefined) { + gl.enableVertexAttribArray(attr); + gl.vertexAttribPointer(attr, buffer.itemSize, gl.FLOAT, false, 0, 0); + } + + return buffer; + }; + + WebGLUtils.getWebglContext = function (canvas, userContextAttributes) { + var e_1, _a; + + var webglIdentifiers = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + var context = null; + + var contextAttributes = __assign({ + preserveDrawingBuffer: false, + antialias: false + }, userContextAttributes); + + var onWebglcontextcreationerror = function (e) { + return e.statusMessage; + }; + + canvas.addEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + + try { + for (var webglIdentifiers_1 = __values(webglIdentifiers), webglIdentifiers_1_1 = webglIdentifiers_1.next(); !webglIdentifiers_1_1.done; webglIdentifiers_1_1 = webglIdentifiers_1.next()) { + var identifier = webglIdentifiers_1_1.value; + + try { + context = canvas.getContext(identifier, contextAttributes); + } catch (t) {} // eslint-disable-line no-empty + + + if (context) { + break; + } + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (webglIdentifiers_1_1 && !webglIdentifiers_1_1.done && (_a = webglIdentifiers_1.return)) _a.call(webglIdentifiers_1); + } finally { + if (e_1) throw e_1.error; + } + } + + canvas.removeEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + return context; + }; + + WebGLUtils.createTexture = function (gl, textureTarget) { + var texture = gl.createTexture(); + gl.bindTexture(textureTarget, texture); + gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindTexture(textureTarget, null); + return texture; + }; + /** + * Returns the webgl availability of the current browser. + * @method WebGLUtils#isWebGLAvailable + * @retuen {Boolean} isWebGLAvailable + */ + + + WebGLUtils.isWebGLAvailable = function () { + if (webglAvailability === null) { + var canvas = document.createElement("canvas"); + var webglContext = WebGLUtils.getWebglContext(canvas); + webglAvailability = !!webglContext; // webglContext Resource forced collection + + if (webglContext) { + var loseContextExtension = webglContext.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + } + + return !!webglAvailability; + }; + /** + * Returns whether webgl is stable in the current browser. + * @method WebGLUtils#isStableWebGL + * @retuen {Boolean} isStableWebGL + */ + + + WebGLUtils.isStableWebGL = function () { + var agentInfo = agent(); + var isStableWebgl = true; + + if (agentInfo.os.name === "android") { + var version = parseFloat(agentInfo.os.version); + + if (version <= 4.3 && version >= 1) { + isStableWebgl = false; + } else if (version === 4.4) { + if (agentInfo.browser.name !== "chrome") { + isStableWebgl = false; + } + } + } + + return isStableWebgl; + }; + + WebGLUtils.getErrorNameFromWebGLErrorCode = function (code) { + if (!(code in WEBGL_ERROR_CODE)) { + return "UNKNOWN_ERROR"; + } + + return WEBGL_ERROR_CODE[code]; + }; + /** + * This function is wrapper for texImage2D to handle exceptions on texImage2D. + * Purpose is to prevent service from being stopped by script error. + */ + + + WebGLUtils.texImage2D = function (gl, target, pixels) { + try { + gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + } catch (error) { + /* eslint-disable no-console */ + console.error("WebGLUtils.texImage2D error:", error); + /* eslint-enable no-console */ + } + }; + + WebGLUtils.getMaxTextureSize = function (gl) { + // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test + return gl.getParameter(gl.MAX_TEXTURE_SIZE); + }; + + return WebGLUtils; + }(); + + var agentInfo = agent(); + var isIE11 = agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11; + var EVENTS = { + ERROR: "error" + }; + /** + * + * Extends Component for firing errors occurs internally. + */ + + var Renderer = + /*#__PURE__*/ + function (_super) { + __extends(Renderer, _super); + + function Renderer() { + var _this = _super.call(this) || this; + + _this._forceDimension = null; + _this._pixelCanvas = null; + _this._pixelContext = null; + return _this; + } + + var __proto = Renderer.prototype; + + __proto.render = function (_a) { + var gl = _a.gl, + shaderProgram = _a.shaderProgram, + indexBuffer = _a.indexBuffer, + mvMatrix = _a.mvMatrix, + pMatrix = _a.pMatrix; + gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); + gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); + + if (indexBuffer) { + gl.drawElements(gl.TRIANGLES, indexBuffer.numItems, gl.UNSIGNED_SHORT, 0); + } + }; // Define interface for Renderers + + /** + * Following MUST BE DEFINED on Child of Renderer + * + * DATA + * + * - getVertexPositionData + * - getIndexData + * - getTextureCoordData + * + * SOURCE + * + * - getVertexShaderSource + * - getFragmentShaderSource + * + * TEXTURE + * + * - bindTexture + */ + + + __proto.getDimension = function (pixelSource) { + var width = pixelSource.naturalWidth || pixelSource.videoWidth; + var height = pixelSource.naturalHeight || pixelSource.videoHeight; + return { + width: width, + height: height + }; + }; + /** + * Update data used by shader + */ + + + __proto.updateShaderData = function (param) { + /* + * Update following data in implementation layer. + * If the data is not changed, it does not need to implement this function. + * + * - _VERTEX_POSITION_DATA + * - _TEXTURE_COORD_DATA + * - _INDEX_DATA + */ + }; + /** + * + * @param {HTMLImageElement | HTMLVideoElement} image + * @param {Object = {width, height}} forceDimension Forced dimension to resize + */ + + + __proto._initPixelSource = function (image, forceDimension) { + if (forceDimension === void 0) { + forceDimension = null; + } + + var isIE11Video = isIE11 && image instanceof HTMLVideoElement; + + if (isIE11Video || forceDimension) { + var _a = forceDimension || this.getDimension(image), + width = _a.width, + height = _a.height; + + this._pixelCanvas = document.createElement("canvas"); + this._pixelCanvas.width = width; + this._pixelCanvas.height = height; + this._pixelContext = this._pixelCanvas.getContext("2d"); + } + + this._forceDimension = forceDimension; + }; + + __proto._getPixelSource = function (image) { + if (!this._pixelCanvas) { + return image; + } + /** + * IE11 && Video + * or + * Dimension is forced (Image is larger than texture size.) + */ + + + var contentDimension = this.getDimension(image); + var textureDimension = this._forceDimension || contentDimension; + + if (this._pixelCanvas.width !== textureDimension.width) { + this._pixelCanvas.width = textureDimension.width; + } + + if (this._pixelCanvas.height !== textureDimension.height) { + this._pixelCanvas.height = textureDimension.height; + } + + if (this._forceDimension) { + this._pixelContext.drawImage(image, 0, 0, contentDimension.width, contentDimension.height, 0, 0, textureDimension.width, textureDimension.height); + } else { + this._pixelContext.drawImage(image, 0, 0); + } + + return this._pixelCanvas; + }; + + __proto._extractTileConfig = function (imageConfig) { + var tileConfig = Array.isArray(imageConfig.tileConfig) ? imageConfig.tileConfig : Array.apply(void 0, __spread(Array(6))).map(function () { + return imageConfig.tileConfig; + }); + tileConfig = tileConfig.map(function (config) { + return __assign({ + flipHorizontal: false, + rotation: 0 + }, config); + }); + return tileConfig; + }; + + __proto._triggerError = function (error) { + /* eslint-disable no-console */ + console.error("Renderer Error:", error); + /* eslint-enable no-console */ + + this.trigger(new ComponentEvent$1(EVENTS.ERROR, { + message: typeof error === "string" ? error : error.message + })); + }; + + Renderer.EVENTS = EVENTS; + return Renderer; + }(Component); + + var CubeRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CubeRenderer, _super); + + function CubeRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeRenderer.prototype; + + CubeRenderer.extractOrder = function (imageConfig) { + return imageConfig.order || "RLUDBF"; + }; + + __proto.getVertexPositionData = function () { + CubeRenderer._VERTEX_POSITION_DATA = CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // top + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // bottom + 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + return CubeRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + if (CubeRenderer._INDEX_DATA) { + return CubeRenderer._INDEX_DATA; + } + + var indexData = []; + var vertexPositionData = this.getVertexPositionData(); + + for (var i = 0; i < vertexPositionData.length / 3; i += 4) { + indexData.push(i, i + 2, i + 1, i, i + 3, i + 2); + } + + CubeRenderer._INDEX_DATA = indexData; + return indexData; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; + var vertexOrder = "BFUDRL"; + var order = CubeRenderer.extractOrder(imageConfig); + var base = this.getVertexPositionData(); + + var tileConfig = this._extractTileConfig(imageConfig); + + var elemSize = 3; + var vertexPerTile = 4; + var trim = imageConfig.trim; + var texCoords = vertexOrder.split("").map(function (face) { + return tileConfig[order.indexOf(face)]; + }).map(function (config, i) { + var rotation = Math.floor(config.rotation / 90); + var ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2]; + + for (var r = 0; r < Math.abs(rotation); r++) { + if (config.flipHorizontal && rotation > 0 || !config.flipHorizontal && rotation < 0) { + ordermap.push(ordermap.shift()); + } else { + ordermap.unshift(ordermap.pop()); + } + } + + var elemPerTile = elemSize * vertexPerTile; + var tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile); + var tileTemp = []; + + for (var j = 0; j < vertexPerTile; j++) { + tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize); + } + + return tileTemp; + }).map(function (coord) { + return _this._shrinkCoord({ + image: image, + faceCoords: coord, + trim: trim + }); + }).reduce(function (acc, val) { + return __spread(acc, val.reduce(function (coords, coord) { + return __spread(coords, coord); + }, [])); + }, []); + return texCoords; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}"; + }; + + __proto.updateTexture = function (gl, image, imageConfig) { + var baseOrder = "RLUDBF"; + var order = CubeRenderer.extractOrder(imageConfig); + var orderMap = {}; + order.split("").forEach(function (v, i) { + orderMap[v] = i; + }); + + try { + if (image instanceof Array) { + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]); + } + } else { + var maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image); + + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + var tile = this.extractTileFromImage(image, tileIdx, maxCubeMapTextureSize); + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile); + } + } + } catch (e) { + this._triggerError(e); + } + }; + + __proto.bindTexture = function (gl, texture, image, imageConfig) { + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + this.updateTexture(gl, image, imageConfig); + }; + + __proto.getSourceTileSize = function (image) { + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var aspectRatio = width / height; + var inputTextureSize; + + if (aspectRatio === 1 / 6) { + inputTextureSize = width; + } else if (aspectRatio === 6) { + inputTextureSize = height; + } else if (aspectRatio === 2 / 3) { + inputTextureSize = width / 2; + } else { + inputTextureSize = width / 3; + } + + return inputTextureSize; + }; + + __proto.extractTileFromImage = function (image, tileIdx, outputTextureSize) { + var width = this.getDimension(image).width; + var inputTextureSize = this.getSourceTileSize(image); + var canvas = document.createElement("canvas"); + canvas.width = outputTextureSize; + canvas.height = outputTextureSize; + var context = canvas.getContext("2d"); + var tilePerRow = width / inputTextureSize; + var x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow); + var y = Math.floor(tileIdx / tilePerRow) * inputTextureSize; + context.drawImage(image, x, y, inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize); + return canvas; + }; + + __proto.getMaxCubeMapTextureSize = function (gl, image) { + var agentInfo = agent(); + var maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); + var imageWidth = this.getSourceTileSize(image); + + if (agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11) { + if (!util.isPowerOfTwo(imageWidth)) { + for (var i = 1; i < maxCubeMapTextureSize; i *= 2) { + if (i < imageWidth) { + continue; + } else { + imageWidth = i; + break; + } + } + } + } + + if (agentInfo.os.name === "ios") { + var majorVersion = agentInfo.os.majorVersion; // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다. + + if (majorVersion === 9) { + imageWidth = 1024; + } // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다. + + + if (majorVersion === 8) { + imageWidth = 512; + } + } // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수 + + + return Math.min(maxCubeMapTextureSize, imageWidth); + }; + + __proto._shrinkCoord = function (coordData) { + var image = coordData.image, + faceCoords = coordData.faceCoords, + trim = coordData.trim; + var inputTextureSize = Array.isArray(image) ? this.getDimension(image[0]).width : this.getSourceTileSize(image); // Shrink by "trim" px + + var SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize); + var axisMultipliers = [0, 1, 2].map(function (axisIndex) { + var axisDir = util.sign(faceCoords[0][axisIndex]); + var notSameDir = faceCoords.some(function (coord) { + return util.sign(coord[axisIndex]) !== axisDir; + }); + return notSameDir; + }).map(function (notSameDir) { + return notSameDir ? SHRINK_MULTIPLIER : 1; + }); + return faceCoords.map(function (coords) { + return coords.map(function (coord, axisIndex) { + return coord * axisMultipliers[axisIndex]; + }); + }); + }; + + CubeRenderer._VERTEX_POSITION_DATA = null; + CubeRenderer._INDEX_DATA = null; + return CubeRenderer; + }(Renderer); + + var CubeStripRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CubeStripRenderer, _super); + + function CubeStripRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeStripRenderer.prototype; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"; + }; + + __proto.getVertexPositionData = function () { + if (!this._vertices) { + this._vertices = [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + } + + return this._vertices; + }; + + __proto.getIndexData = function () { + var _this = this; // TODO: 한번만 계산하도록 수정하기 + + + var indices = function () { + var indexData = []; + + for (var i = 0; i < _this._vertices.length / 3; i += 4) { + indexData.push(i, i + 1, i + 2, i, i + 2, i + 3); + } + + return indexData; + }(); + + return indices; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; // TODO: make it cols, rows as config. + + var cols = 3; + var rows = 2; + var textureSize = this.getDimension(image); + var trim = imageConfig.trim; + var order = imageConfig.order || "RLUDFB"; + var coords = []; // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다. + + for (var r = rows - 1; r >= 0; r--) { + for (var c = 0; c < cols; c++) { + var coord = [c / cols, r / rows, (c + 1) / cols, r / rows, (c + 1) / cols, (r + 1) / rows, c / cols, (r + 1) / rows]; + coords.push(coord); + } + } + + var tileConfigs = this._extractTileConfig(imageConfig); // Transform Coord By Flip & Rotation + + + coords = coords // shrink coord to avoid pixel bleeding + .map(function (coord) { + return _this._shrinkCoord(coord, textureSize, trim); + }).map(function (coord, i) { + return _this._transformCoord(coord, tileConfigs[i]); + }); // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치 + + return "BFUDRL".split("").map(function (face) { + return order.indexOf(face); + }).map(function (index) { + return coords[index]; + }).reduce(function (acc, val) { + return acc.concat(val); + }, []); + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto._transformCoord = function (coord, tileConfig) { + var newCoord = coord.slice(); + + if (tileConfig.flipHorizontal) { + newCoord = this._flipHorizontalCoord(newCoord); + } + + if (tileConfig.rotation) { + newCoord = this._rotateCoord(newCoord, tileConfig.rotation); + } + + return newCoord; + }; + + __proto._shrinkCoord = function (coord, textureSize, trim) { + var width = textureSize.width, + height = textureSize.height; // Shrink by "trim" px + + var SHRINK_Y = trim * (1 / height); + var SHRINK_X = trim * (1 / width); + return [coord[0] + SHRINK_X, coord[1] + SHRINK_Y, coord[2] - SHRINK_X, coord[3] + SHRINK_Y, coord[4] - SHRINK_X, coord[5] - SHRINK_Y, coord[6] + SHRINK_X, coord[7] - SHRINK_Y]; + }; + + __proto._rotateCoord = function (coord, rotationAngle) { + var SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord. + + var shiftCount = Math.floor(rotationAngle / 90) % 4; + + if (shiftCount === 0) { + return coord; + } + + var moved; + var rotatedCoord = []; + + if (shiftCount > 0) { + moved = coord.splice(0, shiftCount * SIZE); + rotatedCoord = coord.concat(moved); + } else { + moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE); + rotatedCoord = moved.concat(coord); + } + + return rotatedCoord; + }; + + __proto._flipHorizontalCoord = function (coord) { + return [coord[2], coord[3], coord[0], coord[1], coord[6], coord[7], coord[4], coord[5]]; + }; + + return CubeStripRenderer; + }(Renderer); + + var latitudeBands = 60; + var longitudeBands = 60; + var radius = 2; + var ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + var textureCoordData = []; + var vertexPositionData = []; + var indexData = []; + var latIdx; + var lngIdx; + + for (latIdx = 0; latIdx <= latitudeBands; latIdx++) { + var theta = (latIdx / latitudeBands - 0.5) * Math.PI; + var sinTheta = Math.sin(theta); + var cosTheta = Math.cos(theta); + + for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) { + var phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + var sinPhi = Math.sin(phi); + var cosPhi = Math.cos(phi); + var x = cosPhi * cosTheta; + var y = sinTheta; + var z = sinPhi * cosTheta; + var u = lngIdx / longitudeBands; + var v = latIdx / latitudeBands; + textureCoordData.push(u, v); + vertexPositionData.push(radius * x, radius * y, radius * z); + + if (lngIdx !== longitudeBands && latIdx !== latitudeBands) { + var a = latIdx * (longitudeBands + 1) + lngIdx; + var b = a + longitudeBands + 1; + indexData.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + + var SphereRenderer = + /*#__PURE__*/ + function (_super) { + __extends(SphereRenderer, _super); + + function SphereRenderer(format) { + var _this = _super.call(this) || this; + + _this._stereoFormat = format; + return _this; + } + + var __proto = SphereRenderer.prototype; + + __proto.render = function (ctx) { + var gl = ctx.gl, + shaderProgram = ctx.shaderProgram; + var leftEyeScaleOffset; + var rightEyeScaleOffset; + + switch (this._stereoFormat) { + case STEREO_FORMAT.TOP_BOTTOM: + leftEyeScaleOffset = [1, 0.5, 0, 0]; + rightEyeScaleOffset = [1, 0.5, 0, 0.5]; + break; + + case STEREO_FORMAT.LEFT_RIGHT: + leftEyeScaleOffset = [0.5, 1, 0, 0]; + rightEyeScaleOffset = [0.5, 1, 0.5, 0]; + break; + + default: + leftEyeScaleOffset = [1, 1, 0, 0]; + rightEyeScaleOffset = [1, 1, 0, 0]; + } + + var uTexScaleOffset = gl.getUniformLocation(shaderProgram, "uTexScaleOffset"); + gl.uniform4fv(uTexScaleOffset, __spread(leftEyeScaleOffset, rightEyeScaleOffset)); + + _super.prototype.render.call(this, ctx); + }; + + __proto.getVertexPositionData = function () { + return SphereRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return SphereRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return SphereRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + SphereRenderer._VERTEX_POSITION_DATA = vertexPositionData; + SphereRenderer._TEXTURE_COORD_DATA = textureCoordData; + SphereRenderer._INDEX_DATA = indexData; + return SphereRenderer; + }(Renderer); + + var MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6; + var longitudeBands$1 = 60; + var textureCoordData$1 = []; + var vertexPositionData$1 = []; + var indexData$1 = []; + + var CylinderRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CylinderRenderer, _super); + + function CylinderRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CylinderRenderer.prototype; + + __proto.getVertexPositionData = function () { + return CylinderRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return CylinderRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return CylinderRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + var resizeDimension; + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device texture limit(" + maxSize + "))"); // Request resizing texture. + + /** + * TODO: Is it need to apply on another projection type? + */ + + + resizeDimension = width > height ? { + width: maxSize, + height: maxSize * height / width + } : { + width: maxSize * width / height, + height: maxSize + }; + } // Pixel Source for IE11 & Video or resizing needed + + + this._initPixelSource(image, resizeDimension); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto.updateShaderData = function (_a) { + var _b = _a.imageAspectRatio, + imageAspectRatio = _b === void 0 ? MIN_ASPECT_RATIO_FOR_FULL_PANORAMA : _b; + var lngIdx; + var cylinderMaxRadian; + var halfCylinderY; + var rotated; + var aspectRatio; // Exception case: orientation is rotated. + + if (imageAspectRatio < 1) { + /** + * If rotated is true, we assume that image is rotated counter clockwise. + * TODO: If there's other rotation, it is need to implement by each rotation. + */ + rotated = true; + aspectRatio = 1 / imageAspectRatio; + } else { + rotated = false; + aspectRatio = imageAspectRatio; + } + + if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) { + var fov = 360 / aspectRatio; + cylinderMaxRadian = 2 * Math.PI; // 360 deg + + halfCylinderY = Math.tan(toRadian(fov / 2)); + } else { + cylinderMaxRadian = aspectRatio; + halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1. + } // initialize shader data before update + + + textureCoordData$1.length = 0; + vertexPositionData$1.length = 0; + indexData$1.length = 0; + var CYLIDER_Y = [-halfCylinderY, halfCylinderY]; + var startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360) + // console.log("cylinderMaxRadian:", glMatrix.toDegree(cylinderMaxRadian), "CYLIDER_Y", CYLIDER_Y, "start angle", glMatrix.toDegree(startAngleForCenterAlign)); + + for (var yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength + /* bottom & top */ + ; yIdx++) { + for (lngIdx = 0; lngIdx <= longitudeBands$1; lngIdx++) { + var angle = startAngleForCenterAlign + lngIdx / longitudeBands$1 * cylinderMaxRadian; + var x = Math.cos(angle); + var y = CYLIDER_Y[yIdx]; + var z = Math.sin(angle); + var u = void 0; + var v = void 0; + + if (rotated) { + // Rotated 90 degree (counter clock wise) + u = 1 - yIdx; // yLength - yIdx; + + v = lngIdx / longitudeBands$1; + } else { + // // Normal case (Not rotated) + u = lngIdx / longitudeBands$1; + v = yIdx; + } + + textureCoordData$1.push(u, v); + vertexPositionData$1.push(x, y, z); + + if (yIdx === 0 && lngIdx < longitudeBands$1) { + var a = lngIdx; + var b = a + longitudeBands$1 + 1; + indexData$1.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + }; + + CylinderRenderer._VERTEX_POSITION_DATA = vertexPositionData$1; + CylinderRenderer._TEXTURE_COORD_DATA = textureCoordData$1; + CylinderRenderer._INDEX_DATA = indexData$1; + return CylinderRenderer; + }(Renderer); + + var VR_DISPLAY_PRESENT_CHANGE = "vrdisplaypresentchange"; + var DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1]; + var DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1]; + var EYES = { + LEFT: "left", + RIGHT: "right" + }; + + var VRManager = + /*#__PURE__*/ + function () { + function VRManager() { + var _this = this; + + this.destroy = function () { + var vrDisplay = _this._vrDisplay; + + _this.removeEndCallback(_this.destroy); + + if (vrDisplay && vrDisplay.isPresenting) { + void vrDisplay.exitPresent(); + } + + _this._clear(); + }; + + this._frameData = new window.VRFrameData(); + + this._clear(); + } + + var __proto = VRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._vrDisplay; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function () { + return Boolean(this._vrDisplay); + }; + + __proto.beforeRender = function (gl) { + // Render to the default backbuffer + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + }; + + __proto.afterRender = function () { + this._vrDisplay.submitFrame(); + }; + + __proto.getEyeParams = function (gl) { + var display = this._vrDisplay; + var halfWidth = gl.drawingBufferWidth * 0.5; + var height = gl.drawingBufferHeight; + var frameData = this._frameData; + display.getFrameData(frameData); + var leftMVMatrix = frameData.leftViewMatrix; + var rightMVMatrix = frameData.rightViewMatrix; + rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset); + rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset); + return [{ + viewport: [0, 0, halfWidth, height], + mvMatrix: leftMVMatrix, + pMatrix: frameData.leftProjectionMatrix + }, { + viewport: [halfWidth, 0, halfWidth, height], + mvMatrix: rightMVMatrix, + pMatrix: frameData.rightProjectionMatrix + }]; + }; + + __proto.isPresenting = function () { + return Boolean(this._vrDisplay && this._vrDisplay.isPresenting); + }; + + __proto.addEndCallback = function (callback) { + window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.removeEndCallback = function (callback) { + window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.requestPresent = function (canvas) { + var _this = this; + + return navigator.getVRDisplays().then(function (displays) { + var vrDisplay = displays.length && displays[0]; + + if (!vrDisplay) { + return Promise$1.reject(new Error("No displays available.")); + } + + if (!vrDisplay.capabilities.canPresent) { + return Promise$1.reject(new Error("Display lacking capability to present.")); + } + + return vrDisplay.requestPresent([{ + source: canvas + }]).then(function () { + var leftEye = vrDisplay.getEyeParameters(EYES.LEFT); + var rightEye = vrDisplay.getEyeParameters(EYES.RIGHT); + canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2; + canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight); + + _this._setDisplay(vrDisplay); + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setDisplay = function (vrDisplay) { + this._vrDisplay = vrDisplay; + var layers = vrDisplay.getLayers(); + + if (layers.length) { + var layer = layers[0]; + this._leftBounds = layer.leftBounds; + this._rightBounds = layer.rightBounds; + } + + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._vrDisplay = null; + this._leftBounds = DEFAULT_LEFT_BOUNDS; + this._rightBounds = DEFAULT_RIGHT_BOUNDS; + this._yawOffset = 0; + }; + + return VRManager; + }(); + + var XR_REFERENCE_SPACE = "local"; + + var XRManager = + /*#__PURE__*/ + function () { + function XRManager(options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + this.destroy = function () { + var xrSession = _this._xrSession; + + _this.removeEndCallback(_this.destroy); + + if (xrSession) { + // Capture to avoid errors + xrSession.end().then(function () { + return void 0; + }, function () { + return void 0; + }); + } + + _this._clear(); + }; + + this._clear(); + + this._options = options; + } + + var __proto = XRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._xrSession; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function (frame) { + var pose = frame.getViewerPose(this._xrRefSpace); + return Boolean(pose); + }; + + __proto.beforeRender = function (gl, frame) { + var session = frame.session; + var baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + }; // eslint-disable-next-line @typescript-eslint/no-empty-function + + + __proto.afterRender = function () {}; + + __proto.getEyeParams = function (gl, frame) { + var _this = this; + + var session = frame.session; + var pose = frame.getViewerPose(this._xrRefSpace); + + if (!pose) { + // Can't render + return null; + } + + var glLayer = session.renderState.baseLayer; + return pose.views.map(function (view) { + var viewport = glLayer.getViewport(view); + var mvMatrix = view.transform.inverse.matrix; + + if (IS_SAFARI_ON_DESKTOP) { + rotateX(mvMatrix, mvMatrix, toRadian(180)); + } + + rotateY(mvMatrix, mvMatrix, _this._yawOffset); + return { + viewport: [viewport.x, viewport.y, viewport.width, viewport.height], + mvMatrix: mvMatrix, + pMatrix: view.projectionMatrix + }; + }); + }; + + __proto.isPresenting = function () { + return this._presenting; + }; + + __proto.addEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.addEventListener("end", callback); + }; + + __proto.removeEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.removeEventListener("end", callback); + }; + + __proto.requestPresent = function (canvas, gl) { + return __awaiter(this, void 0, void 0, function () { + var options, attributes; + + var _this = this; + + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = merge({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + attributes = gl.getContextAttributes(); + if (!(attributes && attributes.xrCompatible !== true)) return [3 + /*break*/ + , 2]; + return [4 + /*yield*/ + , gl.makeXRCompatible()]; + + case 1: + _a.sent(); + + _a.label = 2; + + case 2: + return [2 + /*return*/ + , navigator.xr.requestSession("immersive-vr", options).then(function (session) { + var xrLayer = new window.XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + return session.requestReferenceSpace(XR_REFERENCE_SPACE).then(function (refSpace) { + _this._setSession(session, xrLayer, refSpace); + }); + })]; + } + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setSession = function (session, xrLayer, refSpace) { + this._xrSession = session; + this._xrLayer = xrLayer; + this._xrRefSpace = refSpace; + this._presenting = true; + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._xrSession = null; + this._xrLayer = null; + this._xrRefSpace = null; + this._presenting = false; + this._yawOffset = 0; + this._options = {}; + }; + + return XRManager; + }(); + + var WebGLAnimator = + /*#__PURE__*/ + function () { + function WebGLAnimator() { + var _this = this; + /** + * There can be more than 1 argument when we use XRSession's raf + */ + + + this._onLoop = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + _this._callback.apply(_this, __spread(args)); + + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + }; + /** + * MacOS X Safari Bug Fix + * This code guarantees that rendering should be occurred. + * + * In MacOS X(10.14.2), Safari (12.0.2) + * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term + * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms) + * So browser cannot render the frame and may be freezing. + */ + + + this._onLoopNextTick = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + var before = performance.now(); + + _this._callback.apply(_this, __spread(args)); + + var diff = performance.now() - before; + + if (_this._rafTimer >= 0) { + clearTimeout(_this._rafTimer); + _this._rafTimer = -1; + } + /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */ + + + if (diff < 16) { + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + } else { + /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */ + _this._rafTimer = window.setTimeout(_this._onLoop, 0); + } + }; + + this._callback = null; + this._context = window; + this._rafId = -1; + this._rafTimer = -1; + } + + var __proto = WebGLAnimator.prototype; + + __proto.setCallback = function (callback) { + this._callback = callback; + }; + + __proto.setContext = function (context) { + this._context = context; + }; + + __proto.start = function () { + var context = this._context; + var callback = this._callback; // No context / callback set + + if (!context || !callback) return; // Animation already started + + if (this._rafId >= 0 || this._rafTimer >= 0) return; + + if (IS_SAFARI_ON_DESKTOP) { + this._rafId = context.requestAnimationFrame(this._onLoopNextTick); + } else { + this._rafId = context.requestAnimationFrame(this._onLoop); + } + }; + + __proto.stop = function () { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + + this._rafId = -1; + this._rafTimer = -1; + }; + + return WebGLAnimator; + }(); + + var ImageType = PROJECTION_TYPE; // eslint-disable-next-line @typescript-eslint/naming-convention + + var DEVICE_PIXEL_RATIO = devicePixelRatio || 1; // DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다. + + if (DEVICE_PIXEL_RATIO > 2) { + DEVICE_PIXEL_RATIO = 2; + } // define custom events name + + /** + * TODO: how to manage events/errortype with PanoViewer + * + * I think renderer events should be seperated from viewer events although it has same name. + */ + + + var EVENTS$1 = { + BIND_TEXTURE: "bindTexture", + IMAGE_LOADED: "imageLoaded", + ERROR: "error", + RENDERING_CONTEXT_LOST: "renderingContextLost", + RENDERING_CONTEXT_RESTORE: "renderingContextRestore" + }; + var ERROR_TYPE$1 = { + INVALID_DEVICE: 10, + NO_WEBGL: 11, + FAIL_IMAGE_LOAD: 12, + RENDERER_ERROR: 13 + }; + + var PanoImageRenderer = + /*#__PURE__*/ + function (_super) { + __extends(PanoImageRenderer, _super); + + function PanoImageRenderer(image, width, height, isVideo, container, canvasClass, sphericalConfig, renderingContextAttributes) { + var _this = // Super constructor + _super.call(this) || this; + + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + + _this.exitVR = function () { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; + if (!vr) return; + vr.removeEndCallback(_this.exitVR); + vr.destroy(); + _this._vr = null; // Restore canvas & context on iOS + + if (IS_IOS) { + _this._restoreStyle(); + } + + _this.updateViewportDimensions(_this.width, _this.height); + + _this._updateViewport(); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + _this._bindBuffers(); + + _this._shouldForceDraw = true; + animator.stop(); + animator.setContext(window); + animator.setCallback(_this._render.bind(_this)); + animator.start(); + }; + + _this._renderStereo = function (time, frame) { + var e_1, _a; + + var vr = _this._vr; + var gl = _this.context; + var eyeParams = vr.getEyeParams(gl, frame); + if (!eyeParams) return; + vr.beforeRender(gl, frame); + + try { + // Render both eyes + for (var _b = __values([0, 1]), _c = _b.next(); !_c.done; _c = _b.next()) { + var eyeIndex = _c.value; + var eyeParam = eyeParams[eyeIndex]; + _this.mvMatrix = eyeParam.mvMatrix; + _this.pMatrix = eyeParam.pMatrix; + gl.viewport.apply(gl, __spread(eyeParam.viewport)); + gl.uniform1f(_this.shaderProgram.uEye, eyeIndex); + + _this._bindBuffers(); + + _this._draw(); + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + + vr.afterRender(); + }; + + _this._onFirstVRFrame = function (time, frame) { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; // If rendering is not ready, wait for next frame + + if (!vr.canRender(frame)) return; + var minusZDir = fromValues(0, 0, -1); + var eyeParam = vr.getEyeParams(gl, frame)[0]; // Extract only rotation + + var mvMatrix = fromMat4(create(), eyeParam.mvMatrix); + var pMatrix = fromMat4(create(), eyeParam.pMatrix); + var mvInv = invert(create(), mvMatrix); + var pInv = invert(create(), pMatrix); + var viewDir = transformMat3(create$2(), minusZDir, pInv); + transformMat3(viewDir, viewDir, mvInv); + var yawOffset = util.yawOffsetBetween(viewDir, fromValues(0, 0, 1)); + + if (yawOffset === 0) { + // If the yawOffset is exactly 0, then device sensor is not ready + // So read it again until it has any value in it + return; + } + + vr.setYawOffset(yawOffset); + animator.setCallback(_this._renderStereo); + }; + + _this.sphericalConfig = sphericalConfig; + _this.fieldOfView = sphericalConfig.fieldOfView; + _this.width = width; + _this.height = height; + _this._lastQuaternion = null; + _this._lastYaw = null; + _this._lastPitch = null; + _this._lastFieldOfView = null; + _this.pMatrix = create$1(); + _this.mvMatrix = create$1(); // initialzie pMatrix + + perspective(_this.pMatrix, toRadian(_this.fieldOfView), width / height, 0.1, 100); + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + _this.canvas = _this._initCanvas(container, canvasClass, width, height); + + _this._setDefaultCanvasStyle(); + + _this._wrapper = null; // canvas wrapper + + _this._wrapperOrigStyle = null; + _this._renderingContextAttributes = renderingContextAttributes; + _this._image = null; + _this._imageConfig = null; + _this._imageIsReady = false; + _this._shouldForceDraw = false; + _this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still. + + _this._onContentLoad = _this._onContentLoad.bind(_this); + _this._onContentError = _this._onContentError.bind(_this); + _this._animator = new WebGLAnimator(); // VR/XR manager + + _this._vr = null; + + if (image) { + _this.setImage({ + image: image, + imageType: sphericalConfig.imageType, + isVideo: isVideo, + cubemapConfig: sphericalConfig.cubemapConfig + }); + } + + return _this; + } // FIXME: Please refactor me to have more loose connection to yawpitchcontrol + + + var __proto = PanoImageRenderer.prototype; + + __proto.setYawPitchControl = function (yawPitchControl) { + this._yawPitchControl = yawPitchControl; + }; + + __proto.getContent = function () { + return this._image; + }; + + __proto.setImage = function (_a) { + var image = _a.image, + imageType = _a.imageType, + _b = _a.isVideo, + isVideo = _b === void 0 ? false : _b, + cubemapConfig = _a.cubemapConfig; + this._imageIsReady = false; + this._isVideo = isVideo; + this._imageConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only */ + order: imageType === ImageType.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, cubemapConfig); + + this._setImageType(imageType); + + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._contentLoader = new ImReady().on("ready", this._onContentLoad).on("error", this._onContentError); + + if (isVideo) { + this._image = toVideoElement(image); + + this._contentLoader.check([this._image]); + + this._keepUpdate = true; + } else { + this._image = toImageElement(image); + + this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]); + + this._keepUpdate = false; + } + }; + + __proto.isImageLoaded = function () { + return !!this._image && this._imageIsReady && (!this._isVideo || this._image.readyState >= 2 + /* HAVE_CURRENT_DATA */ + ); + }; + + __proto.bindTexture = function () { + var _this = this; + + return new Promise$1(function (res, rej) { + var contentLoader = _this._contentLoader; + + if (!_this._image) { + return rej("Image is not defined"); + } + + if (!contentLoader) { + return rej("ImageLoader is not initialized"); + } + + if (contentLoader.isReady()) { + _this._bindTexture(); + + res(); + } else { + contentLoader.check(Array.isArray(_this._image) ? _this._image : [_this._image]); + contentLoader.once("ready", function (e) { + if (e.errorCount > 0) { + rej("Failed to load images."); + } else { + _this._bindTexture(); + + res(); + } + }); + } + }); + }; // 부모 엘리먼트에 canvas 를 붙임 + + + __proto.attachTo = function (parentElement) { + if (!this._hasExternalCanvas) { + this.detach(); + parentElement.appendChild(this.canvas); + } + + this._wrapper = parentElement; + }; + + __proto.forceContextLoss = function () { + if (this.hasRenderingContext()) { + var loseContextExtension = this.context.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + }; // 부모 엘리먼트에서 canvas 를 제거 + + + __proto.detach = function () { + if (!this._hasExternalCanvas && this.canvas.parentElement) { + this.canvas.parentElement.removeChild(this.canvas); + } + }; + + __proto.destroy = function () { + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._animator.stop(); + + this.detach(); + this.forceContextLoss(); + this.off(); + this.canvas.removeEventListener("webglcontextlost", this._onWebglcontextlost); + this.canvas.removeEventListener("webglcontextrestored", this._onWebglcontextrestored); + }; + + __proto.hasRenderingContext = function () { + var ctx = this.context; + + if (!ctx || ctx.isContextLost() || !ctx.getProgramParameter(this.shaderProgram, ctx.LINK_STATUS)) { + return false; + } + + return true; + }; + + __proto.updateFieldOfView = function (fieldOfView) { + this.fieldOfView = fieldOfView; + + this._updateViewport(); + }; + + __proto.updateViewportDimensions = function (width, height) { + var viewPortChanged = false; + this.width = width; + this.height = height; + var w = width * DEVICE_PIXEL_RATIO; + var h = height * DEVICE_PIXEL_RATIO; + + if (w !== this.canvas.width) { + this.canvas.width = w; + viewPortChanged = true; + } + + if (h !== this.canvas.height) { + this.canvas.height = h; + viewPortChanged = true; + } + + if (!viewPortChanged) { + return; + } + + this._updateViewport(); + + this._shouldForceDraw = true; + }; + + __proto.keepUpdate = function (doUpdate) { + if (doUpdate && this.isImageLoaded() === false) { + // Force to draw a frame after image is loaded on render() + this._shouldForceDraw = true; + } + + this._keepUpdate = doUpdate; + }; + + __proto.startRender = function () { + this._animator.setCallback(this._render.bind(this)); + + this._animator.start(); + }; + + __proto.stopRender = function () { + this._animator.stop(); + }; + + __proto.renderWithQuaternion = function (quaternion, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastQuaternion && exactEquals$1(this._lastQuaternion, quaternion) && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // updatefieldOfView only if fieldOfView is changed. + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + this.mvMatrix = fromQuat(create$1(), quaternion); + + this._draw(); + + this._lastQuaternion = clone$1(quaternion); + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + + __proto.renderWithYawPitch = function (yaw, pitch, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastYaw !== null && this._lastYaw === yaw && this._lastPitch !== null && this._lastPitch === pitch && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출 + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + identity(this.mvMatrix); + rotateX(this.mvMatrix, this.mvMatrix, -toRadian(pitch)); + rotateY(this.mvMatrix, this.mvMatrix, -toRadian(yaw)); + + this._draw(); + + this._lastYaw = yaw; + this._lastPitch = pitch; + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + /** + * Returns projection renderer by each type + */ + + + __proto.getProjectionRenderer = function () { + return this._renderer; + }; + /** + * @return Promise + */ + + + __proto.enterVR = function (options) { + var vr = this._vr; + + if (!WEBXR_SUPPORTED && !navigator.getVRDisplays) { + return Promise$1.reject("VR is not available on this browser."); + } + + if (vr && vr.isPresenting()) { + return Promise$1.resolve("VR already enabled."); + } + + return this._requestPresent(options); + }; + + __proto._setImageType = function (imageType) { + var _this = this; + + if (!imageType || this._imageType === imageType) { + return; + } + + this._imageType = imageType; + this._isCubeMap = imageType === ImageType.CUBEMAP; + + if (this._renderer) { + this._renderer.off(); + } + + switch (imageType) { + case ImageType.CUBEMAP: + this._renderer = new CubeRenderer(); + break; + + case ImageType.CUBESTRIP: + this._renderer = new CubeStripRenderer(); + break; + + case ImageType.PANORAMA: + this._renderer = new CylinderRenderer(); + break; + + case ImageType.STEREOSCOPIC_EQUI: + this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat); + break; + + default: + this._renderer = new SphereRenderer(STEREO_FORMAT.NONE); + break; + } + + this._renderer.on(Renderer.EVENTS.ERROR, function (e) { + _this.trigger(new ComponentEvent$1(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.RENDERER_ERROR, + message: e.message + })); + }); + + this._initWebGL(); + }; + + __proto._initCanvas = function (container, canvasClass, width, height) { + var canvasInContainer = container.querySelector("." + canvasClass); + + var canvas = canvasInContainer || this._createCanvas(canvasClass); + + this._hasExternalCanvas = !!canvasInContainer; + canvas.width = width; + canvas.height = height; + this._onWebglcontextlost = this._onWebglcontextlost.bind(this); + this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this); + canvas.addEventListener("webglcontextlost", this._onWebglcontextlost); + canvas.addEventListener("webglcontextrestored", this._onWebglcontextrestored); + return canvas; + }; + + __proto._createCanvas = function (className) { + var canvas = document.createElement("canvas"); + canvas.className = className; + return canvas; + }; + + __proto._setDefaultCanvasStyle = function () { + var canvas = this.canvas; + canvas.style.bottom = "0"; + canvas.style.left = "0"; + canvas.style.right = "0"; + canvas.style.top = "0"; + canvas.style.margin = "auto"; + canvas.style.maxHeight = "100%"; + canvas.style.maxWidth = "100%"; + canvas.style.outline = "none"; + canvas.style.position = "absolute"; + }; + + __proto._onContentError = function () { + this._imageIsReady = false; + this._image = null; + this.trigger(new ComponentEvent$1(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.FAIL_IMAGE_LOAD, + message: "failed to load image" + })); + return false; + }; + + __proto._triggerContentLoad = function () { + this.trigger(new ComponentEvent$1(EVENTS$1.IMAGE_LOADED, { + content: this._image, + isVideo: this._isVideo, + projectionType: this._imageType + })); + }; + + __proto._onContentLoad = function (e) { + if (e.errorCount > 0) return; + this._imageIsReady = true; + + this._triggerContentLoad(); + }; + + __proto._initShaderProgram = function () { + var gl = this.context; + + if (this.shaderProgram) { + gl.deleteProgram(this.shaderProgram); + this.shaderProgram = null; + } + + var renderer = this._renderer; + var vsSource = renderer.getVertexShaderSource(); + var fsSource = renderer.getFragmentShaderSource(); + var vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource); + var fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource); + var shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader); + + if (!shaderProgram) { + throw new Error("Failed to initialize shaders: " + WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())); + } + + gl.useProgram(shaderProgram); + shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); + shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); + shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); + shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); + shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); + shaderProgram.uEye = gl.getUniformLocation(shaderProgram, "uEye"); + gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); + gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); // clear buffer + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); // Use TEXTURE0 + + gl.uniform1i(shaderProgram.samplerUniform, 0); + this.shaderProgram = shaderProgram; + }; + + __proto._onWebglcontextlost = function (e) { + e.preventDefault(); + this.trigger(new ComponentEvent$1(EVENTS$1.RENDERING_CONTEXT_LOST)); + }; + + __proto._onWebglcontextrestored = function () { + this._initWebGL(); + + this.trigger(new ComponentEvent$1(EVENTS$1.RENDERING_CONTEXT_RESTORE)); + }; + + __proto._updateViewport = function () { + perspective(this.pMatrix, toRadian(this.fieldOfView), this.canvas.width / this.canvas.height, 0.1, 100); + this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight); + }; + + __proto._initWebGL = function () { + var gl; // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed. + + try { + this._initRenderingContext(); + + gl = this.context; + this.updateViewportDimensions(this.width, this.height); + + this._initShaderProgram(); + } catch (e) { + this.trigger(new ComponentEvent$1(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.NO_WEBGL, + message: "no webgl support" + })); + this.destroy(); + console.error(e); // eslint-disable-line no-console + + return; + } // 캔버스를 투명으로 채운다. + + + gl.clearColor(0, 0, 0, 0); + var textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D; + + if (this.texture) { + gl.deleteTexture(this.texture); + } + + this.texture = WebGLUtils.createTexture(gl, textureTarget); + + if (this._imageType === ImageType.CUBESTRIP) { + // TODO: Apply following options on other projection type. + gl.enable(gl.CULL_FACE); // gl.enable(gl.DEPTH_TEST); + } + }; + + __proto._initRenderingContext = function () { + if (this.hasRenderingContext()) { + return; + } + + if (!window.WebGLRenderingContext) { + throw new Error("WebGLRenderingContext not available."); + } + + this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes); + + if (!this.context) { + throw new Error("Failed to acquire 3D rendering context"); + } + }; + + __proto._initBuffers = function () { + var image = this._image; + + var vertexPositionData = this._renderer.getVertexPositionData(); + + var indexData = this._renderer.getIndexData(); + + var textureCoordData = this._renderer.getTextureCoordData({ + image: image, + imageConfig: this._imageConfig + }); + + var gl = this.context; + this.vertexBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3, this.shaderProgram.vertexPositionAttribute); + this.indexBuffer = WebGLUtils.initBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1); + this.textureCoordBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2, this.shaderProgram.textureCoordAttribute); + + this._bindBuffers(); + }; + + __proto._bindTexture = function () { + // Detect if it is EAC Format while CUBESTRIP mode. + // We assume it is EAC if image is not 3/2 ratio. + if (this._imageType === ImageType.CUBESTRIP) { + var _a = this._renderer.getDimension(this._image), + width = _a.width, + height = _a.height; + + var isEAC = width && height && width / height !== 1.5 ? 1 : 0; + this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram, "uIsEAC"), isEAC); + } else if (this._imageType === ImageType.PANORAMA) { + var _b = this._renderer.getDimension(this._image), + width = _b.width, + height = _b.height; + + var imageAspectRatio = width && height && width / height; + + this._renderer.updateShaderData({ + imageAspectRatio: imageAspectRatio + }); + } // initialize shader buffers after image is loaded.(by updateShaderData) + // because buffer may be differ by image size.(eg. CylinderRenderer) + + + this._initBuffers(); + + this._renderer.bindTexture(this.context, this.texture, this._image, this._imageConfig); + + this._shouldForceDraw = true; + this.trigger(new ComponentEvent$1(EVENTS$1.BIND_TEXTURE)); + }; + + __proto._updateTexture = function () { + this._renderer.updateTexture(this.context, this._image, this._imageConfig); + }; + + __proto._render = function () { + var yawPitchControl = this._yawPitchControl; + var fov = yawPitchControl.getFov(); + + if (yawPitchControl.shouldRenderWithQuaternion()) { + var quaternion = yawPitchControl.getQuaternion(); + this.renderWithQuaternion(quaternion, fov); + } else { + var yawPitch = yawPitchControl.getYawPitch(); + this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov); + } + }; + + __proto._bindBuffers = function () { + var gl = this.context; + var program = this.shaderProgram; + var vertexBuffer = this.vertexBuffer; + var textureCoordBuffer = this.textureCoordBuffer; + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.enableVertexAttribArray(program.vertexPositionAttribute); + gl.vertexAttribPointer(program.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); + gl.enableVertexAttribArray(program.textureCoordAttribute); + gl.vertexAttribPointer(program.textureCoordAttribute, textureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); + }; + + __proto._draw = function () { + if (this._isVideo && this._keepUpdate) { + this._updateTexture(); + } + + this._renderer.render({ + gl: this.context, + shaderProgram: this.shaderProgram, + indexBuffer: this.indexBuffer, + mvMatrix: this.mvMatrix, + pMatrix: this.pMatrix + }); + }; + + __proto._requestPresent = function (options) { + var _this = this; + + var gl = this.context; + var canvas = this.canvas; + var animator = this._animator; + this._vr = WEBXR_SUPPORTED ? new XRManager(options) : new VRManager(); + var vr = this._vr; + animator.stop(); + return new Promise$1(function (resolve, reject) { + vr.requestPresent(canvas, gl).then(function () { + vr.addEndCallback(_this.exitVR); + animator.setContext(vr.context); + animator.setCallback(_this._onFirstVRFrame); + + if (IS_IOS) { + _this._setWrapperFullscreen(); + } + + _this._shouldForceDraw = true; + animator.start(); + resolve("success"); + }).catch(function (e) { + vr.destroy(); + _this._vr = null; + animator.start(); + reject(e); + }); + }); + }; + + __proto._setWrapperFullscreen = function () { + var wrapper = this._wrapper; + if (!wrapper) return; + this._wrapperOrigStyle = wrapper.getAttribute("style"); + var wrapperStyle = wrapper.style; + wrapperStyle.width = "100vw"; + wrapperStyle.height = "100vh"; + wrapperStyle.position = "fixed"; + wrapperStyle.left = "0"; + wrapperStyle.top = "0"; + wrapperStyle.zIndex = "9999"; + }; + + __proto._restoreStyle = function () { + var wrapper = this._wrapper; + var canvas = this.canvas; + if (!wrapper) return; + + if (this._wrapperOrigStyle) { + wrapper.setAttribute("style", this._wrapperOrigStyle); + } else { + wrapper.removeAttribute("style"); + } + + this._wrapperOrigStyle = null; // Restore canvas style + + canvas.removeAttribute("style"); + + this._setDefaultCanvasStyle(); + }; + + PanoImageRenderer.EVENTS = EVENTS$1; + PanoImageRenderer.ERROR_TYPE = ERROR_TYPE$1; + return PanoImageRenderer; + }(Component); + + /** + * @memberof eg.view360 + * @extends eg.Component + * PanoViewer + */ + + var PanoViewer = + /*#__PURE__*/ + function (_super) { + __extends(PanoViewer, _super); + /** + * @classdesc 360 media viewer + * @ko 360 미디어 뷰어 + * + * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트 + * @param options + * + * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
+ * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다. + * @param {Object} [options.cubemapConfig.order = "RLUDBF"(ProjectionType === CUBEMAP) | "RLUDFB" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서 + * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다. + * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다. + * @param {String} [options.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
+ * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위) + * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위) + * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위) + * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위) + * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위) + * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다 + * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다. + * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키 + * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE}
+ * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위 + * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위 + * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위 + * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
+ * @param {String} [options.canvasClass="view360-canvas"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * + * @example + * ``` + * // PanoViewer Creation + * // create PanoViewer with option + * var PanoViewer = eg.view360.PanoViewer; + * // Area where the image will be displayed(HTMLElement) + * var container = document.getElementById("myPanoViewer"); + * + * var panoViewer = new PanoViewer(container, { + * // If projectionType is not specified, the default is "equirectangular". + * // Specifies an image of the "equirectangular" type. + * image: "/path/to/image/image.jpg" + * }); + * ``` + * + * @example + * ``` + * // Cubemap Config Setting Example + * // For support Youtube EAC projection, You should set cubemapConfig as follows. + * cubemapConfig: { + * order: "LFRDBU", + * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}] + * } + * ``` + */ + + + function PanoViewer(container, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; // Raises the error event if webgl is not supported. + + + if (!WebGLUtils.isWebGLAvailable()) { + setTimeout(function () { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.NO_WEBGL, + message: "no webgl support" + })); + }, 0); + return _this; + } + + if (!WebGLUtils.isStableWebGL()) { + setTimeout(function () { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_DEVICE, + message: "blacklisted browser" + })); + }, 0); + return _this; + } + + if (!!options.image && !!options.video) { + setTimeout(function () { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_RESOURCE, + message: "Specifying multi resouces(both image and video) is not valid." + })); + }, 0); + return _this; + } // Check XR support at not when imported, but when created. + // This is intended to make polyfills easier to use. + + + checkXRSupport(); + _this._container = container; + _this._image = options.image || options.video; + _this._isVideo = !!options.video; + _this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + _this._cubemapConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/ + order: _this._projectionType === PROJECTION_TYPE.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, options.cubemapConfig); + _this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; // If the width and height are not provided, will use the size of the container. + + _this._width = options.width || parseInt(window.getComputedStyle(container).width, 10); + _this._height = options.height || parseInt(window.getComputedStyle(container).height, 10); + /** + * Cache the direction for the performance in renderLoop + * + * This value should be updated by "change" event of YawPitchControl. + */ + + _this._yaw = options.yaw || 0; + _this._pitch = options.pitch || 0; + _this._fov = options.fov || 65; + _this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH; + _this._quaternion = null; + _this._aspectRatio = _this._height !== 0 ? _this._width / _this._height : 1; + _this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS; + var fovRange = options.fovRange || [30, 110]; + var touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ? options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL; + + var yawPitchConfig = __assign(__assign({}, options), { + element: container, + yaw: _this._yaw, + pitch: _this._pitch, + fov: _this._fov, + gyroMode: _this._gyroMode, + fovRange: fovRange, + aspectRatio: _this._aspectRatio, + touchDirection: touchDirection + }); + + _this._isReady = false; + + _this._initYawPitchControl(yawPitchConfig); + + _this._initRenderer(_this._yaw, _this._pitch, _this._fov, _this._projectionType, _this._cubemapConfig); + + return _this; + } + /** + * Check whether the current environment can execute PanoViewer + * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다. + * @return PanoViewer executable PanoViewer 실행가능 여부 + */ + + + var __proto = PanoViewer.prototype; + + PanoViewer.isSupported = function () { + return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL(); + }; + /** + * Check whether the current environment supports the WebGL + * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다. + * @return WebGL support WebGL 지원여부 + */ + + + PanoViewer.isWebGLAvailable = function () { + return WebGLUtils.isWebGLAvailable(); + }; + /** + * Check whether the current environment supports the gyro sensor. + * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다. + * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수 + */ + + + PanoViewer.isGyroSensorAvailable = function (callback) { + if (!DeviceMotionEvent && callback) { + callback(false); + return; + } + + var onDeviceMotionChange; + + var checkGyro = function () { + return new Promise$1(function (res) { + onDeviceMotionChange = function (deviceMotion) { + var isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null); + res(isGyroSensorAvailable); + }; + + window.addEventListener("devicemotion", onDeviceMotionChange); + }); + }; + + var timeout = function () { + return new Promise$1(function (res) { + setTimeout(function () { + return res(false); + }, 1000); + }); + }; + + Promise$1.race([checkGyro(), timeout()]).then(function (isGyroSensorAvailable) { + window.removeEventListener("devicemotion", onDeviceMotionChange); + + if (callback) { + callback(isGyroSensorAvailable); + } + + PanoViewer.isGyroSensorAvailable = function (fb) { + if (fb) { + fb(isGyroSensorAvailable); + } + + return isGyroSensorAvailable; + }; + }); + }; + + PanoViewer._isValidTouchDirection = function (direction) { + return direction === PanoViewer.TOUCH_DIRECTION.NONE || direction === PanoViewer.TOUCH_DIRECTION.YAW || direction === PanoViewer.TOUCH_DIRECTION.PITCH || direction === PanoViewer.TOUCH_DIRECTION.ALL; + }; + /** + * Get the video element that the viewer is currently playing. You can use this for playback. + * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다. + * @return HTMLVideoElementHTMLVideoElement + * @example + * ``` + * var videoTag = panoViewer.getVideo(); + * videoTag.play(); // play the video! + * ``` + */ + + + __proto.getVideo = function () { + if (!this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the video information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정) + * @param {object} param + * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}("equirectangular")] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setVideo("/path/to/video/video.mp4", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR + * }); + * ``` + */ + + + __proto.setVideo = function (video, param) { + if (param === void 0) { + param = {}; + } + + if (video) { + this.setImage(video, { + projectionType: param.projectionType, + isVideo: true, + cubemapConfig: param.cubemapConfig, + stereoFormat: param.stereoFormat + }); + } + + return this; + }; + /** + * Get the image information that the viewer is currently using. + * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다. + * @return Image Object이미지 객체 + * @example + * var imageObj = panoViewer.getImage(); + */ + + + __proto.getImage = function () { + if (this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the image information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.) + * @param {object} param Additional information이미지 추가 정보 + * @param {string} [param.projectionType="equirectangular"] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부 + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setImage("/path/to/image/image.png", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP + * }); + * ``` + */ + + + __proto.setImage = function (image, param) { + if (param === void 0) { + param = {}; + } + + var cubemapConfig = __assign({ + order: "RLUDBF", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, param.cubemapConfig); + + var stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; + var isVideo = !!param.isVideo; + + if (this._image && this._isVideo !== isVideo) { + /* eslint-disable no-console */ + console.warn("PanoViewer is not currently supporting content type changes. (Image <--> Video)"); + /* eslint-enable no-console */ + + return this; + } + + if (image) { + this._deactivate(); + + this._image = image; + this._isVideo = isVideo; + this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + this._cubemapConfig = cubemapConfig; + this._stereoFormat = stereoFormat; + + this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig); + } + + return this; + }; + /** + * Set whether the renderer always updates the texture and renders. + * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다. + * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.keepUpdate = function (doUpdate) { + this._photoSphereRenderer.keepUpdate(doUpdate); + + return this; + }; + /** + * Get the current projection type (equirectangular/cube) + * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다. + * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE} + */ + + + __proto.getProjectionType = function () { + return this._projectionType; + }; + /** + * Activate the device's motion sensor, and return the Promise whether the sensor is enabled + * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element. + * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다. + * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다. + */ + + + __proto.enableSensor = function () { + return new Promise$1(function (resolve, reject) { + if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === "function") { + DeviceMotionEvent.requestPermission().then(function (permissionState) { + if (permissionState === "granted") { + resolve(); + } else { + reject(new Error("permission denied")); + } + }).catch(function (e) { + // This can happen when this method wasn't triggered by user interaction + reject(e); + }); + } else { + resolve(); + } + }); + }; + /** + * Disable the device's motion sensor. + * @ko 디바이스의 모션 센서를 비활성화합니다. + * @deprecated + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.disableSensor = function () { + return this; + }; + /** + * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred). + * This method must be used in the context of user interaction, like onclick callback on the button element. + * It can be rejected when an enabling device sensor fails or image/video is still loading("ready" event not triggered). + * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다) + * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우("ready"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다. + * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요. + * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error) + */ + + + __proto.enterVR = function (options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + if (!this._isReady) { + return Promise$1.reject(new Error("PanoViewer is not ready to show image.")); + } + + return new Promise$1(function (resolve, reject) { + _this.enableSensor().then(function () { + return _this._photoSphereRenderer.enterVR(options); + }).then(function (res) { + return resolve(res); + }).catch(function (e) { + return reject(e); + }); + }); + }; + /** + * Exit VR stereo rendering mode. + * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.exitVR = function () { + this._photoSphereRenderer.exitVR(); + + return this; + }; + /** + * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}. + * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다. + * @param useZoom + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseZoom = function (useZoom) { + if (typeof useZoom === "boolean") { + this._yawPitchControl.option("useZoom", useZoom); + } + + return this; + }; + /** + * When true, enables the keyboard move key control: awsd, arrow keys + * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키) + * @param useKeyboard + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseKeyboard = function (useKeyboard) { + this._yawPitchControl.option("useKeyboard", useKeyboard); + + return this; + }; + /** + * Enables control through device motion. ("none", "yawPitch", "VR") + * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR") + * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE} + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setGyroMode("yawPitch"); + * //equivalent + * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH); + * ``` + */ + + + __proto.setGyroMode = function (gyroMode) { + this._yawPitchControl.option("gyroMode", gyroMode); + + return this; + }; + /** + * Set the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 설정합니다. + * @param range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setFovRange([50, 90]); + */ + + + __proto.setFovRange = function (range) { + this._yawPitchControl.option("fovRange", range); + + return this; + }; + /** + * Get the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 반환합니다. + * @return FOV range + * @example + * var range = panoViewer.getFovRange(); // [50, 90] + */ + + + __proto.getFovRange = function () { + return this._yawPitchControl.option("fovRange"); + }; + /** + * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size. + * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다. + * @param {object} [size] + * @param {number} [size.width=width of the container] + * @param {number} [size.height=height of the container] + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.updateViewportDimensions = function (size) { + if (size === void 0) { + size = {}; + } + + if (!this._isReady) { + return this; + } + + var containerSize; + + if (size.width === undefined || size.height === undefined) { + containerSize = window.getComputedStyle(this._container); + } + + var width = size.width || parseInt(containerSize.width, 10); + var height = size.height || parseInt(containerSize.height, 10); // Skip if viewport is not changed. + + if (width === this._width && height === this._height) { + return this; + } + + this._width = width; + this._height = height; + this._aspectRatio = width / height; + + this._photoSphereRenderer.updateViewportDimensions(width, height); + + this._yawPitchControl.option("aspectRatio", this._aspectRatio); + + this._yawPitchControl.updatePanScale({ + height: height + }); + + this.lookAt({}, 0); + return this; + }; + /** + * Get the current field of view(FOV) + * @ko 현재 field of view(FOV) 값을 반환합니다. + */ + + + __proto.getFov = function () { + return this._fov; + }; + /** + * Get current yaw value + * @ko 현재 yaw 값을 반환합니다. + */ + + + __proto.getYaw = function () { + return this._yaw; + }; + /** + * Get current pitch value + * @ko 현재 pitch 값을 반환합니다. + */ + + + __proto.getPitch = function () { + return this._pitch; + }; + /** + * Get the range of controllable Yaw values + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + */ + + + __proto.getYawRange = function () { + return this._yawPitchControl.option("yawRange"); + }; + /** + * Get the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다. + */ + + + __proto.getPitchRange = function () { + return this._yawPitchControl.option("pitchRange"); + }; + /** + * Set the range of controllable yaw + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setYawRange([-90, 90]); + */ + + + __proto.setYawRange = function (yawRange) { + this._yawPitchControl.option("yawRange", yawRange); + + return this; + }; + /** + * Set the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 설정합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setPitchRange([-40, 40]); + */ + + + __proto.setPitchRange = function (pitchRange) { + this._yawPitchControl.option("pitchRange", pitchRange); + + return this; + }; + /** + * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed. + * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다. + * @param showPolePoint + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setShowPolePoint = function (showPolePoint) { + this._yawPitchControl.option("showPolePoint", showPolePoint); + + return this; + }; + /** + * Set a new view by setting camera configuration. Any parameters not specified remain the same. + * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다. + * @param {object} orientation + * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위) + * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위) + * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위) + * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초) + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * // Change the yaw angle (absolute angle) to 30 degrees for one second. + * panoViewer.lookAt({yaw: 30}, 1000); + * ``` + */ + + + __proto.lookAt = function (orientation, duration) { + if (duration === void 0) { + duration = 0; + } + + if (!this._isReady) { + return this; + } + + var yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw; + var pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch; + + var pitchRange = this._yawPitchControl.option("pitchRange"); + + var verticalAngleOfImage = pitchRange[1] - pitchRange[0]; + var fov = orientation.fov !== undefined ? orientation.fov : this._fov; + + if (verticalAngleOfImage < fov) { + fov = verticalAngleOfImage; + } + + this._yawPitchControl.lookAt({ + yaw: yaw, + pitch: pitch, + fov: fov + }, duration); + + if (duration === 0) { + this._photoSphereRenderer.renderWithYawPitch(yaw, pitch, fov); + } + + return this; + }; + /** + * Set touch direction by which user can control. + * @ko 사용자가 조작가능한 터치 방향을 지정합니다. + * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @return PanoViewer instance + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Limit the touch direction to the yaw direction only. + * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW); + * ``` + */ + + + __proto.setTouchDirection = function (direction) { + if (PanoViewer._isValidTouchDirection(direction)) { + this._yawPitchControl.option("touchDirection", direction); + } + + return this; + }; + /** + * Returns touch direction by which user can control + * @ko 사용자가 조작가능한 터치 방향을 반환한다. + * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Returns the current touch direction. + * var dir = panoViewer.getTouchDirection(); + * ``` + */ + + + __proto.getTouchDirection = function () { + return this._yawPitchControl.option("touchDirection"); + }; + /** + * Destroy viewer. Remove all registered event listeners and remove viewer canvas. + * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.destroy = function () { + this._deactivate(); + + if (this._yawPitchControl) { + this._yawPitchControl.destroy(); + + this._yawPitchControl = null; + } + + return this; + }; // TODO: Remove parameters as they're just using private values + + + __proto._initRenderer = function (yaw, pitch, fov, projectionType, cubemapConfig) { + var _this = this; + + this._photoSphereRenderer = new PanoImageRenderer(this._image, this._width, this._height, this._isVideo, this._container, this._canvasClass, { + initialYaw: yaw, + initialPitch: pitch, + fieldOfView: fov, + imageType: projectionType, + cubemapConfig: cubemapConfig, + stereoFormat: this._stereoFormat + }); + + this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl); + + this._bindRendererHandler(); + + this._photoSphereRenderer.bindTexture().then(function () { + return _this._activate(); + }).catch(function () { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.FAIL_BIND_TEXTURE, + message: "failed to bind texture" + })); + }); + }; + /** + * @private + * update values of YawPitchControl if needed. + * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image. + * + * This function should be called after isReady status is true. + */ + + + __proto._updateYawPitchIfNeeded = function () { + if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) { + // update fov by aspect ratio + var image = this._photoSphereRenderer.getContent(); + + var imageAspectRatio = image.naturalWidth / image.naturalHeight; + var yawSize = void 0; + var maxFov = void 0; // If height is larger than width, then we assume it's rotated by 90 degree. + + if (imageAspectRatio < 1) { + // So inverse the aspect ratio. + imageAspectRatio = 1 / imageAspectRatio; + } + + if (imageAspectRatio < 6) { + yawSize = util.toDegree(imageAspectRatio); // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5 + + maxFov = util.toDegree(Math.atan(0.5)) * 2; + } else { + yawSize = 360; + maxFov = 360 / imageAspectRatio; // Make it 5 fixed as axes does. + } // console.log("_updateYawPitchIfNeeded", maxFov, "aspectRatio", image.naturalWidth, image.naturalHeight, "yawSize", yawSize); + + + var minFov = this._yawPitchControl.option("fovRange")[0]; // this option should be called after fov is set. + + + this._yawPitchControl.option({ + "fov": maxFov, + "yawRange": [-yawSize / 2, yawSize / 2], + "pitchRange": [-maxFov / 2, maxFov / 2], + "fovRange": [minFov, maxFov] + }); + + this.lookAt({ + fov: maxFov + }); + } + }; + + __proto._bindRendererHandler = function () { + var _this = this; + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.ERROR, function (e) { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, e)); + }); + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, function () { + _this._deactivate(); + + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.RENDERING_CONTEXT_LOST, + message: "webgl rendering context lost" + })); + }); + }; + + __proto._initYawPitchControl = function (yawPitchConfig) { + var _this = this; + + this._yawPitchControl = new YawPitchControl(yawPitchConfig); + + this._yawPitchControl.on(PANOVIEWER_EVENTS.ANIMATION_END, function (e) { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ANIMATION_END, e)); + }); + + this._yawPitchControl.on("change", function (e) { + _this._yaw = e.yaw; + _this._pitch = e.pitch; + _this._fov = e.fov; + _this._quaternion = e.quaternion; + + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.VIEW_CHANGE, { + yaw: e.yaw, + pitch: e.pitch, + fov: e.fov, + quaternion: e.quaternion, + isTrusted: e.isTrusted + })); + }); + }; + + __proto._activate = function () { + this._photoSphereRenderer.attachTo(this._container); + + this._yawPitchControl.enable(); + + this.updateViewportDimensions(); + this._isReady = true; // update yawPitchControl after isReady status is true. + + this._updateYawPitchIfNeeded(); + + this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.READY)); + + this._photoSphereRenderer.startRender(); + }; + /** + * Destroy webgl context and block user interaction and stop rendering + */ + + + __proto._deactivate = function () { + // Turn off the video if it has one + var video = this.getVideo(); + + if (video) { + video.pause(); + } + + if (this._isReady) { + this._photoSphereRenderer.stopRender(); + + this._yawPitchControl.disable(); + + this._isReady = false; + } + + if (this._photoSphereRenderer) { + this._photoSphereRenderer.destroy(); + + this._photoSphereRenderer = null; + } + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @type {String} + * @example + * eg.view360.PanoViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.PanoViewer + */ + + + PanoViewer.VERSION = VERSION; + PanoViewer.ERROR_TYPE = ERROR_TYPE; + PanoViewer.EVENTS = PANOVIEWER_EVENTS; + PanoViewer.PROJECTION_TYPE = PROJECTION_TYPE; + PanoViewer.GYRO_MODE = GYRO_MODE; // This should be deprecated! + // eslint-disable-next-line @typescript-eslint/naming-convention + + PanoViewer.ProjectionType = PROJECTION_TYPE; + PanoViewer.STEREO_FORMAT = STEREO_FORMAT; + /** + * Constant value for touch directions + * @ko 터치 방향에 대한 상수 값. + * @namespace + * @name TOUCH_DIRECTION + */ + + PanoViewer.TOUCH_DIRECTION = { + /** + * Constant value for none direction. + * @ko none 방향에 대한 상수 값. + * @name NONE + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 1 + */ + NONE: YawPitchControl.TOUCH_DIRECTION_NONE, + + /** + * Constant value for horizontal(yaw) direction. + * @ko horizontal(yaw) 방향에 대한 상수 값. + * @name YAW + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 6 + */ + YAW: YawPitchControl.TOUCH_DIRECTION_YAW, + + /** + * Constant value for vertical direction. + * @ko vertical(pitch) 방향에 대한 상수 값. + * @name PITCH + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 24 + */ + PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH, + + /** + * Constant value for all direction. + * @ko all 방향에 대한 상수 값. + * @name ALL + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 30 + */ + ALL: YawPitchControl.TOUCH_DIRECTION_ALL + }; + return PanoViewer; + }(Component); + + /* eslint-disable @typescript-eslint/naming-convention */ + var PanoViewerModule = { + PanoViewer: PanoViewer, + VERSION: VERSION + }; + merge(PanoViewerModule, Constants); + + return PanoViewerModule; + +}))); +//# sourceMappingURL=view360.panoviewer.pkgd.js.map diff --git a/dist/PanoViewer/view360.panoviewer.pkgd.js.map b/dist/PanoViewer/view360.panoviewer.pkgd.js.map new file mode 100644 index 000000000..efa3d8a60 --- /dev/null +++ b/dist/PanoViewer/view360.panoviewer.pkgd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.panoviewer.pkgd.js","sources":["../../src/version.ts","../../src/utils/utils.ts","../../src/utils/browser.ts","../../src/utils/browserFeature.ts","../../src/utils/math-util.ts","../../src/YawPitchControl/utils.ts","../../src/YawPitchControl/consts.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/math-util.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/util.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/pose-predictor.ts","../../src/YawPitchControl/input/DeviceMotion.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/sensor-sample.ts","../../src/YawPitchControl/input/lib/webvr-polyfill/complementary-filter.ts","../../src/YawPitchControl/input/ComplementaryFilter.ts","../../src/YawPitchControl/input/FusionPoseSensor.ts","../../src/YawPitchControl/input/TiltMotionInput.ts","../../src/YawPitchControl/ScreenRotationAngle.ts","../../src/YawPitchControl/input/RotationPanInput.ts","../../src/YawPitchControl/DeviceQuaternion.ts","../../src/YawPitchControl/YawPitchControl.ts","../../src/PanoViewer/consts.ts","../../src/PanoImageRenderer/WebGLUtils.ts","../../src/PanoImageRenderer/renderer/Renderer.ts","../../src/PanoImageRenderer/renderer/CubeRenderer.ts","../../src/PanoImageRenderer/renderer/CubeStripRenderer.ts","../../src/PanoImageRenderer/renderer/SphereRenderer.ts","../../src/PanoImageRenderer/renderer/CylinderRenderer.ts","../../src/PanoImageRenderer/vr/VRManager.ts","../../src/PanoImageRenderer/vr/XRManager.ts","../../src/PanoImageRenderer/WebGLAnimator.ts","../../src/PanoImageRenderer/PanoImageRenderer.ts","../../src/PanoViewer/PanoViewer.ts","../../src/PanoViewer/index.umd.ts"],"sourcesContent":["const VERSION = \"#__VERSION__#\";\n\nexport {\n VERSION\n};\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","/**\n * Original Code\n * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js\n * Math Util\n * modified by egjs\n */\n/**\n * @fileoverview gl-matrix - High performance matrix and vector operations\n * @author Brandon Jones\n * @author Colin MacKenzie IV\n * @version 2.3.2\n */\n\n/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE. */\n\n// Some minimal math functionality borrowed from gl-Matrix and stripped down\n// for the purposes of this library.\n\nimport { vec2, vec3, quat } from \"gl-matrix\";\n\nimport { ValueOf } from \"../types/internal\";\n\nconst quatToVec3 = (quaternion: quat) => {\n const baseV = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(baseV, baseV, quaternion);\n return baseV;\n};\n\nconst toDegree = (a: number) => a * 180 / Math.PI;\n\nconst util: any = {};\n\nutil.isPowerOfTwo = (n: number) => n && (n & (n - 1)) === 0;\n\nutil.extractPitchFromQuat = (quaternion: quat) => {\n const baseV = quatToVec3(quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n};\n\nutil.hypot = Math.hypot || ((x: number, y: number) => Math.sqrt(x * x + y * y));\n\n// implement reference\n// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식\n// calculating angle between two vectors : http://darkpgmr.tistory.com/121\nconst ROTATE_CONSTANT: {\n PITCH_DELTA: 1;\n YAW_DELTA_BY_ROLL: 2;\n YAW_DELTA_BY_YAW: 3;\n} = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n};\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nconst getRotationDelta = (prevQ: quat, curQ: quat, rotateKind: ValueOf) => {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n // const coefficientD = -1 * vec3.dot(vecN, meshPoint1);\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance =\n coefficientA * crossVec[0] +\n coefficientB * crossVec[1] +\n coefficientC * crossVec[2];\n\n let thetaDirection;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return toDegree(deltaRadian);\n};\n\nconst angleBetweenVec2 = (v1: vec2, v2: vec2) => {\n const det = v1[0] * v2[1] - v2[0] * v1[1];\n const theta = -Math.atan2(det, vec2.dot(v1, v2));\n return theta;\n};\n\nutil.yawOffsetBetween = (viewDir: number, targetDir: number) => {\n const viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]);\n const targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]);\n\n vec2.normalize(viewDirXZ, viewDirXZ);\n vec2.normalize(targetDirXZ, targetDirXZ);\n\n const theta = -angleBetweenVec2(viewDirXZ, targetDirXZ);\n\n return theta;\n};\n\nutil.sign = (x: number) => Math.sign\n ? Math.sign(x)\n : (Number(x > 0) - Number(x < 0)) || +x;\n\nutil.toDegree = toDegree;\nutil.getRotationDelta = getRotationDelta;\nutil.angleBetweenVec2 = angleBetweenVec2;\n\nexport {\n util,\n ROTATE_CONSTANT\n};\n","import { quat } from \"gl-matrix\";\n\nimport {\n util as mathUtil,\n ROTATE_CONSTANT\n} from \"../utils/math-util\";\n\nexport const toAxis = (source, offset) => offset.reduce((acc, v, i) => {\n if (source[i]) {\n acc[source[i]] = v;\n }\n return acc;\n}, {});\n\nexport const getDeltaYaw = (prvQ: quat, curQ: quat) => {\n const yawDeltaByYaw = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(mathUtil.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nexport const getDeltaPitch = (prvQ: quat, curQ: quat) => {\n const pitchDelta = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n","import { userAgent } from \"../utils/browserFeature\";\n/**\n * Returns a number value indiciating the version of Chrome being used,\n * or otherwise `null` if not on Chrome.\n *\n * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19\n */\n/**\n * In Chrome m65, `devicemotion` events are broken but subsequently fixed\n * in 65.0.3325.148. Since many browsers use Chromium, ensure that\n * we scope this detection by branch and build numbers to provide\n * a proper fallback.\n * https://github.com/immersive-web/webvr-polyfill/issues/307\n */\nlet version = -1; // It should not be null because it will be compared with number\nlet branch: string | null = null;\nlet build: string | null = null;\n\nconst match = /Chrome\\/([0-9]+)\\.(?:[0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(userAgent);\n\nif (match) {\n version = parseInt(match[1], 10);\n branch = match[2];\n build = match[3];\n}\n\nconst CHROME_VERSION = version;\nconst IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === \"3325\" && parseInt(build!, 10) < 148;\nconst IS_ANDROID = /Android/i.test(userAgent);\n\nconst CONTROL_MODE_VR = 1;\nconst CONTROL_MODE_YAWPITCH = 2;\n\nconst TOUCH_DIRECTION_NONE = 1;\nconst TOUCH_DIRECTION_YAW = 2;\nconst TOUCH_DIRECTION_PITCH = 4;\nconst TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH;\n\n/* Const for MovableCoord */\nconst MC_DECELERATION = 0.0014;\nconst MC_MAXIMUM_DURATION = 1000;\nconst MC_BIND_SCALE = [0.20, 0.20];\n\nconst MIN_FIELD_OF_VIEW = 20;\nconst MAX_FIELD_OF_VIEW = 110;\nconst PAN_SCALE = 320;\n\n// const DELTA_THRESHOLD = 0.015;\n// const DELTA_THRESHOLD = 0.09; // Note4\n// const DELTA_THRESHOLD = 0.0825;\n// const DELTA_THRESHOLD = 0.075;\n// const DELTA_THRESHOLD = 0.06;\n// const DELTA_THRESHOLD = 0.045;\nconst DELTA_THRESHOLD = 0.0375; // Note2\n\nconst YAW_RANGE_HALF = 180;\nconst PITCH_RANGE_HALF = 90;\nconst CIRCULAR_PITCH_RANGE_HALF = 180;\nconst PINCH_EVENTS = \"pinchstart pinchmove pinchend\";\n\nconst KEYMAP = {\n LEFT_ARROW: 37,\n A: 65,\n UP_ARROW: 38,\n W: 87,\n RIGHT_ARROW: 39,\n D: 68,\n DOWN_ARROW: 40,\n S: 83\n};\n\nconst GYRO_MODE: {\n NONE: \"none\";\n YAWPITCH: \"yawPitch\";\n VR: \"VR\";\n} = {\n NONE: \"none\",\n YAWPITCH: \"yawPitch\",\n VR: \"VR\"\n};\n\nexport {\n GYRO_MODE,\n\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n\n TOUCH_DIRECTION_NONE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MIN_FIELD_OF_VIEW,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n DELTA_THRESHOLD,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n PINCH_EVENTS,\n KEYMAP,\n\n CHROME_VERSION,\n IS_CHROME_WITHOUT_DEVICE_MOTION,\n IS_ANDROID\n};\n","/* eslint-disable */\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { window as win } from \"../../../../utils/browser\";\n\nconst MathUtil = win.MathUtil || {};\n\nMathUtil.degToRad = Math.PI / 180;\nMathUtil.radToDeg = 180 / Math.PI;\n\n// Some minimal math functionality borrowed from THREE.Math and stripped down\n// for the purposes of this library.\n\n\nMathUtil.Vector2 = function( x, y ) {\n this.x = x || 0;\n this.y = y || 0;\n};\n\nMathUtil.Vector2.prototype = {\n constructor: MathUtil.Vector2,\n\n set: function( x, y ) {\n this.x = x;\n this.y = y;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n },\n\n subVectors: function( a, b ) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n\n return this;\n }\n};\n\nMathUtil.Vector3 = function( x, y, z ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n};\n\nMathUtil.Vector3.prototype = {\n constructor: MathUtil.Vector3,\n\n set: function( x, y, z ) {\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n\n return this;\n },\n\n length: function() {\n return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n },\n\n normalize: function() {\n const scalar = this.length();\n\n if ( scalar !== 0 ) {\n const invScalar = 1 / scalar;\n\n this.multiplyScalar(invScalar);\n } else {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n }\n\n return this;\n },\n\n multiplyScalar: function( scalar ) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n },\n\n applyQuaternion: function( q ) {\n const x = this.x;\n const y = this.y;\n const z = this.z;\n\n const qx = q.x;\n const qy = q.y;\n const qz = q.z;\n const qw = q.w;\n\n // calculate quat * vector\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = - qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n return this;\n },\n\n dot: function( v ) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n },\n\n crossVectors: function( a, b ) {\n const ax = a.x;\n const ay = a.y;\n const az = a.z;\n const bx = b.x;\n const by = b.y;\n const bz = b.z;\n\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n\n return this;\n }\n};\n\nMathUtil.Quaternion = function( x, y, z, w ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n this.w = ( w !== undefined ) ? w : 1;\n};\n\nMathUtil.Quaternion.prototype = {\n constructor: MathUtil.Quaternion,\n\n set: function( x, y, z, w ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n\n return this;\n },\n\n copy: function( quaternion ) {\n this.x = quaternion.x;\n this.y = quaternion.y;\n this.z = quaternion.z;\n this.w = quaternion.w;\n\n return this;\n },\n\n setFromEulerXYZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 + s1 * s2 * c3;\n this.w = c1 * c2 * c3 - s1 * s2 * s3;\n\n return this;\n },\n\n setFromEulerYXZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 - s1 * s2 * c3;\n this.w = c1 * c2 * c3 + s1 * s2 * s3;\n\n return this;\n },\n\n setFromAxisAngle: function( axis, angle ) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n // assumes axis is normalized\n\n const halfAngle = angle / 2;\n const s = Math.sin( halfAngle );\n\n this.x = axis.x * s;\n this.y = axis.y * s;\n this.z = axis.z * s;\n this.w = Math.cos( halfAngle );\n\n return this;\n },\n\n multiply: function( q ) {\n return this.multiplyQuaternions( this, q );\n },\n\n multiplyQuaternions: function( a, b ) {\n // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n const qax = a.x;\n const qay = a.y;\n const qaz = a.z;\n const qaw = a.w;\n const qbx = b.x;\n const qby = b.y;\n const qbz = b.z;\n const qbw = b.w;\n\n this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n return this;\n },\n\n inverse: function() {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n\n this.normalize();\n\n return this;\n },\n\n normalize: function() {\n let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n if ( l === 0 ) {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n this.w = 1;\n } else {\n l = 1 / l;\n\n this.x = this.x * l;\n this.y = this.y * l;\n this.z = this.z * l;\n this.w = this.w * l;\n }\n\n return this;\n },\n\n slerp: function( qb, t ) {\n if ( t === 0 ) return this;\n if ( t === 1 ) return this.copy( qb );\n\n const x = this.x;\n const y = this.y;\n const z = this.z;\n const w = this.w;\n\n // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n let cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;\n\n if ( cosHalfTheta < 0 ) {\n this.w = - qb.w;\n this.x = - qb.x;\n this.y = - qb.y;\n this.z = - qb.z;\n\n cosHalfTheta = - cosHalfTheta;\n } else {\n this.copy( qb );\n }\n\n if ( cosHalfTheta >= 1.0 ) {\n this.w = w;\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n }\n\n const halfTheta = Math.acos( cosHalfTheta );\n const sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n if ( Math.abs( sinHalfTheta ) < 0.001 ) {\n this.w = 0.5 * ( w + this.w );\n this.x = 0.5 * ( x + this.x );\n this.y = 0.5 * ( y + this.y );\n this.z = 0.5 * ( z + this.z );\n\n return this;\n }\n\n const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;\n const ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n this.w = ( w * ratioA + this.w * ratioB );\n this.x = ( x * ratioA + this.x * ratioB );\n this.y = ( y * ratioA + this.y * ratioB );\n this.z = ( z * ratioA + this.z * ratioB );\n\n return this;\n },\n\n setFromUnitVectors: function() {\n // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n // assumes direction vectors vFrom and vTo are normalized\n\n let v1;\n let r;\n const EPS = 0.000001;\n\n return function( vFrom, vTo ) {\n if ( v1 === undefined ) v1 = new MathUtil.Vector3();\n\n r = vFrom.dot( vTo ) + 1;\n\n if ( r < EPS ) {\n r = 0;\n\n if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n v1.set( - vFrom.y, vFrom.x, 0 );\n } else {\n v1.set( 0, - vFrom.z, vFrom.y );\n }\n } else {\n v1.crossVectors( vFrom, vTo );\n }\n\n this.x = v1.x;\n this.y = v1.y;\n this.z = v1.z;\n this.w = r;\n\n this.normalize();\n\n return this;\n };\n }()\n};\n\nexport default MathUtil;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tslint:disable: only-arrow-functions\n\nimport { window as win, document as doc, navigator as nav } from \"../../../../utils/browser\";\n\nconst userAgent = nav?.userAgent ?? \"\";\nconst Util = (win ).Util || {};\n\nUtil.MIN_TIMESTEP = 0.001;\nUtil.MAX_TIMESTEP = 1;\n\nUtil.base64 = function(mimeType, base64) {\n return \"data:\" + mimeType + \";base64,\" + base64;\n};\n\nUtil.clamp = function(value, min, max) {\n return Math.min(Math.max(min, value), max);\n};\n\nUtil.lerp = function(a, b, t) {\n return a + ((b - a) * t);\n};\n\nUtil.isIOS = (function() {\n const isIOS = /iPad|iPhone|iPod/.test(nav?.platform);\n return function() {\n return isIOS;\n };\n})();\n\nUtil.isWebViewAndroid = (function() {\n const isWebViewAndroid = userAgent.indexOf(\"Version\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1 &&\n userAgent.indexOf(\"Chrome\") !== -1;\n return function() {\n return isWebViewAndroid;\n };\n})();\n\nUtil.isSafari = (function() {\n const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n return function() {\n return isSafari;\n };\n})();\n\nUtil.isFirefoxAndroid = (function() {\n const isFirefoxAndroid = userAgent.indexOf(\"Firefox\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1;\n return function() {\n return isFirefoxAndroid;\n };\n})();\n\nUtil.isR7 = (function() {\n const isR7 = userAgent.indexOf(\"R7 Build\") !== -1;\n return function() {\n return isR7;\n };\n})();\n\nUtil.isLandscapeMode = function() {\n const rtn = (win.orientation === 90 || win.orientation === -90);\n return Util.isR7() ? !rtn : rtn;\n};\n\n// Helper method to validate the time steps of sensor timestamps.\nUtil.isTimestampDeltaValid = function(timestampDeltaS) {\n if (isNaN(timestampDeltaS)) {\n return false;\n }\n if (timestampDeltaS <= Util.MIN_TIMESTEP) {\n return false;\n }\n if (timestampDeltaS > Util.MAX_TIMESTEP) {\n return false;\n }\n return true;\n};\n\nUtil.getScreenWidth = function() {\n return Math.max(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.getScreenHeight = function() {\n return Math.min(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.requestFullscreen = function(element) {\n if (Util.isWebViewAndroid()) {\n return false;\n }\n if (element.requestFullscreen) {\n element.requestFullscreen();\n } else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n } else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n } else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.exitFullscreen = function() {\n if (doc.exitFullscreen) {\n doc.exitFullscreen();\n } else if (doc.webkitExitFullscreen) {\n doc.webkitExitFullscreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.getFullscreenElement = function() {\n return doc.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n};\n\nUtil.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {\n // No error checking for brevity.\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n const program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n\n for (const attribName in attribLocationMap)\n gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);\n\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n};\n\nUtil.getProgramUniforms = function(gl, program) {\n const uniforms = {};\n const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n let uniformName = \"\";\n for (let i = 0; i < uniformCount; i++) {\n const uniformInfo = gl.getActiveUniform(program, i);\n uniformName = uniformInfo.name.replace(\"[0]\", \"\");\n uniforms[uniformName] = gl.getUniformLocation(program, uniformName);\n }\n return uniforms;\n};\n\nUtil.orthoMatrix = function(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right);\n const bt = 1 / (bottom - top);\n const nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n};\n\nUtil.copyArray = function(source, dest) {\n for (let i = 0, n = source.length; i < n; i++) {\n dest[i] = source[i];\n }\n};\n\nUtil.isMobile = function() {\n let check = false;\n (function(a) {\n if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))check = true;\n })(userAgent || nav?.vendor || win.opera);\n return check;\n};\n\nUtil.extend = function(dest, src) {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n dest[key] = src[key];\n }\n }\n\n return dest;\n};\n\nUtil.safariCssSizeWorkaround = function(canvas) {\n // TODO(smus): Remove this workaround when Safari for iOS is fixed.\n // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).\n //\n // \"To the last I grapple with thee;\n // from hell's heart I stab at thee;\n // for hate's sake I spit my last breath at thee.\"\n // -- Moby Dick, by Herman Melville\n if (Util.isIOS()) {\n const width = canvas.style.width;\n const height = canvas.style.height;\n canvas.style.width = (parseInt(width) + 1) + \"px\";\n canvas.style.height = (parseInt(height)) + \"px\";\n setTimeout(function() {\n canvas.style.width = width;\n canvas.style.height = height;\n }, 100);\n }\n\n // Debug only.\n win.Util = Util;\n win.canvas = canvas;\n};\n\nUtil.isDebug = function() {\n return Util.getQueryParameter(\"debug\");\n};\n\nUtil.getQueryParameter = function(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n const results = regex.exec(location.search);\n return results === null ? \"\" : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n};\n\nUtil.frameDataFromPose = (function() {\n const piOver180 = Math.PI / 180.0;\n const rad45 = Math.PI * 0.25;\n\n // Borrowed from glMatrix.\n function mat4_perspectiveFromFieldOfView(out, fov, near, far) {\n const upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45);\n const downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45);\n const leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45);\n const rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45);\n const xScale = 2.0 / (leftTan + rightTan);\n const yScale = 2.0 / (upTan + downTan);\n\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = ((upTan - downTan) * yScale * 0.5);\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = (far * near) / (near - far);\n out[15] = 0.0;\n return out;\n }\n\n function mat4_fromRotationTranslation(out, q, v) {\n // Quaternion math\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n\n return out;\n }\n\n function mat4_translate(out, a, v) {\n const x = v[0];\n const y = v[1];\n const z = v[2];\n let a00;\n let a01;\n let a02;\n let a03;\n let a10;\n let a11;\n let a12;\n let a13;\n let a20;\n let a21;\n let a22;\n let a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];\n a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];\n a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];\n\n out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;\n out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;\n out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;\n\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n }\n\n function mat4_invert(out, a) {\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n }\n\n const defaultOrientation = new Float32Array([0, 0, 0, 1]);\n const defaultPosition = new Float32Array([0, 0, 0]);\n\n function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {\n mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);\n\n const orientation = pose.orientation || defaultOrientation;\n const position = pose.position || defaultPosition;\n\n mat4_fromRotationTranslation(view, orientation, position);\n if (parameters)\n mat4_translate(view, view, parameters.offset);\n mat4_invert(view, view);\n }\n\n return function(frameData, pose, vrDisplay) {\n if (!frameData || !pose)\n return false;\n\n frameData.pose = pose;\n frameData.timestamp = pose.timestamp;\n\n updateEyeMatrices(\n frameData.leftProjectionMatrix, frameData.leftViewMatrix,\n pose, vrDisplay.getEyeParameters(\"left\"), vrDisplay);\n updateEyeMatrices(\n frameData.rightProjectionMatrix, frameData.rightViewMatrix,\n pose, vrDisplay.getEyeParameters(\"right\"), vrDisplay);\n\n return true;\n };\n})();\n\nUtil.isInsideCrossDomainIFrame = function() {\n const isFramed = (win.self !== win.top);\n const refDomain = Util.getDomainFromUrl(doc.referrer);\n const thisDomain = Util.getDomainFromUrl(win.location.href);\n\n return isFramed && (refDomain !== thisDomain);\n};\n\n// From http://stackoverflow.com/a/23945027.\nUtil.getDomainFromUrl = function(url) {\n let domain;\n // Find & remove protocol (http, ftp, etc.) and get domain.\n if (url.indexOf(\"://\") > -1) {\n domain = url.split(\"/\")[2];\n } else {\n domain = url.split(\"/\")[0];\n }\n\n // find & remove port number\n domain = domain.split(\":\")[0];\n\n return domain;\n};\n\nexport default Util;\n","/* eslint-disable */\n\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * Given an orientation and the gyroscope data, predicts the future orientation\n * of the head. This makes rendering appear faster.\n *\n * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf\n * @param {Number} predictionTimeS time from head movement to the appearance of\n * the corresponding image.\n */\nclass PosePredictor {\n public predictionTimeS;\n public previousQ;\n public previousTimestampS;\n public deltaQ;\n public outQ;\n\n public constructor(predictionTimeS) {\n this.predictionTimeS = predictionTimeS;\n\n // The quaternion corresponding to the previous state.\n this.previousQ = new MathUtil.Quaternion();\n // Previous time a prediction occurred.\n this.previousTimestampS = null;\n\n // The delta quaternion that adjusts the current pose.\n this.deltaQ = new MathUtil.Quaternion();\n // The output quaternion.\n this.outQ = new MathUtil.Quaternion();\n }\n\n public getPrediction(currentQ, gyro, timestampS) {\n if (!this.previousTimestampS) {\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n return currentQ;\n }\n\n // Calculate axis and angle based on gyroscope rotation rate data.\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n\n const angularSpeed = gyro.length();\n\n // If we're rotating slowly, don't do prediction.\n if (angularSpeed < MathUtil.degToRad * 20) {\n if (Util.isDebug()) {\n console.log(\"Moving slowly, at %s deg/s: no prediction\",\n (MathUtil.radToDeg * angularSpeed).toFixed(1));\n }\n this.outQ.copy(currentQ);\n this.previousQ.copy(currentQ);\n return this.outQ;\n }\n\n // Get the predicted angle based on the time delta and latency.\n const deltaT = timestampS - this.previousTimestampS;\n const predictAngle = angularSpeed * this.predictionTimeS;\n\n this.deltaQ.setFromAxisAngle(axis, predictAngle);\n this.outQ.copy(this.previousQ);\n this.outQ.multiply(this.deltaQ);\n\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n\n return this.outQ;\n }\n}\n\nexport default PosePredictor;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3 } from \"gl-matrix\";\n\nimport { Mutable } from \"../../types/internal\";\nimport { window } from \"../../utils/browser\";\nimport { IS_CHROME_WITHOUT_DEVICE_MOTION, IS_ANDROID } from \"../consts\";\n\nconst STILLNESS_THRESHOLD = 200; // millisecond\n\nexport default class DeviceMotion extends Component<{\n devicemotion: {\n inputEvent: DeviceMotionEvent | {\n deviceorientation: {\n alpha: number;\n beta: number;\n gamma: number;\n };\n };\n };\n}> {\n public readonly isWithoutDeviceMotion: boolean;\n public readonly isAndroid: boolean;\n\n public stillGyroVec: vec3;\n public rawGyroVec: vec3;\n public adjustedGyroVec: vec3;\n public lastDevicemotionTimestamp: number;\n\n private _timer: number;\n private _isEnabled: boolean;\n\n public constructor() {\n super();\n this._onDeviceMotion = this._onDeviceMotion.bind(this);\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onChromeWithoutDeviceMotion = this._onChromeWithoutDeviceMotion.bind(this);\n\n this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION;\n this.isAndroid = IS_ANDROID;\n\n this.stillGyroVec = vec3.create();\n this.rawGyroVec = vec3.create();\n this.adjustedGyroVec = vec3.create();\n\n this._timer = -1;\n\n this.lastDevicemotionTimestamp = 0;\n this._isEnabled = false;\n this.enable();\n }\n\n public enable() {\n if (this.isAndroid) {\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n }\n if (this.isWithoutDeviceMotion) {\n window.addEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n } else {\n window.addEventListener(\"devicemotion\", this._onDeviceMotion);\n }\n this._isEnabled = true;\n }\n\n public disable() {\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n window.removeEventListener(\"devicemotion\", this._onDeviceMotion);\n this._isEnabled = false;\n }\n\n private _onChromeWithoutDeviceMotion(e: DeviceOrientationEvent) {\n let {alpha, beta, gamma} = e;\n\n // There is deviceorientation event trigged with empty values\n // on Headless Chrome.\n if (alpha === null) {\n return;\n }\n\n // convert to radian\n alpha = (alpha || 0) * Math.PI / 180;\n beta = (beta || 0) * Math.PI / 180;\n gamma = (gamma || 0) * Math.PI / 180;\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: {\n deviceorientation: {\n alpha,\n beta,\n gamma: -gamma\n }\n }\n }));\n }\n\n private _onDeviceOrientation() {\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timer = window.setTimeout(() => {\n if ((new Date().getTime() - this.lastDevicemotionTimestamp) < STILLNESS_THRESHOLD) {\n vec3.copy(this.stillGyroVec, this.rawGyroVec);\n }\n }, STILLNESS_THRESHOLD);\n }\n\n private _onDeviceMotion(e: DeviceMotionEvent) {\n // desktop chrome triggers devicemotion event with empthy sensor values.\n // Those events should ignored.\n const isGyroSensorAvailable = !(e.rotationRate!.alpha == null);\n const isGravitySensorAvailable = !(e.accelerationIncludingGravity!.x == null);\n\n if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) {\n return;\n }\n\n const devicemotionEvent = {...e} as Mutable;\n\n devicemotionEvent.interval = e.interval;\n devicemotionEvent.timeStamp = e.timeStamp;\n devicemotionEvent.type = e.type;\n devicemotionEvent.rotationRate = {\n alpha: e.rotationRate!.alpha,\n beta: e.rotationRate!.beta,\n gamma: e.rotationRate!.gamma\n };\n devicemotionEvent.accelerationIncludingGravity = {\n x: e.accelerationIncludingGravity!.x,\n y: e.accelerationIncludingGravity!.y,\n z: e.accelerationIncludingGravity!.z\n };\n devicemotionEvent.acceleration = {\n x: e.acceleration!.x,\n y: e.acceleration!.y,\n z: e.acceleration!.z\n };\n\n if (this.isAndroid) {\n vec3.set(\n this.rawGyroVec,\n e.rotationRate!.alpha || 0,\n e.rotationRate!.beta || 0,\n e.rotationRate!.gamma || 0);\n vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec);\n this.lastDevicemotionTimestamp = new Date().getTime();\n\n (devicemotionEvent as any).adjustedRotationRate = {\n alpha: this.adjustedGyroVec[0],\n beta: this.adjustedGyroVec[1],\n gamma: this.adjustedGyroVec[2]};\n }\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: devicemotionEvent\n }));\n }\n}\n","class SensorSample {\n public sample;\n public timestampS;\n\n public constructor(sample?, timestampS?) {\n this.set(sample, timestampS);\n }\n\n public set(sample, timestampS) {\n this.sample = sample;\n this.timestampS = timestampS;\n }\n\n public copy(sensorSample) {\n this.set(sensorSample.sample, sensorSample.timestampS);\n }\n}\n\nexport default SensorSample;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SensorSample from \"./sensor-sample\";\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * An implementation of a simple complementary filter, which fuses gyroscope and\n * accelerometer data from the 'devicemotion' event.\n *\n * Accelerometer data is very noisy, but stable over the long term.\n * Gyroscope data is smooth, but tends to drift over the long term.\n *\n * This fusion is relatively simple:\n * 1. Get orientation estimates from accelerometer by applying a low-pass filter\n * on that data.\n * 2. Get orientation estimates from gyroscope by integrating over time.\n * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the\n * short term.\n */\nclass ComplementaryFilter {\n public kFilter;\n public currentAccelMeasurement;\n public currentGyroMeasurement;\n public previousGyroMeasurement;\n public filterQ;\n public previousFilterQ;\n public accelQ;\n public isOrientationInitialized;\n public estimatedGravity;\n public measuredGravity;\n public gyroIntegralQ;\n\n constructor(kFilter) {\n this.kFilter = kFilter;\n\n // Raw sensor measurements.\n this.currentAccelMeasurement = new SensorSample();\n this.currentGyroMeasurement = new SensorSample();\n this.previousGyroMeasurement = new SensorSample();\n\n // Set default look direction to be in the correct direction.\n if (Util.isIOS()) {\n this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);\n } else {\n this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);\n }\n this.previousFilterQ = new MathUtil.Quaternion();\n this.previousFilterQ.copy(this.filterQ);\n\n // Orientation based on the accelerometer.\n this.accelQ = new MathUtil.Quaternion();\n // Whether or not the orientation has been initialized.\n this.isOrientationInitialized = false;\n // Running estimate of gravity based on the current orientation.\n this.estimatedGravity = new MathUtil.Vector3();\n // Measured gravity based on accelerometer.\n this.measuredGravity = new MathUtil.Vector3();\n\n // Debug only quaternion of gyro-based orientation.\n this.gyroIntegralQ = new MathUtil.Quaternion();\n }\n\n public addAccelMeasurement(vector, timestampS) {\n this.currentAccelMeasurement.set(vector, timestampS);\n }\n\n public addGyroMeasurement = function(vector, timestampS) {\n this.currentGyroMeasurement.set(vector, timestampS);\n\n const deltaT = timestampS - this.previousGyroMeasurement.timestampS;\n if (Util.isTimestampDeltaValid(deltaT)) {\n this.run_();\n }\n\n this.previousGyroMeasurement.copy(this.currentGyroMeasurement);\n };\n\n public getOrientation() {\n return this.filterQ;\n }\n\n public run_() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n if (Util.isDebug()) {\n console.log(\"Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)\",\n MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),\n (this.estimatedGravity.x).toFixed(1),\n (this.estimatedGravity.y).toFixed(1),\n (this.estimatedGravity.z).toFixed(1),\n (this.measuredGravity.x).toFixed(1),\n (this.measuredGravity.y).toFixed(1),\n (this.measuredGravity.z).toFixed(1));\n }\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n }\n\n private accelToQuaternion_(accel) {\n const normAccel = new MathUtil.Vector3();\n normAccel.copy(accel);\n normAccel.normalize();\n const quat = new MathUtil.Quaternion();\n quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);\n quat.inverse();\n return quat;\n }\n\n private gyroToQuaternionDelta_(gyro, dt) {\n // Extract axis and angle from the gyroscope data.\n const quat = new MathUtil.Quaternion();\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n quat.setFromAxisAngle(axis, gyro.length() * dt);\n return quat;\n }\n}\n\nexport default ComplementaryFilter;\n","import MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport ComplementaryFilter from \"./lib/webvr-polyfill/complementary-filter\";\n\nComplementaryFilter.prototype.run_ = function() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n\n if (!this.isFilterQuaternionInitialized) {\n this.isFilterQuaternionInitialized = true;\n }\n};\n\nComplementaryFilter.prototype.getOrientation = function() {\n if (this.isFilterQuaternionInitialized) {\n return this.filterQ;\n } else {\n return null;\n }\n};\n\nexport default ComplementaryFilter;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\n\nimport { window, IS_IOS, IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { CHROME_VERSION } from \"../consts\";\n\nimport PosePredictor from \"./lib/webvr-polyfill/pose-predictor\";\nimport MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport Util from \"./lib/webvr-polyfill/util\";\nimport DeviceMotion from \"./DeviceMotion\";\nimport ComplementaryFilter from \"./ComplementaryFilter\";\n\n\nconst K_FILTER = 0.98;\nconst PREDICTION_TIME_S = 0.040;\n\nexport default class FusionPoseSensor extends Component<{\n change: {\n quaternion: quat;\n };\n}> {\n public deviceMotion: DeviceMotion | null;\n public accelerometer: any;\n public gyroscope: any;\n public filter: ComplementaryFilter;\n public posePredictor: PosePredictor;\n public filterToWorldQ: any;\n public isFirefoxAndroid: boolean;\n public isIOS: boolean;\n public isChromeUsingDegrees: boolean;\n public inverseWorldToScreenQ: any;\n public worldToScreenQ: any;\n public originalPoseAdjustQ: any;\n public resetQ: any;\n public deviceOrientationFixQ: any;\n public predictedQ: any;\n public previousTimestampS: number;\n\n private _isEnabled: boolean;\n private _deviceOrientationQ: any;\n private _prevOrientation: quat;\n private _alpha: number;\n\n public constructor() {\n super();\n\n this.deviceMotion = new DeviceMotion();\n\n this.accelerometer = new MathUtil.Vector3();\n this.gyroscope = new MathUtil.Vector3();\n\n this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);\n this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);\n\n this.filter = new ComplementaryFilter(K_FILTER);\n this.posePredictor = new PosePredictor(PREDICTION_TIME_S);\n\n this.filterToWorldQ = new MathUtil.Quaternion();\n\n this.isFirefoxAndroid = Util.isFirefoxAndroid();\n // This includes iPhone & iPad(both desktop and mobile mode) ref #326\n this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP;\n\n // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18\n this.isChromeUsingDegrees = CHROME_VERSION >= 66;\n\n this._isEnabled = false;\n\n // Set the filter to world transform, depending on OS.\n if (this.isIOS) {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);\n } else {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n this.inverseWorldToScreenQ = new MathUtil.Quaternion();\n this.worldToScreenQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),\n -window.orientation * Math.PI / 180);\n\n this._setScreenTransform();\n // Adjust this filter for being in landscape mode.\n if (Util.isLandscapeMode()) {\n this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);\n }\n\n // Keep track of a reset transform for resetSensor.\n this.resetQ = new MathUtil.Quaternion();\n\n this.deviceMotion.on(\"devicemotion\", this._onDeviceMotionChange);\n this.enable();\n }\n\n public enable() {\n if (this.isEnabled()) {\n return;\n }\n this.deviceMotion!.enable();\n this._isEnabled = true;\n window.addEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public disable() {\n if (!this.isEnabled()) {\n return;\n }\n this.deviceMotion!.disable();\n this._isEnabled = false;\n window.removeEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public isEnabled() {\n return this._isEnabled;\n }\n\n public destroy() {\n this.disable();\n this.deviceMotion = null;\n }\n\n public getOrientation() {\n let orientation;\n\n // Hack around using deviceorientation instead of devicemotion\n if (this.deviceMotion!.isWithoutDeviceMotion && this._deviceOrientationQ) {\n this.deviceOrientationFixQ = this.deviceOrientationFixQ || (() => {\n const y = new MathUtil.Quaternion()\n .setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -this._alpha);\n\n return y;\n })();\n\n orientation = this._deviceOrientationQ;\n const out = new MathUtil.Quaternion();\n\n out.copy(orientation);\n out.multiply(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.worldToScreenQ);\n out.multiplyQuaternions(this.deviceOrientationFixQ, out);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n } else {\n // Convert from filter space to the the same system used by the\n // deviceorientation event.\n orientation = this.filter.getOrientation();\n\n if (!orientation) {\n return null;\n }\n\n const out = this._convertFusionToPredicted(orientation);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n }\n }\n\n private _triggerChange() {\n const orientation = this.getOrientation();\n\n // if orientation is not prepared. don't trigger change event\n if (!orientation) {\n return;\n }\n\n if (!this._prevOrientation) {\n this._prevOrientation = orientation;\n return;\n }\n\n if (quat.equals(this._prevOrientation, orientation)) {\n return;\n }\n\n this.trigger(new ComponentEvent(\"change\", { quaternion: orientation }));\n }\n\n private _convertFusionToPredicted(orientation: quat) {\n // Predict orientation.\n this.predictedQ =\n this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);\n\n // Convert to THREE coordinate system: -Z forward, Y up, X right.\n const out = new MathUtil.Quaternion();\n\n out.copy(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.predictedQ);\n out.multiply(this.worldToScreenQ);\n\n return out;\n }\n\n private _onDeviceMotionChange({ inputEvent }) {\n const deviceorientation = inputEvent.deviceorientation;\n const deviceMotion = inputEvent;\n const accGravity = deviceMotion.accelerationIncludingGravity;\n const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;\n let timestampS = deviceMotion.timeStamp / 1000;\n\n if (deviceorientation) {\n if (!this._alpha) {\n this._alpha = deviceorientation.alpha;\n }\n this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();\n this._deviceOrientationQ.setFromEulerYXZ(\n deviceorientation.beta,\n deviceorientation.alpha,\n deviceorientation.gamma\n );\n\n this._triggerChange();\n } else {\n // Firefox Android timeStamp returns one thousandth of a millisecond.\n if (this.isFirefoxAndroid) {\n timestampS /= 1000;\n }\n\n this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);\n this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);\n\n // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate`\n // is reported in degrees, so we first convert to radians.\n if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) {\n this.gyroscope.multiplyScalar(Math.PI / 180);\n }\n\n this.filter.addAccelMeasurement(this.accelerometer, timestampS);\n this.filter.addGyroMeasurement(this.gyroscope, timestampS);\n\n this._triggerChange();\n\n this.previousTimestampS = timestampS;\n }\n }\n\n private _onScreenOrientationChange() {\n this._setScreenTransform();\n }\n\n private _setScreenTransform() {\n this.worldToScreenQ.set(0, 0, 0, 1);\n\n const orientation = window.orientation;\n\n switch (orientation) {\n case 0:\n break;\n case 90:\n case -90:\n case 180:\n this.worldToScreenQ\n .setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI);\n break;\n default:\n break;\n }\n this.inverseWorldToScreenQ.copy(this.worldToScreenQ);\n this.inverseWorldToScreenQ.inverse();\n }\n}\n","import Component from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\n\nimport { toAxis } from \"../utils\";\nimport { util, ROTATE_CONSTANT } from \"../../utils/math-util\";\n\nimport FusionPoseSensor from \"./FusionPoseSensor\";\n\nconst getDeltaYaw = (prvQ: quat, curQ: quat): number => {\n const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(util.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nconst getDeltaPitch = (prvQ: quat, curQ: quat): number => {\n const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport default class TiltMotionInput extends Component<{}> {\n public element: HTMLElement;\n public options: { scale: number; threshold: number };\n public fusionPoseSensor: FusionPoseSensor | null;\n public axes: string[];\n public observer: InputTypeObserver | null;\n\n private _prevQuaternion: quat | null;\n private _quaternion: quat | null;\n\n public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {\n super();\n this.element = el;\n\n this._prevQuaternion = null;\n this._quaternion = null;\n\n this.fusionPoseSensor = null;\n\n this.options = {\n ...{\n scale: 1,\n threshold: 0\n }, ...options\n };\n\n this._onPoseChange = this._onPoseChange.bind(this);\n }\n\n public mapAxes(axes: string[]) {\n this.axes = axes;\n }\n\n public connect(observer: InputTypeObserver) {\n if (this.observer) {\n return this;\n }\n this.observer = observer;\n this.fusionPoseSensor = new FusionPoseSensor();\n this.fusionPoseSensor.enable();\n this._attachEvent();\n return this;\n }\n\n public disconnect() {\n if (!this.observer) {\n return this;\n }\n\n this._dettachEvent();\n this.fusionPoseSensor!.disable();\n this.fusionPoseSensor!.destroy();\n this.fusionPoseSensor = null;\n this.observer = null;\n return this;\n }\n\n public destroy() {\n this.disconnect();\n (this.element as any) = null;\n (this.options as any) = null;\n (this.axes as any) = null;\n this._prevQuaternion = null;\n this._quaternion = null;\n }\n\n private _onPoseChange(event) {\n if (!this._prevQuaternion) {\n this._prevQuaternion = quat.clone(event.quaternion);\n this._quaternion = quat.clone(event.quaternion);\n return;\n }\n\n quat.copy(this._prevQuaternion, this._quaternion!);\n quat.copy(this._quaternion!, event.quaternion);\n\n this.observer!.change(this, event, toAxis(this.axes, [\n getDeltaYaw(this._prevQuaternion, this._quaternion as quat),\n getDeltaPitch(this._prevQuaternion, this._quaternion as quat)\n ]));\n }\n\n private _attachEvent() {\n this.fusionPoseSensor!.on(\"change\", this._onPoseChange);\n }\n\n private _dettachEvent() {\n this.fusionPoseSensor!.off(\"change\", this._onPoseChange);\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport { window } from \"../utils/browser\";\n\n// Singleton\nlet screenRotationAngleInst: ScreenRotationAngle | null = null;\nlet refCount = 0;\n\nexport default class ScreenRotationAngle {\n private _spinR: number;\n private _screenOrientationAngle: number;\n\n public constructor() {\n refCount++;\n\n if (screenRotationAngleInst) {\n return screenRotationAngleInst;\n }\n /* eslint-disable */\n screenRotationAngleInst = this;\n /* eslint-enable */\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n\n this._spinR = 0;\n\n this._screenOrientationAngle = 0;\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.addEventListener(\"orientationchange\", this._onOrientationChange);\n }\n\n public getRadian() {\n // Join with screen orientation\n // this._testVal = this._spinR + \", \" + this._screenOrientationAngle + \", \" + window.orientation;\n return this._spinR + glMatrix.toRadian(this._screenOrientationAngle);\n }\n\n public unref() {\n if (--refCount > 0) {\n return;\n }\n\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"orientationchange\", this._onOrientationChange);\n\n this._spinR = 0;\n this._screenOrientationAngle = 0;\n /* eslint-disable */\n screenRotationAngleInst = null;\n /* eslint-enable */\n refCount = 0;\n }\n\n private _onDeviceOrientation(e: DeviceOrientationEvent) {\n if (e.beta === null || e.gamma === null) {\n // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it.\n return;\n }\n\n // Radian\n const betaR = glMatrix.toRadian(e.beta);\n const gammaR = glMatrix.toRadian(e.gamma);\n\n /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */\n this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR));\n }\n\n private _onOrientationChange() {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientationAngle = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n /* iOS */\n this._screenOrientationAngle = window.orientation >= 0 ?\n window.orientation : 360 + (window.orientation as number);\n }\n }\n}\n","import Axes, { PanInput } from \"@egjs/axes\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\nimport { PanInputOption } from \"@egjs/axes/declaration/inputType/PanInput\";\n\nimport ScreenRotationAngle from \"../ScreenRotationAngle\";\n\n/**\n * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle.\n *\n * The reason for using this function is that in VR mode,\n * the roll angle is adjusted in the direction opposite to the screen rotation angle.\n *\n * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move.\n * @extends PanInput\n */\nexport default class RotationPanInput extends PanInput {\n private _useRotation: boolean;\n private _screenRotationAngle: ScreenRotationAngle | null;\n private _userDirection: number;\n\n /**\n * Constructor\n * @private\n * @param {HTMLElement} el target element\n * @param {Object} [options] The option object\n * @param {Boolean} [options.useRotation] Whether to use rotation(or VR)\n */\n public constructor(el: HTMLElement, options: Partial<{ useRotation: boolean } & PanInputOption> = {}) {\n super(el, options);\n\n this._useRotation = false;\n this._screenRotationAngle = null;\n\n this.setUseRotation(!!(options && options.useRotation));\n\n this._userDirection = Axes.DIRECTION_ALL;\n }\n\n public setUseRotation(useRotation: boolean) {\n this._useRotation = useRotation;\n\n if (this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n this._screenRotationAngle = null;\n }\n\n if (this._useRotation) {\n this._screenRotationAngle = new ScreenRotationAngle();\n }\n }\n\n public connect(observer: InputTypeObserver) {\n // User intetened direction\n this._userDirection = this._direction;\n\n // In VR Mode, Use ALL direction if direction is not none\n // Because horizontal and vertical is changed dynamically by screen rotation.\n // this._direction is used to initialize hammerjs\n if (this._useRotation && (this._direction & Axes.DIRECTION_ALL)) {\n this._direction = Axes.DIRECTION_HORIZONTAL;\n }\n\n return super.connect(observer);\n }\n\n public destroy() {\n if (this._useRotation && this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n }\n\n super.destroy();\n }\n\n protected _getOffset(properties: number[], useDirection: boolean[]) {\n if (this._useRotation === false) {\n return super._getOffset(properties, useDirection);\n }\n\n const offset = super._getOffset(properties, [true, true]);\n const newOffset = [0, 0];\n\n const theta = this._screenRotationAngle!.getRadian();\n\n const cosTheta = Math.cos(theta);\n const sinTheta = Math.sin(theta);\n\n // RotateZ\n newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta;\n newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta;\n\n // Use only user allowed direction.\n if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) {\n newOffset[0] = 0;\n } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) {\n newOffset[1] = 0;\n }\n\n return newOffset;\n }\n}\n\n/**\n * Override getDirectionByAngle to return DIRECTION_ALL\n * Ref: https://github.com/naver/egjs-axes/issues/99\n *\n * But we obey axes's rule. If axes's rule is problem, let's apply following code.\n */\n// PanInput.getDirectionByAngle = function (angle, thresholdAngle) {\n// \treturn DIRECTION_ALL;\n// };\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3, glMatrix, quat } from \"gl-matrix\";\n\nimport FusionPoseSensor from \"./input/FusionPoseSensor\";\n\nconst Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0);\n\nexport default class DeviceQuaternion extends Component<{\n change: {\n isTrusted: boolean;\n };\n}> {\n private _fusionPoseSensor: FusionPoseSensor | null;\n private _quaternion: quat;\n\n public constructor() {\n super();\n\n this._fusionPoseSensor = new FusionPoseSensor();\n this._quaternion = quat.create();\n\n this._fusionPoseSensor.enable();\n this._fusionPoseSensor.on(\"change\", e => {\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(\"change\", { isTrusted: true }));\n });\n }\n\n public getCombinedQuaternion(yaw: number) {\n const yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw));\n const conj = quat.conjugate(quat.create(), this._quaternion);\n // Multiply pitch quaternion -> device quaternion -> yaw quaternion\n const outQ = quat.multiply(quat.create(), conj, yawQ);\n\n return outQ;\n }\n\n public destroy() {\n // detach all event handler\n this.off();\n\n if (this._fusionPoseSensor) {\n this._fusionPoseSensor.off();\n this._fusionPoseSensor.destroy();\n this._fusionPoseSensor = null;\n }\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PinchInput, MoveKeyInput, WheelInput } from \"@egjs/axes\";\nimport { vec2, quat, glMatrix } from \"gl-matrix\";\n\nimport { SUPPORT_TOUCH, SUPPORT_DEVICEMOTION } from \"../utils/browserFeature\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { ValueOf } from \"../types/internal\";\n\nimport TiltMotionInput from \"./input/TiltMotionInput\";\nimport RotationPanInput from \"./input/RotationPanInput\";\nimport DeviceQuaternion from \"./DeviceQuaternion\";\nimport {\n GYRO_MODE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n TOUCH_DIRECTION_NONE\n} from \"./consts\";\n\n\nconst DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF];\nconst DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF];\nconst CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF];\n\nexport interface YawPitchControlOptions {\n element: HTMLElement | null;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n touchDirection: number;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n aspectRatio: number;\n}\ninterface YawPitchControlEvents {\n change: ComponentEvent<{\n yaw: number;\n pitch: number;\n fov: number;\n quaternion: quat | null;\n targetElement: HTMLElement;\n isTrusted: boolean;\n }>;\n hold: ComponentEvent<{\n isTrusted: boolean;\n }>;\n animationEnd: ComponentEvent<{\n isTrusted: boolean;\n }>;\n}\n\n/**\n * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates.\n * @alias eg.YawPitchControl\n * @extends eg.Component\n *\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass YawPitchControl extends Component {\n public static VERSION = VERSION;\n // Expose DeviceOrientationControls sub module for test purpose\n public static CONTROL_MODE_VR = CONTROL_MODE_VR;\n public static CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH;\n public static TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL;\n public static TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW;\n public static TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH;\n public static TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE;\n\n public options: YawPitchControlOptions;\n\n private _element: HTMLElement | null;\n private _initialFov: number;\n private _enabled: boolean;\n private _isAnimating: boolean;\n private _deviceQuaternion: DeviceQuaternion | null;\n\n private _axes: Axes;\n private _axesPanInput: RotationPanInput;\n private _axesWheelInput: WheelInput;\n private _axesTiltMotionInput: TiltMotionInput | null;\n private _axesPinchInput: PinchInput | null;\n private _axesMoveKeyInput: MoveKeyInput;\n\n /**\n * @param {object} options The option object of the eg.YawPitch module\n * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module\n * @param {number} [options.yaw=0] initial yaw (degree)\n * @param {number} [options.pitch=0] initial pitch (degree)\n * @param {number} [options.fov=65] initial field of view (degree)\n * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown\n * @param {boolean} [options.useZoom=true] Indicates whether zoom is available\n * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled\n * @param {string} [config.gyroMode=yawPitch] Enables control through device motion.\n * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move)\n * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw\n * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch\n * @param {number[]} [options.fovRange=[30, 110] Range of FOV\n * @param {number} [options.aspectRatio=1] Aspect Ratio\n */\n public constructor(options: Partial) {\n super();\n this.options = {} as any;\n\n const opt = {\n ...{\n element: null,\n yaw: 0,\n pitch: 0,\n fov: 65,\n showPolePoint: false,\n useZoom: true,\n useKeyboard: true,\n gyroMode: GYRO_MODE.YAWPITCH,\n touchDirection: TOUCH_DIRECTION_ALL,\n yawRange: DEFAULT_YAW_RANGE,\n pitchRange: DEFAULT_PITCH_RANGE,\n fovRange: [30, 110],\n aspectRatio: 1 /* TODO: Need Mandatory? */\n }, ...options\n };\n\n this._element = opt.element;\n this._initialFov = opt.fov;\n this._enabled = false;\n this._isAnimating = false;\n this._deviceQuaternion = null;\n\n this._initAxes(opt);\n this.option(opt);\n }\n\n /**\n * Update Pan Scale\n *\n * Scale(Sensitivity) values of panning is related with fov and height.\n * If at least one of them is changed, this function need to be called.\n * @param {*} param\n */\n public updatePanScale(param: Partial<{\n height: number;\n }> = {}) {\n const fov = this._axes.get().fov;\n const areaHeight = param.height || parseInt(window.getComputedStyle(this._element!).height, 10);\n const scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight;\n\n this._axesPanInput.options.scale = [scale, scale];\n this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW;\n\n return this;\n }\n\n public option(): YawPitchControlOptions;\n public option(key: K): YawPitchControlOptions[K];\n public option(key: K, newValue: YawPitchControlOptions[K]): YawPitchControl;\n public option(newOptions: Partial): YawPitchControl;\n /*\n * Override component's option method\n * to call method for updating values which is affected by option change.\n *\n * @param {*} args\n */\n public option(key?: K | Partial, newValue?: YawPitchControlOptions[K]) {\n // Getter\n if (!key) {\n return this._getOptions();\n } else if (key && typeof key === \"string\" && typeof newValue === \"undefined\") {\n return this._getOptions(key);\n }\n\n // Setter\n let newOptions: Partial = {};\n let changedKeyList: string[] = []; // TODO: if value is not changed, then do not push on changedKeyList.\n\n if (typeof key === \"string\") {\n changedKeyList.push(key);\n newOptions[key] = newValue;\n } else {\n const options = key; // Retrieving object here\n changedKeyList = Object.keys(options);\n newOptions = {...options};\n }\n\n this._setOptions(this._getValidatedOptions(newOptions));\n this._applyOptions(changedKeyList);\n return this;\n }\n\n /**\n * Enable YawPitch functionality\n * @method eg.YawPitch#enable\n */\n public enable() {\n if (this._enabled) {\n return this;\n }\n\n this._enabled = true;\n\n // touchDirection is decided by parameter is valid string (Ref. Axes.connect)\n this._applyOptions(Object.keys(this.options));\n\n // TODO: Is this code is needed? Check later.\n this.updatePanScale();\n\n return this;\n }\n\n /**\n * Disable YawPitch functionality\n * @method eg.YawPitch#disable\n */\n public disable(persistOrientation: boolean = false) {\n if (!this._enabled) {\n return this;\n }\n\n // TODO: Check peristOrientation is needed!\n if (!persistOrientation) {\n this._resetOrientation();\n }\n this._axes.disconnect();\n this._enabled = false;\n return this;\n }\n\n /**\n * Set one or more of yaw, pitch, fov\n * @param {Object} coordinate yaw, pitch, fov\n * @param {Number} duration Animation duration. if it is above 0 then it's animated.\n */\n public lookAt({yaw, pitch, fov}, duration) {\n const pos = this._axes.get();\n\n const y = yaw === undefined ? 0 : yaw - pos.yaw;\n const p = pitch === undefined ? 0 : pitch - pos.pitch;\n const f = fov === undefined ? 0 : fov - pos.fov;\n\n // Allow duration of animation to have more than MC_MAXIMUM_DURATION.\n this._axes.options.maximumDuration = Infinity;\n\n this._axes.setBy({\n yaw: y,\n pitch: p,\n fov: f\n }, duration);\n }\n\n public getYawPitch() {\n const yawPitch = this._axes.get();\n\n return {\n yaw: yawPitch.yaw,\n pitch: yawPitch.pitch\n };\n }\n\n public getFov() {\n return this._axes.get().fov;\n }\n\n public getQuaternion() {\n const pos = this._axes.get();\n\n return this._deviceQuaternion!.getCombinedQuaternion(pos.yaw);\n }\n\n public shouldRenderWithQuaternion() {\n return this.options.gyroMode === GYRO_MODE.VR;\n }\n\n /**\n * Destroys objects\n */\n public destroy() {\n /* eslint-disable @typescript-eslint/no-unused-expressions */\n this._axes && this._axes.destroy();\n this._axesPanInput && this._axesPanInput.destroy();\n this._axesWheelInput && this._axesWheelInput.destroy();\n this._axesTiltMotionInput && this._axesTiltMotionInput.destroy();\n this._axesPinchInput && this._axesPinchInput.destroy();\n this._axesMoveKeyInput && this._axesMoveKeyInput.destroy();\n this._deviceQuaternion && this._deviceQuaternion.destroy();\n /* eslint-enable @typescript-eslint/no-unused-expressions */\n }\n\n private _initAxes(opt: YawPitchControlOptions) {\n const yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio);\n const pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint);\n const useRotation = opt.gyroMode === GYRO_MODE.VR;\n\n this._axesPanInput = new RotationPanInput(this._element!, {useRotation});\n this._axesWheelInput = new WheelInput(this._element, {scale: -4});\n this._axesTiltMotionInput = null;\n this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, {scale: -1}) : null;\n this._axesMoveKeyInput = new MoveKeyInput(this._element, {scale: [-6, 6]});\n\n this._axes = new Axes({\n yaw: {\n range: yRange,\n circular: this._isCircular(yRange),\n bounce: [0, 0]\n },\n pitch: {\n range: pRange,\n circular: this._isCircular(pRange),\n bounce: [0, 0]\n },\n fov: {\n range: opt.fovRange,\n circular: [false, false],\n bounce: [0, 0]\n }\n }, {\n deceleration: MC_DECELERATION,\n maximumDuration: MC_MAXIMUM_DURATION\n }, {\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }).on({\n // TODO: change event type after Axes event type inference update\n hold: (evt: any) => {\n // Restore maximumDuration not to be spin too mush.\n this._axes.options.maximumDuration = MC_MAXIMUM_DURATION;\n\n this.trigger(new ComponentEvent(\"hold\", { isTrusted: evt.isTrusted }));\n },\n change: (evt: any) => {\n if (evt.delta.fov !== 0) {\n this._updateControlScale(evt);\n this.updatePanScale();\n }\n this._triggerChange(evt);\n },\n release: evt => {\n this._triggerChange(evt);\n },\n animationEnd: (evt: any) => {\n this.trigger(new ComponentEvent(\"animationEnd\", { isTrusted: evt.isTrusted }));\n }\n });\n }\n\n private _getValidatedOptions(newOptions: Partial) {\n if (newOptions.yawRange) {\n newOptions.yawRange =\n this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio);\n }\n if (newOptions.pitchRange) {\n newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov);\n }\n return newOptions;\n }\n\n private _getOptions(): YawPitchControlOptions;\n private _getOptions(key: K): YawPitchControlOptions[K];\n private _getOptions(key?: K) {\n let value;\n\n if (typeof key === \"string\") {\n value = this.options[key];\n } else if (arguments.length === 0) {\n value = this.options;\n }\n return value;\n }\n\n private _setOptions(options: Partial): void {\n for (const key in options) {\n this.options[key] = options[key];\n }\n }\n\n private _applyOptions(keys: string[]) {\n const options = this.options;\n const axes = this._axes;\n const isVR = options.gyroMode === GYRO_MODE.VR;\n const isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH;\n // If it's VR mode, restrict user interaction to yaw direction only\n const touchDirection = isVR ?\n (TOUCH_DIRECTION_YAW & options.touchDirection) :\n options.touchDirection;\n\n // If one of below is changed, call updateControlScale()\n if (keys.some(key =>\n key === \"showPolePoint\" || key === \"fov\" || key === \"aspectRatio\" ||\n key === \"yawRange\" || key === \"pitchRange\"\n )) {\n // If fov is changed, update pan scale\n if (keys.indexOf(\"fov\") >= 0) {\n axes.setTo({\"fov\": options.fov});\n this.updatePanScale();\n }\n\n this._updateControlScale();\n }\n\n if (keys.some(key => key === \"fovRange\")) {\n const fovRange = options.fovRange;\n const prevFov = axes.get().fov;\n let nextFov = axes.get().fov;\n\n vec2.copy(axes.axis.fov.range as vec2, fovRange as vec2);\n\n if (nextFov < fovRange[0]) {\n nextFov = fovRange[0];\n } else if (prevFov > fovRange[1]) {\n nextFov = fovRange[1];\n }\n\n if (prevFov !== nextFov) {\n axes.setTo({\n fov: nextFov\n }, 0);\n this._updateControlScale();\n this.updatePanScale();\n }\n }\n\n if (keys.some(key => key === \"gyroMode\") && SUPPORT_DEVICEMOTION) {\n // Disconnect first\n if (this._axesTiltMotionInput) {\n this._axes.disconnect(this._axesTiltMotionInput);\n this._axesTiltMotionInput.destroy();\n this._axesTiltMotionInput = null;\n }\n\n if (this._deviceQuaternion) {\n this._deviceQuaternion.destroy();\n this._deviceQuaternion = null;\n }\n\n if (isVR) {\n this._initDeviceQuaternion();\n } else if (isYawPitch) {\n this._axesTiltMotionInput = new TiltMotionInput(this._element!);\n this._axes.connect([\"yaw\", \"pitch\"], this._axesTiltMotionInput);\n }\n\n this._axesPanInput.setUseRotation(isVR);\n }\n\n if (keys.some(key => key === \"useKeyboard\")) {\n const useKeyboard = options.useKeyboard;\n\n if (useKeyboard) {\n axes.connect([\"yaw\", \"pitch\"], this._axesMoveKeyInput);\n } else {\n axes.disconnect(this._axesMoveKeyInput);\n }\n }\n\n if (keys.some(key => key === \"useZoom\")) {\n const useZoom = options.useZoom;\n\n // Disconnect first\n axes.disconnect(this._axesWheelInput);\n if (useZoom) {\n axes.connect([\"fov\"], this._axesWheelInput);\n }\n }\n\n this._togglePinchInputByOption(options.touchDirection, options.useZoom);\n\n if (keys.some(key => key === \"touchDirection\") && this._enabled) {\n this._enableTouch(touchDirection);\n }\n }\n\n private _togglePinchInputByOption(touchDirection: YawPitchControlOptions[\"touchDirection\"], useZoom: boolean) {\n if (this._axesPinchInput) {\n // disconnect first\n this._axes.disconnect(this._axesPinchInput);\n\n // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll.\n if (\n useZoom &&\n touchDirection === TOUCH_DIRECTION_ALL &&\n // TODO: Get rid of using private property of axes instance.\n (this._axes as any)._inputs.indexOf(this._axesPinchInput) === -1\n ) {\n this._axes.connect([\"fov\"], this._axesPinchInput);\n }\n }\n }\n\n private _enableTouch(direction: YawPitchControlOptions[\"touchDirection\"]) {\n // Disconnect first\n if (this._axesPanInput) {\n this._axes.disconnect(this._axesPanInput);\n }\n\n const yawEnabled = direction & TOUCH_DIRECTION_YAW ? \"yaw\" : null;\n const pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? \"pitch\" : null;\n\n this._axes.connect([yawEnabled, pitchEnabled] as string[], this._axesPanInput);\n }\n\n private _initDeviceQuaternion() {\n this._deviceQuaternion = new DeviceQuaternion();\n this._deviceQuaternion.on(\"change\", e => {\n this._triggerChange(e);\n });\n }\n\n private _getValidYawRange(newYawRange: number[], newFov?: number, newAspectRatio?: number) {\n const ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1);\n const fov = newFov || this._axes.get().fov;\n const horizontalFov = fov * ratio;\n const isValid = newYawRange[1] - newYawRange[0] >= horizontalFov;\n\n if (isValid) {\n return newYawRange;\n } else {\n return this.options.yawRange || DEFAULT_YAW_RANGE;\n }\n }\n\n private _getValidPitchRange(newPitchRange: number[], newFov?: number) {\n const fov = newFov || this._axes.get().fov;\n const isValid = newPitchRange[1] - newPitchRange[0] >= fov;\n\n if (isValid) {\n return newPitchRange;\n } else {\n return this.options.pitchRange || DEFAULT_PITCH_RANGE;\n }\n }\n\n private _isCircular(range: number[]) {\n return range[1] - range[0] < 360 ? [false, false] : [true, true];\n }\n\n /**\n * Update yaw/pitch min/max by 5 factor\n *\n * 1. showPolePoint\n * 2. fov\n * 3. yawRange\n * 4. pitchRange\n * 5. aspectRatio\n *\n * If one of above is changed, call this function\n */\n private _updateControlScale(changeEvt?: any) { // TODO: Change type after Axes type inference update\n const opt = this.options;\n const fov = this._axes.get().fov;\n\n const pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint);\n const yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio);\n\n // TODO: If not changed!?\n const pos = this._axes.get();\n let y = pos.yaw;\n let p = pos.pitch;\n\n vec2.copy(this._axes.axis.yaw.range as any, yRange as any);\n vec2.copy(this._axes.axis.pitch.range as any, pRange as any);\n this._axes.axis.yaw.circular = this._isCircular(yRange);\n this._axes.axis.pitch.circular = this._isCircular(pRange);\n\n /**\n * update yaw/pitch by it's range.\n */\n if (y < yRange[0]) {\n y = yRange[0];\n } else if (y > yRange[1]) {\n y = yRange[1];\n }\n\n if (p < pRange[0]) {\n p = pRange[0];\n } else if (p > pRange[1]) {\n p = pRange[1];\n }\n\n if (changeEvt) {\n changeEvt.set({\n yaw: y,\n pitch: p\n });\n }\n\n this._axes.setTo({\n yaw: y,\n pitch: p\n }, 0);\n\n return this;\n }\n\n private _updatePitchRange(pitchRange: number[], fov: number, showPolePoint: boolean) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n // Circular pitch on VR\n return CIRCULAR_PITCH_RANGE;\n }\n\n const verticalAngle = pitchRange[1] - pitchRange[0];\n const halfFov = fov / 2;\n const isPanorama = verticalAngle < 180;\n\n if (showPolePoint && !isPanorama) {\n // Use full pinch range\n return pitchRange.concat();\n }\n\n // Round value as movableCood do.\n return [pitchRange[0] + halfFov, pitchRange[1] - halfFov];\n }\n\n private _updateYawRange(yawRange: number[], fov: number, aspectRatio: number) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n return DEFAULT_YAW_RANGE;\n }\n\n const horizontalAngle = yawRange[1] - yawRange[0];\n\n /**\n * Full 360 Mode\n */\n if (horizontalAngle >= 360) {\n // Don't limit yaw range on Full 360 mode.\n return yawRange.concat();\n }\n\n /**\n * Panorama mode\n */\n // Ref : https://github.com/naver/egjs-view360/issues/290\n const halfHorizontalFov =\n mathUtil.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))) as number;\n\n // Round value as movableCood do.\n return [\n yawRange[0] + halfHorizontalFov,\n yawRange[1] - halfHorizontalFov\n ];\n }\n\n // TODO: update param type after Axes event type inference update\n private _triggerChange(evt: any) {\n const pos = this._axes.get();\n const opt = this.options;\n const event: YawPitchControlEvents[\"change\"] extends ComponentEvent ? T : never = {\n targetElement: opt.element as HTMLElement,\n isTrusted: evt.isTrusted,\n yaw: pos.yaw,\n pitch: pos.pitch,\n fov: pos.fov,\n quaternion: null\n };\n\n if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) {\n event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw);\n }\n\n this.trigger(new ComponentEvent(\"change\", event));\n }\n\n // TODO: makes constant to be logic\n private _adjustAspectRatio(input: number) {\n const inputRange = [\n 0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670,\n 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19,\n 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26,\n 2.30, 2.60, 3.00, 5.00, 6.00\n ];\n const outputRange = [\n 0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710,\n 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15,\n 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72,\n 1.82, 1.92, 2.00, 2.24, 2.30\n ];\n\n let rangeIdx = -1;\n\n for (let i = 0; i < inputRange.length - 1; i++) {\n if (inputRange[i] <= input && inputRange[i + 1] >= input) {\n rangeIdx = i;\n break;\n }\n }\n\n if (rangeIdx === -1) {\n if (inputRange[0] > input) {\n return outputRange[0];\n } else {\n // FIXME: this looks definitely wrong\n return outputRange[(outputRange[0] as any).length - 1];\n }\n }\n\n const inputA = inputRange[rangeIdx];\n const inputB = inputRange[rangeIdx + 1];\n const outputA = outputRange[rangeIdx];\n const outputB = outputRange[rangeIdx + 1];\n\n return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA));\n }\n\n private _lerp(a: number, b: number, fraction: number) {\n return a + fraction * (b - a);\n }\n\n private _resetOrientation() {\n const opt = this.options;\n\n this._axes.setTo({\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }, 0);\n\n return this;\n }\n}\n\nexport default YawPitchControl;\n","/**\n * Constant value for gyro mode.
(Reference {@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide})\n * @ko gyro 모드 대한 상수 값.
({@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide} 참고)\n * @namespace\n * @name GYRO_MODE\n * @memberof eg.view360.PanoViewer\n */\n/**\n * Disable gyro\n * @ko gyro 비활성화\n * @name NONE\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"none\"\n */\n/**\n * YawPitch Mode\n * @ko YawPitch Mode\n * @name YAWPITCH\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"yawPitch\"\n */\n/**\n * VR Mode\n * @ko VR Mode\n * @name VR\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"VR\"\n */\nimport { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\nimport { GYRO_MODE } from \"../YawPitchControl/consts\";\n\n/**\n * Constant value for errors\n * @ko 에러에 대한 상수 값\n * @namespace\n * @name ERROR_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst ERROR_TYPE = {\n /**\n * Unsupported device\n * @ko 미지원 기기\n * @name INVALID_DEVICE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 10\n */\n INVALID_DEVICE: 10,\n /**\n * Webgl not support\n * @ko WEBGL 미지원\n * @name NO_WEBGL\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 11\n */\n NO_WEBGL: 11,\n /**\n * Failed to load image\n * @ko 이미지 로드 실패\n * @name FAIL_IMAGE_LOAD\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 12\n */\n FAIL_IMAGE_LOAD: 12,\n /**\n * Failed to bind texture\n * @ko 텍스쳐 바인딩 실패\n * @name FAIL_BIND_TEXTURE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 13\n */\n FAIL_BIND_TEXTURE: 13,\n /**\n * Only one resource(image or video) should be specified\n * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함)\n * @name INVALID_RESOURCE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 14\n */\n INVALID_RESOURCE: 14,\n /**\n * WebGL context lost occurred\n * @ko WebGL context lost 발생\n * @name RENDERING_CONTEXT_LOST\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 15\n */\n RENDERING_CONTEXT_LOST: 15\n};\n\n/**\n * Constant value for events\n * @ko 이벤트에 대한 상수 값\n * @namespace\n * @name EVENTS\n * @memberof eg.view360.PanoViewer\n */\nconst PANOVIEWER_EVENTS: {\n READY: \"ready\";\n VIEW_CHANGE: \"viewChange\";\n ANIMATION_END: \"animationEnd\";\n ERROR: \"error\";\n} = {\n /**\n * Events that is fired when PanoViewer is ready to show image and handle user interaction.\n * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트\n * @name READY\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default ready\n */\n READY: \"ready\",\n /**\n * Events that is fired when direction or fov is changed.\n * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트\n * @name VIEW_CHANGE\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default viewChange\n */\n VIEW_CHANGE: \"viewChange\",\n /**\n * Events that is fired when animation which is triggered by inertia is ended.\n * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트\n * @name ANIMATION_END\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default animationEnd\n */\n ANIMATION_END: \"animationEnd\",\n /**\n * Events that is fired when error occurs\n * @ko 에러 발생 시 발생하는 이벤트\n * @name ERROR\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default error\n */\n ERROR: \"error\"\n};\n\n/**\n * Constant value for projection type\n * @ko 프로젝션 타입 대한 상수 값\n * @namespace\n * @name PROJECTION_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst PROJECTION_TYPE: {\n EQUIRECTANGULAR: \"equirectangular\";\n CUBEMAP: \"cubemap\";\n CUBESTRIP: \"cubestrip\";\n PANORAMA: \"panorama\";\n STEREOSCOPIC_EQUI: \"stereoequi\";\n} = {\n /**\n * Constant value for equirectangular type.\n * @ko equirectangular 에 대한 상수 값.\n * @name EQUIRECTANGULAR\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default equirectangular\n */\n EQUIRECTANGULAR: \"equirectangular\",\n /**\n * Constant value for cubemap type.\n * @ko cubemap 에 대한 상수 값.\n * @name CUBEMAP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubemap\n */\n CUBEMAP: \"cubemap\",\n /**\n * Constant value for cubestrip type.\n * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC.\n * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다.\n * @name CUBESTRIP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubestrip\n */\n CUBESTRIP: \"cubestrip\",\n /**\n * Constant value for PANORAMA type.\n *\n * PANORAMA is a format for a panorma image which is taken from smartphone.\n * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다.\n *\n * @name PANORAMA\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default panorama\n */\n PANORAMA: \"panorama\",\n /**\n * Constant value for EQUI_STEREOSCOPY type.\n *\n * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present.\n * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다.\n *\n * @name STEREOSCOPIC_EQUI\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default stereoequi\n */\n STEREOSCOPIC_EQUI: \"stereoequi\"\n};\n\n/**\n * A constant value for the format of the stereoscopic equirectangular projection type.\n * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값\n * @namespace\n * @name STEREO_FORMAT\n * @memberof eg.view360.PanoViewer\n */\nconst STEREO_FORMAT: {\n TOP_BOTTOM: \"3dv\";\n LEFT_RIGHT: \"3dh\";\n NONE: \"\";\n} = {\n /**\n * A constant value for format of top bottom stereoscopic 360 equirectangular projection.\n * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name TOP_BOTTOM\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dv\"\n */\n TOP_BOTTOM: \"3dv\",\n /**\n * A constant value for format of left right stereoscopic 360 equirectangular projection.\n * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name LEFT_RIGHT\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dh\"\n */\n LEFT_RIGHT: \"3dh\",\n /**\n * A constant value specifying media is not in stereoscopic format.\n * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"\"\n */\n NONE: \"\"\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst PANOVIEWER_OPTIONS: { [key in keyof PanoViewerOptions]: true } = {\n image: true,\n video: true,\n projectionType: true,\n cubemapConfig: true,\n stereoFormat: true,\n width: true,\n height: true,\n yaw: true,\n pitch: true,\n fov: true,\n showPolePoint: true,\n useZoom: true,\n useKeyboard: true,\n gyroMode: true,\n yawRange: true,\n pitchRange: true,\n fovRange: true,\n touchDirection: true,\n canvasClass: true\n};\n\nconst DEFAULT_CANVAS_CLASS = \"view360-canvas\";\n\nexport {\n GYRO_MODE,\n PANOVIEWER_EVENTS,\n ERROR_TYPE,\n PROJECTION_TYPE,\n STEREO_FORMAT,\n PANOVIEWER_OPTIONS,\n DEFAULT_CANVAS_CLASS\n};\n","import agent from \"@egjs/agent\";\n\nimport { TypedArray } from \"../types/internal\";\n\nconst WEBGL_ERROR_CODE = {\n \"0\": \"NO_ERROR\",\n \"1280\": \"INVALID_ENUM\",\n \"1281\": \"INVALID_VALUE\",\n \"1282\": \"INVALID_OPERATION\",\n \"1285\": \"OUT_OF_MEMORY\",\n \"1286\": \"INVALID_FRAMEBUFFER_OPERATION\",\n \"37442\": \"CONTEXT_LOST_WEBGL\"\n};\n\nlet webglAvailability: boolean | null = null;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet MAX_TEXTURE_SIZE_FOR_TEST: number | null = null;\n\nexport default class WebGLUtils {\n public static createShader(gl: WebGLRenderingContext, type: number, source: string) {\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (success) {\n return shader;\n }\n\n // eslint-disable-next-line\n console.error(gl.getShaderInfoLog(shader));\n\n return null;\n }\n\n public static createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = gl.createProgram()!;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (success) {\n return program;\n }\n\n gl.deleteProgram(program);\n return null;\n }\n\n public static initBuffer(gl: WebGLRenderingContext, target: number /* bind point */, data: TypedArray, itemSize: number, attr?: number) {\n const buffer = gl.createBuffer()!;\n\n gl.bindBuffer(target, buffer);\n gl.bufferData(target, data, gl.STATIC_DRAW);\n\n if (buffer) {\n (buffer as any).itemSize = itemSize;\n (buffer as any).numItems = data.length / itemSize;\n }\n\n if (attr !== undefined) {\n gl.enableVertexAttribArray(attr);\n gl.vertexAttribPointer(attr, (buffer as any).itemSize, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n }\n\n public static getWebglContext(canvas: HTMLCanvasElement, userContextAttributes?: WebGLContextAttributes) {\n const webglIdentifiers = [\"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n const contextAttributes = {\n ...{\n preserveDrawingBuffer: false,\n antialias: false\n }, ...userContextAttributes\n };\n\n const onWebglcontextcreationerror = e => e.statusMessage;\n\n canvas.addEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n return context;\n }\n\n public static createTexture(gl: WebGLRenderingContext, textureTarget: number) {\n const texture = gl.createTexture();\n\n gl.bindTexture(textureTarget, texture);\n gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(textureTarget, null);\n\n return texture;\n }\n\n /**\n * Returns the webgl availability of the current browser.\n * @method WebGLUtils#isWebGLAvailable\n * @retuen {Boolean} isWebGLAvailable\n */\n public static isWebGLAvailable(): boolean {\n if (webglAvailability === null) {\n const canvas = document.createElement(\"canvas\");\n const webglContext = WebGLUtils.getWebglContext(canvas);\n\n webglAvailability = !!webglContext;\n\n // webglContext Resource forced collection\n if (webglContext) {\n const loseContextExtension = webglContext.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n return !!webglAvailability;\n }\n\n /**\n * Returns whether webgl is stable in the current browser.\n * @method WebGLUtils#isStableWebGL\n * @retuen {Boolean} isStableWebGL\n */\n public static isStableWebGL() {\n const agentInfo = agent();\n let isStableWebgl = true;\n\n if (agentInfo.os.name === \"android\") {\n const version = parseFloat(agentInfo.os.version);\n\n if (version <= 4.3 && version >= 1) {\n isStableWebgl = false;\n } else if (version === 4.4) {\n if (agentInfo.browser.name !== \"chrome\") {\n isStableWebgl = false;\n }\n }\n }\n return isStableWebgl;\n }\n\n public static getErrorNameFromWebGLErrorCode(code: number | string) {\n if (!(code in WEBGL_ERROR_CODE)) {\n return \"UNKNOWN_ERROR\";\n }\n\n return WEBGL_ERROR_CODE[code];\n }\n\n\n /**\n * This function is wrapper for texImage2D to handle exceptions on texImage2D.\n * Purpose is to prevent service from being stopped by script error.\n */\n public static texImage2D(gl: WebGLRenderingContext, target: number, pixels: TexImageSource) {\n try {\n gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n } catch (error) {\n /* eslint-disable no-console */\n console.error(\"WebGLUtils.texImage2D error:\", error);\n /* eslint-enable no-console */\n }\n }\n\n public static getMaxTextureSize(gl: WebGLRenderingContext) {\n // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test\n return MAX_TEXTURE_SIZE_FOR_TEST || gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n}\n\n/**\n * This function should not be used in service code. It's provided only for test purpose.\n * It should be set to null or 0 when test is done.\n * @param {Number} size\n */\nconst setMaxTextureSizeForTestOnlyPurpose = (size: number) => {\n MAX_TEXTURE_SIZE_FOR_TEST = size;\n};\n\nexport {\n setMaxTextureSizeForTestOnlyPurpose\n};\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport agent from \"@egjs/agent\";\nimport { mat4 } from \"gl-matrix\";\n\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nconst agentInfo = agent();\nconst isIE11 = agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11;\n\nconst EVENTS: {\n ERROR: \"error\";\n} = {\n ERROR: \"error\"\n};\n\n/**\n *\n * Extends Component for firing errors occurs internally.\n */\nabstract class Renderer extends Component<{\n [EVENTS.ERROR]: {\n message: string;\n };\n}> {\n public static EVENTS = EVENTS;\n\n private _forceDimension: { width: number; height: number } | null;\n private _pixelCanvas: HTMLCanvasElement | null;\n private _pixelContext: CanvasRenderingContext2D | null;\n\n public constructor() {\n super();\n\n this._forceDimension = null;\n this._pixelCanvas = null;\n this._pixelContext = null;\n }\n\n public abstract getVertexPositionData(): number[];\n public abstract getIndexData(): number[];\n public abstract getTextureCoordData(textureData: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }): number[];\n\n public abstract getVertexShaderSource(): string;\n public abstract getFragmentShaderSource(): string;\n public abstract bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n public abstract updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n\n public render({ gl, shaderProgram, indexBuffer, mvMatrix, pMatrix }: {\n gl: WebGLRenderingContext;\n shaderProgram: WebGLProgram;\n indexBuffer: WebGLBuffer;\n mvMatrix: mat4;\n pMatrix: mat4;\n }) {\n gl.uniformMatrix4fv((shaderProgram as any).pMatrixUniform, false, pMatrix);\n gl.uniformMatrix4fv((shaderProgram as any).mvMatrixUniform, false, mvMatrix);\n\n if (indexBuffer) {\n gl.drawElements(gl.TRIANGLES, (indexBuffer as any).numItems, gl.UNSIGNED_SHORT, 0);\n }\n }\n\n // Define interface for Renderers\n /**\n * Following MUST BE DEFINED on Child of Renderer\n *\n * DATA\n *\n * - getVertexPositionData\n * - getIndexData\n * - getTextureCoordData\n *\n * SOURCE\n *\n * - getVertexShaderSource\n * - getFragmentShaderSource\n *\n * TEXTURE\n *\n * - bindTexture\n */\n public getDimension(pixelSource: HTMLImageElement | HTMLVideoElement) {\n const width = (pixelSource as HTMLImageElement).naturalWidth\n || (pixelSource as HTMLVideoElement).videoWidth;\n const height = (pixelSource as HTMLImageElement).naturalHeight\n || (pixelSource as HTMLVideoElement).videoHeight;\n\n return { width, height };\n }\n\n /**\n * Update data used by shader\n */\n public updateShaderData(param) { // eslint-disable-line @typescript-eslint/no-unused-vars\n /*\n * Update following data in implementation layer.\n * If the data is not changed, it does not need to implement this function.\n *\n * - _VERTEX_POSITION_DATA\n * - _TEXTURE_COORD_DATA\n * - _INDEX_DATA\n */\n }\n\n /**\n *\n * @param {HTMLImageElement | HTMLVideoElement} image\n * @param {Object = {width, height}} forceDimension Forced dimension to resize\n */\n protected _initPixelSource(image: HTMLImageElement | HTMLVideoElement, forceDimension: Renderer[\"_forceDimension\"] = null) {\n const isIE11Video = isIE11 && (image instanceof HTMLVideoElement);\n\n if (isIE11Video || forceDimension) {\n const {width, height} = forceDimension || this.getDimension(image);\n\n this._pixelCanvas = document.createElement(\"canvas\");\n this._pixelCanvas.width = width;\n this._pixelCanvas.height = height;\n this._pixelContext = this._pixelCanvas.getContext(\"2d\");\n }\n this._forceDimension = forceDimension;\n }\n\n protected _getPixelSource(image: HTMLImageElement | HTMLVideoElement) {\n if (!this._pixelCanvas) {\n return image;\n }\n\n /**\n * IE11 && Video\n * or\n * Dimension is forced (Image is larger than texture size.)\n */\n const contentDimension = this.getDimension(image);\n const textureDimension = this._forceDimension || contentDimension;\n\n if (this._pixelCanvas.width !== textureDimension.width) {\n this._pixelCanvas.width = textureDimension.width;\n }\n\n if (this._pixelCanvas.height !== textureDimension.height) {\n this._pixelCanvas.height = textureDimension.height;\n }\n\n if (this._forceDimension) {\n this._pixelContext!.drawImage(image,\n 0, 0, contentDimension.width, contentDimension.height,\n 0, 0, textureDimension.width, textureDimension.height);\n } else {\n this._pixelContext!.drawImage(image, 0, 0);\n }\n\n return this._pixelCanvas;\n }\n\n protected _extractTileConfig(imageConfig: CubemapConfig) {\n let tileConfig: TileConfig[] =\n Array.isArray(imageConfig.tileConfig) ?\n imageConfig.tileConfig : Array(...Array(6)).map(() => imageConfig.tileConfig) as TileConfig[];\n\n tileConfig = tileConfig.map(\n config => ({\n ...{\n flipHorizontal: false,\n rotation: 0\n }, ...config\n })\n );\n\n return tileConfig;\n }\n\n protected _triggerError(error) {\n /* eslint-disable no-console */\n console.error(\"Renderer Error:\", error);\n /* eslint-enable no-console */\n\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n message: typeof error === \"string\" ? error : error.message\n }));\n }\n}\n\nexport default Renderer;\n","import agent from \"@egjs/agent\";\n\nimport WebGLUtils from \"../WebGLUtils\";\nimport { util as mathUtil } from \"../../utils/math-util\";\nimport { CubemapConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nclass CubeRenderer extends Renderer {\n public static extractOrder(imageConfig: CubemapConfig) {\n return imageConfig.order || \"RLUDBF\";\n }\n\n private static _VERTEX_POSITION_DATA: number[] | null = null;\n private static _INDEX_DATA: number[] | null = null;\n\n public getVertexPositionData() {\n CubeRenderer._VERTEX_POSITION_DATA =\n CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // top\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // bottom\n 1, -1, -1,\n -1, -1, -1,\n -1, -1, 1,\n 1, -1, 1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n return CubeRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n if (CubeRenderer._INDEX_DATA) {\n return CubeRenderer._INDEX_DATA;\n }\n\n const indexData: number[] = [];\n const vertexPositionData = this.getVertexPositionData();\n\n for (let i = 0; i < (vertexPositionData.length / 3); i += 4) {\n indexData.push(\n i,\n i + 2,\n i + 1,\n i,\n i + 3,\n i + 2\n );\n }\n\n CubeRenderer._INDEX_DATA = indexData;\n return indexData;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n const vertexOrder = \"BFUDRL\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const base = this.getVertexPositionData();\n const tileConfig = this._extractTileConfig(imageConfig);\n const elemSize = 3;\n const vertexPerTile = 4;\n const { trim } = imageConfig;\n\n const texCoords = vertexOrder.split(\"\")\n .map(face => tileConfig[order.indexOf(face)])\n .map((config, i) => {\n const rotation = Math.floor(config.rotation / 90);\n const ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2];\n\n for (let r = 0; r < Math.abs(rotation); r++) {\n if ((config.flipHorizontal && rotation > 0) ||\n (!config.flipHorizontal && rotation < 0)) {\n ordermap.push(ordermap.shift()!);\n } else {\n ordermap.unshift(ordermap.pop()!);\n }\n }\n\n const elemPerTile = elemSize * vertexPerTile;\n const tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile);\n const tileTemp: number[][] = [];\n\n for (let j = 0; j < vertexPerTile; j++) {\n tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize);\n }\n return tileTemp;\n })\n .map(coord => this._shrinkCoord({ image, faceCoords: coord, trim }))\n .reduce((acc: number[], val: number[][]) => [\n ...acc,\n ...val.reduce((coords, coord) => [...coords, ...coord], [])\n ], []);\n\n return texCoords;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n const baseOrder = \"RLUDBF\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const orderMap = {};\n\n order.split(\"\").forEach((v, i) => {\n orderMap[v] = i;\n });\n\n try {\n if (image instanceof Array) {\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]);\n }\n } else {\n const maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image);\n\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n const tile = this.extractTileFromImage(\n image, tileIdx, maxCubeMapTextureSize\n );\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile);\n }\n }\n } catch (e) {\n this._triggerError(e);\n }\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n this.updateTexture(gl, image, imageConfig);\n }\n\n public getSourceTileSize(image: HTMLImageElement | HTMLVideoElement) {\n const {width, height} = this.getDimension(image);\n const aspectRatio = width / height;\n let inputTextureSize;\n\n if (aspectRatio === 1 / 6) {\n inputTextureSize = width;\n } else if (aspectRatio === 6) {\n inputTextureSize = height;\n } else if (aspectRatio === 2 / 3) {\n inputTextureSize = width / 2;\n } else {\n inputTextureSize = width / 3;\n }\n return inputTextureSize;\n }\n\n public extractTileFromImage(image: HTMLImageElement | HTMLVideoElement, tileIdx: number, outputTextureSize: number) {\n const {width} = this.getDimension(image);\n const inputTextureSize = this.getSourceTileSize(image);\n\n const canvas = document.createElement(\"canvas\");\n\n canvas.width = outputTextureSize;\n canvas.height = outputTextureSize;\n const context = canvas.getContext(\"2d\");\n const tilePerRow = width / inputTextureSize;\n\n const x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow);\n const y = Math.floor(tileIdx / tilePerRow) * (inputTextureSize);\n\n context!.drawImage(\n image, x, y,\n inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize\n );\n return canvas;\n }\n\n public getMaxCubeMapTextureSize(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n const agentInfo = agent();\n const maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n let imageWidth = this.getSourceTileSize(image);\n\n if (agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11) {\n if (!mathUtil.isPowerOfTwo(imageWidth)) {\n for (let i = 1; i < maxCubeMapTextureSize; i *= 2) {\n if (i < imageWidth) {\n continue;\n } else {\n imageWidth = i;\n break;\n }\n }\n }\n }\n if (agentInfo.os.name === \"ios\") {\n const majorVersion = agentInfo.os.majorVersion;\n\n // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다.\n if (majorVersion === 9) {\n imageWidth = 1024;\n }\n // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다.\n if (majorVersion === 8) {\n imageWidth = 512;\n }\n }\n // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수\n return Math.min(maxCubeMapTextureSize, imageWidth);\n }\n\n private _shrinkCoord(coordData: {\n image: HTMLImageElement | HTMLVideoElement;\n faceCoords: number[][];\n trim: number;\n }) {\n const { image, faceCoords, trim } = coordData;\n\n const inputTextureSize = Array.isArray(image)\n ? this.getDimension(image[0]).width\n : this.getSourceTileSize(image);\n\n // Shrink by \"trim\" px\n const SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize);\n\n const axisMultipliers = [0, 1, 2].map(axisIndex => {\n const axisDir = mathUtil.sign(faceCoords[0][axisIndex]);\n const notSameDir = faceCoords.some(coord => mathUtil.sign(coord[axisIndex]) !== axisDir);\n\n return notSameDir;\n }).map(notSameDir => notSameDir ? SHRINK_MULTIPLIER : 1);\n\n return faceCoords.map(coords => coords.map((coord, axisIndex) => coord * axisMultipliers[axisIndex]));\n }\n}\n\nexport default CubeRenderer;\n","\nimport WebGLUtils from \"../WebGLUtils\";\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nexport default class CubeStripRenderer extends Renderer {\n private _vertices: number[];\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}`;\n }\n\n public getVertexPositionData() {\n if (!this._vertices) {\n this._vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n }\n\n return this._vertices;\n }\n\n public getIndexData() {\n // TODO: 한번만 계산하도록 수정하기\n const indices = (() => {\n const indexData: number[] = [];\n\n for (let i = 0; i < (this._vertices.length / 3); i += 4) {\n indexData.push(\n i,\n i + 1,\n i + 2,\n i,\n i + 2,\n i + 3\n );\n }\n return indexData;\n })();\n\n return indices;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n // TODO: make it cols, rows as config.\n const cols = 3;\n const rows = 2;\n\n const textureSize = this.getDimension(image);\n const { trim } = imageConfig;\n\n const order = imageConfig.order || \"RLUDFB\";\n let coords: number[][] = [];\n\n // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다.\n for (let r = rows - 1; r >= 0; r--) {\n for (let c = 0; c < cols; c++) {\n const coord = [\n c / cols, r / rows,\n (c + 1) / cols, r / rows,\n (c + 1) / cols, (r + 1) / rows,\n c / cols, (r + 1) / rows\n ];\n\n coords.push(coord);\n }\n }\n\n const tileConfigs = this._extractTileConfig(imageConfig);\n\n // Transform Coord By Flip & Rotation\n coords = coords\n // shrink coord to avoid pixel bleeding\n .map(coord => this._shrinkCoord(coord, textureSize, trim))\n .map((coord, i) => this._transformCoord(coord, tileConfigs[i]));\n\n // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치\n return \"BFUDRL\".split(\"\")\n .map(face => order.indexOf(face))\n .map(index => coords[index])\n .reduce((acc, val) => acc.concat(val), []);\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n private _transformCoord(coord: number[], tileConfig: TileConfig) {\n let newCoord = coord.slice();\n\n if (tileConfig.flipHorizontal) {\n newCoord = this._flipHorizontalCoord(newCoord);\n }\n\n if (tileConfig.rotation) {\n newCoord = this._rotateCoord(newCoord, tileConfig.rotation);\n }\n\n return newCoord;\n }\n\n private _shrinkCoord(coord: number[], textureSize: { width: number; height: number }, trim: number) {\n const { width, height } = textureSize;\n\n // Shrink by \"trim\" px\n const SHRINK_Y = trim * (1 / height);\n const SHRINK_X = trim * (1 / width);\n\n return [\n coord[0] + SHRINK_X, coord[1] + SHRINK_Y,\n coord[2] - SHRINK_X, coord[3] + SHRINK_Y,\n coord[4] - SHRINK_X, coord[5] - SHRINK_Y,\n coord[6] + SHRINK_X, coord[7] - SHRINK_Y\n ];\n }\n\n private _rotateCoord(coord: number[], rotationAngle: number) {\n const SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord.\n const shiftCount = Math.floor(rotationAngle / 90) % 4;\n\n if (shiftCount === 0) {\n return coord;\n }\n\n let moved;\n let rotatedCoord: number[] = [];\n\n if (shiftCount > 0) {\n moved = coord.splice(0, shiftCount * SIZE);\n rotatedCoord = coord.concat(moved);\n } else {\n moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE);\n rotatedCoord = moved.concat(coord);\n }\n\n return rotatedCoord;\n }\n\n private _flipHorizontalCoord(coord: number[]) {\n return [\n coord[2], coord[3],\n coord[0], coord[1],\n coord[6], coord[7],\n coord[4], coord[5]\n ];\n }\n}\n","import WebGLUtils from \"../WebGLUtils\";\nimport { STEREO_FORMAT } from \"../../PanoViewer/consts\";\nimport { ValueOf } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nconst latitudeBands = 60;\nconst longitudeBands = 60;\nconst radius = 2;\nconst ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\nlet latIdx: number;\nlet lngIdx: number;\n\nfor (latIdx = 0; latIdx <= latitudeBands; latIdx++) {\n const theta = (latIdx / latitudeBands - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / longitudeBands;\n const v = latIdx / latitudeBands;\n\n textureCoordData.push(u, v);\n vertexPositionData.push(radius * x, radius * y, radius * z);\n\n if (lngIdx !== longitudeBands && latIdx !== latitudeBands) {\n const a = latIdx * (longitudeBands + 1) + lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n}\n\nclass SphereRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n private _stereoFormat: ValueOf;\n\n public constructor(format: SphereRenderer[\"_stereoFormat\"]) {\n super();\n\n this._stereoFormat = format;\n }\n\n public render(ctx: Parameters[0]) {\n const {gl, shaderProgram} = ctx;\n\n let leftEyeScaleOffset: number[];\n let rightEyeScaleOffset: number[];\n\n switch (this._stereoFormat) {\n case STEREO_FORMAT.TOP_BOTTOM:\n leftEyeScaleOffset = [1, 0.5, 0, 0];\n rightEyeScaleOffset = [1, 0.5, 0, 0.5];\n break;\n case STEREO_FORMAT.LEFT_RIGHT:\n leftEyeScaleOffset = [0.5, 1, 0, 0];\n rightEyeScaleOffset = [0.5, 1, 0.5, 0];\n break;\n default:\n leftEyeScaleOffset = [1, 1, 0, 0];\n rightEyeScaleOffset = [1, 1, 0, 0];\n }\n\n const uTexScaleOffset = gl.getUniformLocation(shaderProgram, \"uTexScaleOffset\");\n\n gl.uniform4fv(uTexScaleOffset, [...leftEyeScaleOffset, ...rightEyeScaleOffset]);\n\n super.render(ctx);\n }\n\n public getVertexPositionData() {\n return SphereRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return SphereRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return SphereRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const { width, height } = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n}\n\nexport default SphereRenderer;\n","import { glMatrix } from \"gl-matrix\";\n\nimport WebGLUtils from \"../WebGLUtils\";\n\nimport Renderer from \"./Renderer\";\n\n// const latitudeBands = 60;\nconst MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6;\nconst longitudeBands = 60;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\n\nclass CylinderRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n public getVertexPositionData() {\n return CylinderRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return CylinderRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return CylinderRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n let resizeDimension: { width: number; height: number } | undefined;\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device texture limit(${maxSize}))`);\n\n // Request resizing texture.\n /**\n * TODO: Is it need to apply on another projection type?\n */\n resizeDimension = width > height ?\n {width: maxSize, height: maxSize * height / width} :\n {width: maxSize * width / height, height: maxSize};\n }\n\n // Pixel Source for IE11 & Video or resizing needed\n this._initPixelSource(image, resizeDimension);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n public updateShaderData({ imageAspectRatio = MIN_ASPECT_RATIO_FOR_FULL_PANORAMA }) {\n let lngIdx: number;\n let cylinderMaxRadian: number;\n let halfCylinderY: number;\n let rotated: boolean;\n let aspectRatio: number;\n\n // Exception case: orientation is rotated.\n if (imageAspectRatio < 1) {\n /**\n * If rotated is true, we assume that image is rotated counter clockwise.\n * TODO: If there's other rotation, it is need to implement by each rotation.\n */\n rotated = true;\n aspectRatio = 1 / imageAspectRatio;\n } else {\n rotated = false;\n aspectRatio = imageAspectRatio;\n }\n\n if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) {\n const fov = 360 / aspectRatio;\n\n cylinderMaxRadian = 2 * Math.PI; // 360 deg\n halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2));\n } else {\n cylinderMaxRadian = aspectRatio;\n halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1.\n }\n\n // initialize shader data before update\n textureCoordData.length = 0;\n vertexPositionData.length = 0;\n indexData.length = 0;\n\n const CYLIDER_Y = [-halfCylinderY, halfCylinderY];\n const startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360)\n\n // console.log(\"cylinderMaxRadian:\", glMatrix.toDegree(cylinderMaxRadian), \"CYLIDER_Y\", CYLIDER_Y, \"start angle\", glMatrix.toDegree(startAngleForCenterAlign));\n for (let yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength/* bottom & top */; yIdx++) {\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const angle = startAngleForCenterAlign + (lngIdx / longitudeBands * cylinderMaxRadian);\n const x = Math.cos(angle);\n const y = CYLIDER_Y[yIdx];\n const z = Math.sin(angle);\n let u: number;\n let v: number;\n\n if (rotated) {\n // Rotated 90 degree (counter clock wise)\n u = 1 - yIdx; // yLength - yIdx;\n v = lngIdx / longitudeBands;\n } else {\n // \t// Normal case (Not rotated)\n u = lngIdx / longitudeBands;\n v = yIdx;\n }\n\n textureCoordData.push(u, v);\n vertexPositionData.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < longitudeBands) {\n const a = lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n }\n}\n\nexport default CylinderRenderer;\n","import Promise from \"promise-polyfill\";\nimport { mat4 } from \"gl-matrix\";\n\nconst VR_DISPLAY_PRESENT_CHANGE = \"vrdisplaypresentchange\";\nconst DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1];\nconst DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1];\nconst EYES = {\n LEFT: \"left\",\n RIGHT: \"right\"\n} as const;\n\nclass VRManager {\n private _vrDisplay: VRDisplay | null;\n private _frameData: VRFrameData;\n private _yawOffset: number;\n private _leftBounds: number[];\n private _rightBounds: number[];\n\n public constructor() {\n this._frameData = new window.VRFrameData();\n this._clear();\n }\n\n public get context() { return this._vrDisplay; }\n\n public destroy = () => {\n const vrDisplay = this._vrDisplay;\n\n this.removeEndCallback(this.destroy);\n\n if (vrDisplay && vrDisplay.isPresenting) {\n void vrDisplay.exitPresent();\n }\n\n this._clear();\n };\n\n public canRender() {\n return Boolean(this._vrDisplay);\n }\n\n public beforeRender(gl: WebGLRenderingContext) {\n // Render to the default backbuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public afterRender() {\n this._vrDisplay!.submitFrame();\n }\n\n public getEyeParams(gl: WebGLRenderingContext) {\n const display = this._vrDisplay!;\n const halfWidth = gl.drawingBufferWidth * 0.5;\n const height = gl.drawingBufferHeight;\n const frameData = this._frameData;\n\n display.getFrameData(frameData);\n\n const leftMVMatrix = frameData.leftViewMatrix;\n const rightMVMatrix = frameData.rightViewMatrix;\n\n mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset);\n mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset);\n\n return [\n {\n viewport: [0, 0, halfWidth, height],\n mvMatrix: leftMVMatrix,\n pMatrix: frameData.leftProjectionMatrix\n },\n {\n viewport: [halfWidth, 0, halfWidth, height],\n mvMatrix: rightMVMatrix,\n pMatrix: frameData.rightProjectionMatrix\n }\n ];\n }\n\n public isPresenting() {\n return Boolean(this._vrDisplay && this._vrDisplay.isPresenting);\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public requestPresent(canvas: HTMLCanvasElement) {\n return navigator.getVRDisplays().then(displays => {\n const vrDisplay = displays.length && displays[0];\n\n if (!vrDisplay) {\n return Promise.reject(new Error(\"No displays available.\"));\n }\n if (!vrDisplay.capabilities.canPresent) {\n return Promise.reject(new Error(\"Display lacking capability to present.\"));\n }\n\n return vrDisplay.requestPresent([{source: canvas}]).then(() => {\n const leftEye = vrDisplay.getEyeParameters(EYES.LEFT);\n const rightEye = vrDisplay.getEyeParameters(EYES.RIGHT);\n\n canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;\n canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);\n\n this._setDisplay(vrDisplay);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setDisplay(vrDisplay: VRDisplay) {\n this._vrDisplay = vrDisplay;\n\n const layers = vrDisplay.getLayers();\n\n if (layers.length) {\n const layer = layers[0];\n\n this._leftBounds = layer.leftBounds as number[];\n this._rightBounds = layer.rightBounds as number[];\n }\n\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._vrDisplay = null;\n this._leftBounds = DEFAULT_LEFT_BOUNDS;\n this._rightBounds = DEFAULT_RIGHT_BOUNDS;\n this._yawOffset = 0;\n }\n}\n\nexport default VRManager;\n","import { mat4, glMatrix } from \"gl-matrix\";\nimport { XRFrame, XRLayer, XRReferenceSpace, XRSession, XRSessionInit } from \"webxr\";\n\nimport { IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { merge } from \"../../utils/utils\";\n\nconst XR_REFERENCE_SPACE = \"local\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\nclass XRManager {\n private _xrSession: XRSession | null;\n private _xrLayer: XRLayer | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n private _yawOffset: number;\n private _presenting: boolean;\n\n public constructor(options: XRSessionOptions = {}) {\n this._clear();\n this._options = options;\n }\n\n public get context() { return this._xrSession; }\n\n public destroy = () => {\n const xrSession = this._xrSession;\n\n this.removeEndCallback(this.destroy);\n\n if (xrSession) {\n // Capture to avoid errors\n xrSession.end().then(() => void 0, () => void 0);\n }\n this._clear();\n };\n\n public canRender(frame: XRFrame) {\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n return Boolean(pose);\n }\n\n public beforeRender(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer!.framebuffer);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n public afterRender() {}\n\n public getEyeParams(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) {\n // Can't render\n return null;\n }\n\n const glLayer = session.renderState.baseLayer;\n\n return pose.views.map(view => {\n const viewport = glLayer!.getViewport(view);\n const mvMatrix = view.transform.inverse.matrix;\n\n if (IS_SAFARI_ON_DESKTOP) {\n mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180));\n }\n\n mat4.rotateY(mvMatrix, mvMatrix, this._yawOffset);\n\n return {\n viewport: [viewport.x, viewport.y, viewport.width, viewport.height],\n mvMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n public isPresenting() {\n return this._presenting;\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.addEventListener(\"end\", callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.removeEventListener(\"end\", callback);\n }\n\n public async requestPresent(canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {\n const options = merge({\n requiredFeatures: [XR_REFERENCE_SPACE]\n }, this._options);\n\n const attributes = gl.getContextAttributes();\n if (attributes && (attributes as any).xrCompatible !== true) {\n await (gl as any).makeXRCompatible();\n }\n\n return (navigator as any).xr.requestSession(\"immersive-vr\", options).then(session => {\n const xrLayer = new (window as any).XRWebGLLayer(session, gl);\n\n session.updateRenderState({baseLayer: xrLayer});\n return session.requestReferenceSpace(XR_REFERENCE_SPACE)\n .then(refSpace => {\n this._setSession(session, xrLayer, refSpace);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setSession(session: XRSession, xrLayer: XRLayer, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrLayer = xrLayer;\n this._xrRefSpace = refSpace;\n this._presenting = true;\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._xrSession = null;\n this._xrLayer = null;\n this._xrRefSpace = null;\n this._presenting = false;\n this._yawOffset = 0;\n this._options = {};\n }\n}\n\nexport default XRManager;\n","import { IS_SAFARI_ON_DESKTOP } from \"../utils/browser\";\n\nclass WebGLAnimator {\n private _callback: ((...args: any[]) => any) | null;\n private _context: any;\n private _rafId: number;\n private _rafTimer: number;\n\n public constructor() {\n this._callback = null;\n this._context = window;\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public setCallback(callback: (...args: any[]) => any) {\n this._callback = callback;\n }\n\n public setContext(context: any) {\n this._context = context;\n }\n\n public start() {\n const context = this._context;\n const callback = this._callback;\n\n // No context / callback set\n if (!context || !callback) return;\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n if (IS_SAFARI_ON_DESKTOP) {\n this._rafId = context.requestAnimationFrame(this._onLoopNextTick);\n } else {\n this._rafId = context.requestAnimationFrame(this._onLoop);\n }\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n /**\n * There can be more than 1 argument when we use XRSession's raf\n */\n private _onLoop = (...args: any[]) => {\n this._callback!(...args);\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n };\n\n /**\n * MacOS X Safari Bug Fix\n * This code guarantees that rendering should be occurred.\n *\n * In MacOS X(10.14.2), Safari (12.0.2)\n * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term\n * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms)\n * So browser cannot render the frame and may be freezing.\n */\n private _onLoopNextTick = (...args: any[]) => {\n const before = performance.now();\n\n this._callback!(...args);\n\n const diff = performance.now() - before;\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n this._rafTimer = -1;\n }\n\n /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */\n if (diff < 16) {\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n } else {\n /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */\n this._rafTimer = window.setTimeout(this._onLoop, 0);\n }\n };\n}\n\nexport default WebGLAnimator;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { XRFrame } from \"webxr\";\nimport Promise from \"promise-polyfill\";\nimport { glMatrix, vec3, mat3, mat4, quat } from \"gl-matrix\";\nimport ImReady, { OnReady } from \"@egjs/imready\";\n\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { devicePixelRatio, WEBXR_SUPPORTED } from \"../utils/browserFeature\";\nimport { PROJECTION_TYPE, STEREO_FORMAT } from \"../PanoViewer/consts\";\nimport { IS_IOS } from \"../utils/browser\";\nimport { CubemapConfig, ImageCandidate, ValueOf, VideoCandidate } from \"../types/internal\";\nimport YawPitchControl from \"../YawPitchControl/YawPitchControl\";\nimport { toImageElement, toVideoElement } from \"../utils/utils\";\n\nimport WebGLUtils from \"./WebGLUtils\";\nimport Renderer from \"./renderer/Renderer\";\nimport CubeRenderer from \"./renderer/CubeRenderer\";\nimport CubeStripRenderer from \"./renderer/CubeStripRenderer\";\nimport SphereRenderer from \"./renderer/SphereRenderer\";\nimport CylinderRenderer from \"./renderer/CylinderRenderer\";\nimport VRManager from \"./vr/VRManager\";\nimport XRManager from \"./vr/XRManager\";\nimport WebGLAnimator from \"./WebGLAnimator\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ImageType = PROJECTION_TYPE;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet DEVICE_PIXEL_RATIO = devicePixelRatio || 1;\n\n// DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다.\nif (DEVICE_PIXEL_RATIO > 2) {\n DEVICE_PIXEL_RATIO = 2;\n}\n\n// define custom events name\n/**\n * TODO: how to manage events/errortype with PanoViewer\n *\n * I think renderer events should be seperated from viewer events although it has same name.\n */\nconst EVENTS: {\n BIND_TEXTURE: \"bindTexture\";\n IMAGE_LOADED: \"imageLoaded\";\n ERROR: \"error\";\n RENDERING_CONTEXT_LOST: \"renderingContextLost\";\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\";\n} = {\n BIND_TEXTURE: \"bindTexture\",\n IMAGE_LOADED: \"imageLoaded\",\n ERROR: \"error\",\n RENDERING_CONTEXT_LOST: \"renderingContextLost\",\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\"\n};\n\nconst ERROR_TYPE = {\n INVALID_DEVICE: 10,\n NO_WEBGL: 11,\n FAIL_IMAGE_LOAD: 12,\n RENDERER_ERROR: 13\n};\n\nclass PanoImageRenderer extends Component<{\n [EVENTS.ERROR]: {\n type: number;\n message: string;\n };\n [EVENTS.IMAGE_LOADED]: {\n content: HTMLElement;\n isVideo: boolean;\n projectionType: ValueOf;\n };\n [EVENTS.BIND_TEXTURE]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_LOST]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_RESTORE]: ComponentEvent;\n}> {\n public static EVENTS = EVENTS;\n public static ERROR_TYPE = ERROR_TYPE;\n\n public sphericalConfig: {\n initialYaw: number;\n initialPitch: number;\n fieldOfView: number;\n imageType: ValueOf;\n stereoFormat: ValueOf;\n cubemapConfig: Partial;\n };\n\n public fieldOfView: number;\n public width: number;\n public height: number;\n\n public canvas: HTMLCanvasElement;\n public context: WebGLRenderingContext;\n public shaderProgram: WebGLProgram | null;\n public texture: WebGLTexture;\n\n public pMatrix: mat4;\n public mvMatrix: mat4;\n\n public textureCoordBuffer: WebGLBuffer | null = null;\n public vertexBuffer: WebGLBuffer | null = null;\n public indexBuffer: WebGLBuffer | null = null;\n\n private _wrapper: HTMLElement | null;\n private _wrapperOrigStyle: string | null;\n private _lastQuaternion: quat | null;\n private _lastYaw: number | null;\n private _lastPitch: number | null;\n private _lastFieldOfView: number | null;\n private _renderingContextAttributes?: WebGLContextAttributes;\n\n private _renderer: Renderer;\n private _contentLoader: ImReady | null;\n private _image: HTMLImageElement | HTMLImageElement[] | HTMLVideoElement | null;\n private _imageConfig: CubemapConfig | null;\n private _imageType: ValueOf;\n private _imageIsReady: boolean;\n private _isVideo: boolean;\n private _isCubeMap: boolean;\n private _shouldForceDraw: boolean;\n private _keepUpdate: boolean;\n private _hasExternalCanvas: boolean;\n\n private _yawPitchControl: YawPitchControl;\n private _animator: WebGLAnimator;\n private _vr: VRManager | XRManager | null;\n\n public constructor(\n image: ImageCandidate | VideoCandidate,\n width: number,\n height: number,\n isVideo: boolean,\n container: HTMLElement,\n canvasClass: string,\n sphericalConfig: PanoImageRenderer[\"sphericalConfig\"],\n renderingContextAttributes?: WebGLContextAttributes\n ) {\n // Super constructor\n super();\n\n this.sphericalConfig = sphericalConfig;\n this.fieldOfView = sphericalConfig.fieldOfView;\n\n this.width = width;\n this.height = height;\n\n this._lastQuaternion = null;\n this._lastYaw = null;\n this._lastPitch = null;\n this._lastFieldOfView = null;\n\n this.pMatrix = mat4.create();\n this.mvMatrix = mat4.create();\n\n // initialzie pMatrix\n mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), width / height, 0.1, 100);\n\n this.textureCoordBuffer = null;\n this.vertexBuffer = null;\n this.indexBuffer = null;\n\n this.canvas = this._initCanvas(container, canvasClass, width, height);\n\n this._setDefaultCanvasStyle();\n this._wrapper = null; // canvas wrapper\n this._wrapperOrigStyle = null;\n\n this._renderingContextAttributes = renderingContextAttributes;\n this._image = null;\n this._imageConfig = null;\n this._imageIsReady = false;\n this._shouldForceDraw = false;\n this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still.\n\n this._onContentLoad = this._onContentLoad.bind(this);\n this._onContentError = \tthis._onContentError.bind(this);\n\n this._animator = new WebGLAnimator();\n\n // VR/XR manager\n this._vr = null;\n\n if (image) {\n this.setImage({\n image,\n imageType: sphericalConfig.imageType,\n isVideo,\n cubemapConfig: sphericalConfig.cubemapConfig\n });\n }\n }\n\n // FIXME: Please refactor me to have more loose connection to yawpitchcontrol\n public setYawPitchControl(yawPitchControl: YawPitchControl) {\n this._yawPitchControl = yawPitchControl;\n }\n\n public getContent() {\n return this._image;\n }\n\n public setImage({\n image,\n imageType,\n isVideo = false,\n cubemapConfig\n }: {\n image: ImageCandidate | VideoCandidate;\n imageType: PanoImageRenderer[\"_imageType\"];\n isVideo: boolean;\n cubemapConfig: Partial;\n }) {\n this._imageIsReady = false;\n this._isVideo = isVideo;\n this._imageConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only */\n order: (imageType === ImageType.CUBEMAP) ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n },\n ...cubemapConfig\n };\n this._setImageType(imageType);\n\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._contentLoader = new ImReady()\n .on(\"ready\", this._onContentLoad)\n .on(\"error\", this._onContentError);\n\n if (isVideo) {\n this._image = toVideoElement(image as VideoCandidate);\n this._contentLoader.check([this._image]);\n this._keepUpdate = true;\n } else {\n this._image = toImageElement(image as ImageCandidate);\n this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n this._keepUpdate = false;\n }\n }\n\n public isImageLoaded() {\n return !!this._image && this._imageIsReady &&\n (!this._isVideo || (this._image as HTMLVideoElement).readyState >= 2 /* HAVE_CURRENT_DATA */);\n }\n\n public bindTexture() {\n return new Promise((res, rej) => {\n const contentLoader = this._contentLoader;\n\n if (!this._image) {\n return rej(\"Image is not defined\");\n }\n\n if (!contentLoader) {\n return rej(\"ImageLoader is not initialized\");\n }\n\n if (contentLoader.isReady()) {\n this._bindTexture();\n res();\n } else {\n contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n contentLoader.once(\"ready\", e => {\n if (e.errorCount > 0) {\n rej(\"Failed to load images.\");\n } else {\n this._bindTexture();\n res();\n }\n });\n }\n });\n }\n\n // 부모 엘리먼트에 canvas 를 붙임\n public attachTo(parentElement) {\n if (!this._hasExternalCanvas) {\n this.detach();\n parentElement.appendChild(this.canvas);\n }\n this._wrapper = parentElement;\n }\n\n public forceContextLoss() {\n if (this.hasRenderingContext()) {\n const loseContextExtension = this.context.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n\n // 부모 엘리먼트에서 canvas 를 제거\n public detach() {\n if (!this._hasExternalCanvas && this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n\n public destroy() {\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._animator.stop();\n this.detach();\n this.forceContextLoss();\n\n this.off();\n\n this.canvas.removeEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n this.canvas.removeEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n }\n\n public hasRenderingContext() {\n const ctx = this.context;\n if (\n !ctx\n || ctx.isContextLost()\n || !ctx.getProgramParameter(this.shaderProgram!, ctx.LINK_STATUS)) {\n return false;\n }\n return true;\n }\n\n public updateFieldOfView(fieldOfView) {\n this.fieldOfView = fieldOfView;\n this._updateViewport();\n }\n\n public updateViewportDimensions(width, height) {\n let viewPortChanged = false;\n\n this.width = width;\n this.height = height;\n\n const w = width * DEVICE_PIXEL_RATIO;\n const h = height * DEVICE_PIXEL_RATIO;\n\n if (w !== this.canvas.width) {\n this.canvas.width = w;\n viewPortChanged = true;\n }\n\n if (h !== this.canvas.height) {\n this.canvas.height = h;\n viewPortChanged = true;\n }\n\n if (!viewPortChanged) {\n return;\n }\n\n this._updateViewport();\n this._shouldForceDraw = true;\n }\n\n public keepUpdate(doUpdate) {\n if (doUpdate && this.isImageLoaded() === false) {\n // Force to draw a frame after image is loaded on render()\n this._shouldForceDraw = true;\n }\n\n this._keepUpdate = doUpdate;\n }\n\n public startRender() {\n this._animator.setCallback(this._render.bind(this));\n this._animator.start();\n }\n\n public stopRender() {\n this._animator.stop();\n }\n\n public renderWithQuaternion(quaternion, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // updatefieldOfView only if fieldOfView is changed.\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion);\n\n this._draw();\n\n this._lastQuaternion = quat.clone(quaternion);\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n public renderWithYawPitch(yaw, pitch, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastYaw !== null && this._lastYaw === yaw &&\n this._lastPitch !== null && this._lastPitch === pitch &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n mat4.identity(this.mvMatrix);\n mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch));\n mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw));\n\n this._draw();\n\n this._lastYaw = yaw;\n this._lastPitch = pitch;\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n /**\n * Returns projection renderer by each type\n */\n public getProjectionRenderer() {\n return this._renderer;\n }\n\n /**\n * @return Promise\n */\n public enterVR(options) {\n const vr = this._vr;\n\n if (!WEBXR_SUPPORTED && !(navigator as any).getVRDisplays) {\n return Promise.reject(\"VR is not available on this browser.\");\n }\n if (vr && vr.isPresenting()) {\n return Promise.resolve(\"VR already enabled.\");\n }\n\n return this._requestPresent(options);\n }\n\n public exitVR = () => {\n const vr = this._vr;\n const gl = this.context;\n const animator = this._animator;\n\n if (!vr) return;\n\n vr.removeEndCallback(this.exitVR);\n vr.destroy();\n this._vr = null;\n\n // Restore canvas & context on iOS\n if (IS_IOS) {\n this._restoreStyle();\n }\n this.updateViewportDimensions(this.width, this.height);\n this._updateViewport();\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._bindBuffers();\n this._shouldForceDraw = true;\n\n animator.stop();\n animator.setContext(window);\n animator.setCallback(this._render.bind(this));\n animator.start();\n };\n\n private _setImageType(imageType) {\n if (!imageType || this._imageType === imageType) {\n return;\n }\n\n this._imageType = imageType;\n this._isCubeMap = imageType === ImageType.CUBEMAP;\n\n if (this._renderer) {\n this._renderer.off();\n }\n\n switch (imageType) {\n case ImageType.CUBEMAP:\n this._renderer = new CubeRenderer();\n break;\n case ImageType.CUBESTRIP:\n this._renderer = new CubeStripRenderer();\n break;\n case ImageType.PANORAMA:\n this._renderer = new CylinderRenderer();\n break;\n case ImageType.STEREOSCOPIC_EQUI:\n this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat);\n break;\n default:\n this._renderer = new SphereRenderer(STEREO_FORMAT.NONE);\n break;\n }\n\n this._renderer.on(Renderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERER_ERROR,\n message: e.message\n }));\n });\n\n this._initWebGL();\n }\n\n private _initCanvas(container: HTMLElement, canvasClass: string, width: number, height: number) {\n const canvasInContainer = container.querySelector(`.${canvasClass}`);\n const canvas = canvasInContainer || this._createCanvas(canvasClass);\n\n this._hasExternalCanvas = !!canvasInContainer;\n\n canvas.width = width;\n canvas.height = height;\n\n this._onWebglcontextlost = this._onWebglcontextlost.bind(this);\n this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this);\n\n canvas.addEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n canvas.addEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n\n return canvas;\n }\n\n private _createCanvas(className: string) {\n const canvas = document.createElement(\"canvas\");\n\n canvas.className = className;\n\n return canvas;\n }\n\n private _setDefaultCanvasStyle() {\n const canvas = this.canvas;\n\n canvas.style.bottom = \"0\";\n canvas.style.left = \"0\";\n canvas.style.right = \"0\";\n canvas.style.top = \"0\";\n canvas.style.margin = \"auto\";\n canvas.style.maxHeight = \"100%\";\n canvas.style.maxWidth = \"100%\";\n canvas.style.outline = \"none\";\n canvas.style.position = \"absolute\";\n }\n\n private _onContentError() {\n this._imageIsReady = false;\n this._image = null;\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_IMAGE_LOAD,\n message: \"failed to load image\"\n }));\n\n return false;\n }\n\n private _triggerContentLoad() {\n this.trigger(new ComponentEvent(EVENTS.IMAGE_LOADED, {\n content: this._image as HTMLElement,\n isVideo: this._isVideo,\n projectionType: this._imageType\n }));\n }\n\n private _onContentLoad(e: OnReady) {\n if (e.errorCount > 0) return;\n\n this._imageIsReady = true;\n\n this._triggerContentLoad();\n }\n\n private _initShaderProgram() {\n const gl = this.context;\n\n if (this.shaderProgram) {\n gl.deleteProgram(this.shaderProgram);\n this.shaderProgram = null;\n }\n\n const renderer = this._renderer;\n\n const vsSource = renderer.getVertexShaderSource();\n const fsSource = renderer.getFragmentShaderSource();\n\n const vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource)!;\n const fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource)!;\n\n const shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader);\n\n if (!shaderProgram) {\n throw new Error(`Failed to initialize shaders: ${WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())}`);\n }\n\n gl.useProgram(shaderProgram);\n (shaderProgram as any).vertexPositionAttribute = gl.getAttribLocation(shaderProgram, \"aVertexPosition\");\n (shaderProgram as any).pMatrixUniform = gl.getUniformLocation(shaderProgram, \"uPMatrix\");\n (shaderProgram as any).mvMatrixUniform = gl.getUniformLocation(shaderProgram, \"uMVMatrix\");\n (shaderProgram as any).samplerUniform = gl.getUniformLocation(shaderProgram, \"uSampler\");\n (shaderProgram as any).textureCoordAttribute = gl.getAttribLocation(shaderProgram, \"aTextureCoord\");\n (shaderProgram as any).uEye = gl.getUniformLocation(shaderProgram, \"uEye\");\n\n gl.enableVertexAttribArray((shaderProgram as any).vertexPositionAttribute);\n gl.enableVertexAttribArray((shaderProgram as any).textureCoordAttribute);\n\n // clear buffer\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\n // Use TEXTURE0\n gl.uniform1i((shaderProgram as any).samplerUniform, 0);\n\n this.shaderProgram = shaderProgram;\n }\n\n private _onWebglcontextlost(e) {\n e.preventDefault();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_LOST));\n }\n\n private _onWebglcontextrestored() {\n this._initWebGL();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_RESTORE));\n }\n\n private _updateViewport() {\n mat4.perspective(\n this.pMatrix,\n glMatrix.toRadian(this.fieldOfView),\n this.canvas.width / this.canvas.height,\n 0.1,\n 100);\n\n this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight);\n }\n\n private _initWebGL() {\n let gl: WebGLRenderingContext;\n\n // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed.\n try {\n this._initRenderingContext();\n gl = this.context;\n\n this.updateViewportDimensions(this.width, this.height);\n this._initShaderProgram();\n } catch (e) {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n this.destroy();\n console.error(e); // eslint-disable-line no-console\n return;\n }\n // 캔버스를 투명으로 채운다.\n gl.clearColor(0, 0, 0, 0);\n const textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\n\n if (this.texture) {\n gl.deleteTexture(this.texture);\n }\n\n this.texture = WebGLUtils.createTexture(gl, textureTarget)!;\n\n if (this._imageType === ImageType.CUBESTRIP) {\n // TODO: Apply following options on other projection type.\n gl.enable(gl.CULL_FACE);\n // gl.enable(gl.DEPTH_TEST);\n }\n }\n\n private _initRenderingContext() {\n if (this.hasRenderingContext()) {\n return;\n }\n\n if (!window.WebGLRenderingContext) {\n throw new Error(\"WebGLRenderingContext not available.\");\n }\n\n this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes)!;\n\n if (!this.context) {\n throw new Error(\"Failed to acquire 3D rendering context\");\n }\n }\n\n private _initBuffers() {\n const image = this._image as HTMLImageElement | HTMLVideoElement;\n\n const vertexPositionData = this._renderer.getVertexPositionData();\n const indexData = this._renderer.getIndexData();\n const textureCoordData = this._renderer.getTextureCoordData({\n image,\n imageConfig: this._imageConfig!\n });\n const gl = this.context;\n\n this.vertexBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3,\n (this.shaderProgram as any).vertexPositionAttribute);\n\n this.indexBuffer = WebGLUtils.initBuffer(\n gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1);\n\n this.textureCoordBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2,\n (this.shaderProgram as any).textureCoordAttribute);\n\n this._bindBuffers();\n }\n\n private _bindTexture() {\n // Detect if it is EAC Format while CUBESTRIP mode.\n // We assume it is EAC if image is not 3/2 ratio.\n if (this._imageType === ImageType.CUBESTRIP) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const isEAC = width && height && width / height !== 1.5 ? 1 : 0;\n\n this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram!, \"uIsEAC\"), isEAC);\n } else if (this._imageType === ImageType.PANORAMA) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const imageAspectRatio = width && height && width / height;\n\n this._renderer.updateShaderData({imageAspectRatio});\n }\n\n // initialize shader buffers after image is loaded.(by updateShaderData)\n // because buffer may be differ by image size.(eg. CylinderRenderer)\n this._initBuffers();\n\n this._renderer.bindTexture(\n this.context,\n this.texture,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n this._shouldForceDraw = true;\n\n this.trigger(new ComponentEvent(EVENTS.BIND_TEXTURE));\n }\n\n private _updateTexture() {\n this._renderer.updateTexture(\n this.context,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n }\n\n private _render() {\n const yawPitchControl = this._yawPitchControl;\n const fov = yawPitchControl.getFov();\n\n if (yawPitchControl.shouldRenderWithQuaternion()) {\n const quaternion = yawPitchControl.getQuaternion();\n\n this.renderWithQuaternion(quaternion, fov);\n } else {\n const yawPitch = yawPitchControl.getYawPitch();\n\n this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov);\n }\n }\n\n private _renderStereo = (time: number, frame: XRFrame) => {\n const vr = this._vr;\n const gl = this.context;\n\n const eyeParams = vr!.getEyeParams(gl, frame);\n\n if (!eyeParams) return;\n\n vr!.beforeRender(gl, frame);\n\n // Render both eyes\n for (const eyeIndex of [0, 1]) {\n const eyeParam = eyeParams[eyeIndex];\n\n this.mvMatrix = eyeParam.mvMatrix;\n this.pMatrix = eyeParam.pMatrix;\n\n gl.viewport(...eyeParam.viewport as [number, number, number, number]);\n gl.uniform1f((this.shaderProgram as any).uEye, eyeIndex);\n\n this._bindBuffers();\n this._draw();\n }\n\n vr!.afterRender();\n };\n\n private _bindBuffers() {\n const gl = this.context;\n const program = this.shaderProgram;\n\n const vertexBuffer = this.vertexBuffer;\n const textureCoordBuffer = this.textureCoordBuffer;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray((program as any).vertexPositionAttribute);\n gl.vertexAttribPointer(\n (program as any).vertexPositionAttribute, (vertexBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);\n gl.enableVertexAttribArray((program as any).textureCoordAttribute);\n gl.vertexAttribPointer(\n (program as any).textureCoordAttribute, (textureCoordBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n }\n\n private _draw() {\n if (this._isVideo && this._keepUpdate) {\n this._updateTexture();\n }\n\n this._renderer.render({\n gl: this.context,\n shaderProgram: this.shaderProgram!,\n indexBuffer: this.indexBuffer!,\n mvMatrix: this.mvMatrix,\n pMatrix: this.pMatrix\n });\n }\n\n private _requestPresent(options) {\n const gl = this.context;\n const canvas = this.canvas;\n const animator = this._animator;\n\n this._vr = WEBXR_SUPPORTED ?\n new XRManager(options) :\n new VRManager();\n\n const vr = this._vr;\n\n animator.stop();\n return new Promise((resolve, reject) => {\n vr.requestPresent(canvas, gl)\n .then(() => {\n vr.addEndCallback(this.exitVR);\n animator.setContext(vr.context);\n animator.setCallback(this._onFirstVRFrame);\n\n if (IS_IOS) {\n this._setWrapperFullscreen();\n }\n\n this._shouldForceDraw = true;\n animator.start();\n\n resolve(\"success\");\n })\n .catch(e => {\n vr.destroy();\n this._vr = null;\n animator.start();\n\n reject(e);\n });\n });\n }\n\n private _onFirstVRFrame = (time, frame) => {\n const vr = this._vr!;\n const gl = this.context;\n const animator = this._animator;\n\n // If rendering is not ready, wait for next frame\n if (!vr.canRender(frame)) return;\n\n const minusZDir = vec3.fromValues(0, 0, -1);\n const eyeParam = vr.getEyeParams(gl, frame)![0];\n // Extract only rotation\n const mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix);\n const pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix);\n\n const mvInv = mat3.invert(mat3.create(), mvMatrix);\n const pInv = mat3.invert(mat3.create(), pMatrix);\n const viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv);\n\n vec3.transformMat3(viewDir, viewDir, mvInv);\n\n const yawOffset = mathUtil.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1));\n\n if (yawOffset === 0) {\n // If the yawOffset is exactly 0, then device sensor is not ready\n // So read it again until it has any value in it\n return;\n }\n\n vr.setYawOffset(yawOffset);\n animator.setCallback(this._renderStereo);\n };\n\n private _setWrapperFullscreen() {\n const wrapper = this._wrapper;\n\n if (!wrapper) return;\n\n this._wrapperOrigStyle = wrapper.getAttribute(\"style\");\n const wrapperStyle = wrapper.style;\n\n wrapperStyle.width = \"100vw\";\n wrapperStyle.height = \"100vh\";\n wrapperStyle.position = \"fixed\";\n wrapperStyle.left = \"0\";\n wrapperStyle.top = \"0\";\n wrapperStyle.zIndex = \"9999\";\n }\n\n private _restoreStyle() {\n const wrapper = this._wrapper;\n const canvas = this.canvas;\n\n if (!wrapper) return;\n\n if (this._wrapperOrigStyle) {\n wrapper.setAttribute(\"style\", this._wrapperOrigStyle);\n } else {\n wrapper.removeAttribute(\"style\");\n }\n\n this._wrapperOrigStyle = null;\n\n // Restore canvas style\n canvas.removeAttribute(\"style\");\n this._setDefaultCanvasStyle();\n }\n}\n\nexport default PanoImageRenderer;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Promise from \"promise-polyfill\";\nimport { quat } from \"gl-matrix\";\n\nimport { DeviceMotionEvent, checkXRSupport } from \"../utils/browserFeature\";\nimport YawPitchControl, { YawPitchControlOptions } from \"../YawPitchControl/YawPitchControl\";\nimport PanoImageRenderer from \"../PanoImageRenderer/PanoImageRenderer\";\nimport WebGLUtils from \"../PanoImageRenderer/WebGLUtils\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { CubemapConfig, ValueOf } from \"../types/internal\";\nimport { AnimationEndEvent, ReadyEvent, ViewChangeEvent, ErrorEvent } from \"../types/event\";\n\nimport { ERROR_TYPE, PANOVIEWER_EVENTS as EVENTS, GYRO_MODE, PROJECTION_TYPE, STEREO_FORMAT, DEFAULT_CANVAS_CLASS } from \"./consts\";\n\nexport interface PanoViewerOptions {\n image: string | HTMLElement;\n video: string | HTMLElement;\n projectionType: ValueOf;\n cubemapConfig: Partial;\n stereoFormat: ValueOf;\n width: number;\n height: number;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n touchDirection: ValueOf;\n canvasClass: string;\n}\n\nexport interface PanoViewerEvent {\n ready: ReadyEvent;\n viewChange: ViewChangeEvent;\n animationEnd: AnimationEndEvent;\n error: ErrorEvent;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * PanoViewer\n */\nclass PanoViewer extends Component {\n /**\n * Check whether the current environment can execute PanoViewer\n * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다.\n * @return PanoViewer executable PanoViewer 실행가능 여부\n */\n public static isSupported(): boolean {\n return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL();\n }\n\n /**\n * Check whether the current environment supports the WebGL\n * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다.\n * @return WebGL support WebGL 지원여부\n */\n public static isWebGLAvailable(): boolean {\n return WebGLUtils.isWebGLAvailable();\n }\n\n /**\n * Check whether the current environment supports the gyro sensor.\n * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다.\n * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수\n */\n public static isGyroSensorAvailable(callback: (isAvailable: boolean) => any) {\n if (!DeviceMotionEvent && callback) {\n callback(false);\n return;\n }\n\n let onDeviceMotionChange;\n\n const checkGyro = () => new Promise(res => {\n onDeviceMotionChange = deviceMotion => {\n const isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null);\n\n res(isGyroSensorAvailable);\n };\n\n window.addEventListener(\"devicemotion\", onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n Promise.race([checkGyro(), timeout()]).then((isGyroSensorAvailable: boolean) => {\n window.removeEventListener(\"devicemotion\", onDeviceMotionChange);\n\n if (callback) {\n callback(isGyroSensorAvailable);\n }\n\n PanoViewer.isGyroSensorAvailable = fb => {\n if (fb) {\n fb(isGyroSensorAvailable);\n }\n return isGyroSensorAvailable;\n };\n });\n }\n\n private static _isValidTouchDirection(direction) {\n return direction === PanoViewer.TOUCH_DIRECTION.NONE ||\n direction === PanoViewer.TOUCH_DIRECTION.YAW ||\n direction === PanoViewer.TOUCH_DIRECTION.PITCH ||\n direction === PanoViewer.TOUCH_DIRECTION.ALL;\n }\n\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @name VERSION\n * @static\n * @type {String}\n * @example\n * eg.view360.PanoViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.PanoViewer\n */\n public static VERSION = VERSION;\n public static ERROR_TYPE = ERROR_TYPE;\n public static EVENTS = EVENTS;\n public static PROJECTION_TYPE = PROJECTION_TYPE;\n public static GYRO_MODE = GYRO_MODE;\n // This should be deprecated!\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static ProjectionType = PROJECTION_TYPE;\n public static STEREO_FORMAT = STEREO_FORMAT;\n\n /**\n * Constant value for touch directions\n * @ko 터치 방향에 대한 상수 값.\n * @namespace\n * @name TOUCH_DIRECTION\n */\n public static TOUCH_DIRECTION = {\n /**\n * Constant value for none direction.\n * @ko none 방향에 대한 상수 값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 1\n */\n NONE: YawPitchControl.TOUCH_DIRECTION_NONE,\n /**\n * Constant value for horizontal(yaw) direction.\n * @ko horizontal(yaw) 방향에 대한 상수 값.\n * @name YAW\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 6\n */\n YAW: YawPitchControl.TOUCH_DIRECTION_YAW,\n /**\n * Constant value for vertical direction.\n * @ko vertical(pitch) 방향에 대한 상수 값.\n * @name PITCH\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 24\n */\n PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH,\n /**\n * Constant value for all direction.\n * @ko all 방향에 대한 상수 값.\n * @name ALL\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 30\n */\n ALL: YawPitchControl.TOUCH_DIRECTION_ALL\n };\n\n private _container: HTMLElement;\n // Options\n private _image: ConstructorParameters[0];\n private _isVideo: boolean;\n private _projectionType: ValueOf;\n private _cubemapConfig: Partial;\n private _stereoFormat: ValueOf;\n private _width: number;\n private _height: number;\n private _yaw: number;\n private _pitch: number;\n private _fov: number;\n private _gyroMode: ValueOf;\n private _quaternion: quat | null;\n private _aspectRatio: number;\n private _isReady: boolean;\n private _canvasClass: string;\n\n // Internal Values\n private _photoSphereRenderer: PanoImageRenderer | null;\n private _yawPitchControl: YawPitchControl | null;\n\n /**\n * @classdesc 360 media viewer\n * @ko 360 미디어 뷰어\n *\n * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트\n * @param options\n *\n * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
\n * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다.\n * @param {Object} [options.cubemapConfig.order = \"RLUDBF\"(ProjectionType === CUBEMAP) | \"RLUDFB\" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서\n * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다.\n * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다.\n * @param {String} [options.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
\n * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위)\n * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위)\n * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위)\n * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위)\n * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위)\n * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다\n * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다.\n * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키\n * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE}
\n * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위\n * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위\n * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위\n * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
\n * @param {String} [options.canvasClass=\"view360-canvas\"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n *\n * @example\n * ```\n * // PanoViewer Creation\n * // create PanoViewer with option\n * var PanoViewer = eg.view360.PanoViewer;\n * // Area where the image will be displayed(HTMLElement)\n * var container = document.getElementById(\"myPanoViewer\");\n *\n * var panoViewer = new PanoViewer(container, {\n * // If projectionType is not specified, the default is \"equirectangular\".\n * // Specifies an image of the \"equirectangular\" type.\n * image: \"/path/to/image/image.jpg\"\n * });\n * ```\n *\n * @example\n * ```\n * // Cubemap Config Setting Example\n * // For support Youtube EAC projection, You should set cubemapConfig as follows.\n * cubemapConfig: {\n * order: \"LFRDBU\",\n * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}]\n * }\n * ```\n */\n public constructor(container: HTMLElement, options: Partial = {}) {\n super();\n\n // Raises the error event if webgl is not supported.\n if (!WebGLUtils.isWebGLAvailable()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n }, 0);\n return this;\n }\n\n if (!WebGLUtils.isStableWebGL()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_DEVICE,\n message: \"blacklisted browser\"\n }));\n }, 0);\n\n return this;\n }\n\n if (!!options.image && !!options.video) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_RESOURCE,\n message: \"Specifying multi resouces(both image and video) is not valid.\"\n }));\n }, 0);\n return this;\n }\n\n // Check XR support at not when imported, but when created.\n // This is intended to make polyfills easier to use.\n checkXRSupport();\n\n this._container = container;\n this._image = options.image! as HTMLImageElement || options.video! as HTMLVideoElement;\n this._isVideo = !!options.video;\n this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/\n order: this._projectionType === PROJECTION_TYPE.CUBEMAP ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...options.cubemapConfig\n };\n this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n\n // If the width and height are not provided, will use the size of the container.\n this._width = options.width || parseInt(window.getComputedStyle(container).width, 10);\n this._height = options.height || parseInt(window.getComputedStyle(container).height, 10);\n\n /**\n * Cache the direction for the performance in renderLoop\n *\n * This value should be updated by \"change\" event of YawPitchControl.\n */\n this._yaw = options.yaw || 0;\n this._pitch = options.pitch || 0;\n this._fov = options.fov || 65;\n\n this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH;\n this._quaternion = null;\n\n this._aspectRatio = this._height !== 0 ? this._width / this._height : 1;\n\n this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS;\n\n const fovRange = options.fovRange || [30, 110];\n const touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ?\n options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL;\n const yawPitchConfig = {\n ...options,\n ...{\n element: container,\n yaw: this._yaw,\n pitch: this._pitch,\n fov: this._fov,\n gyroMode: this._gyroMode,\n fovRange,\n aspectRatio: this._aspectRatio,\n touchDirection\n }\n };\n\n this._isReady = false;\n\n this._initYawPitchControl(yawPitchConfig);\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n /**\n * Get the video element that the viewer is currently playing. You can use this for playback.\n * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다.\n * @return HTMLVideoElementHTMLVideoElement\n * @example\n * ```\n * var videoTag = panoViewer.getVideo();\n * videoTag.play(); // play the video!\n * ```\n */\n public getVideo() {\n if (!this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent() as HTMLVideoElement;\n }\n\n /**\n * Set the video information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정)\n * @param {object} param\n * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}(\"equirectangular\")] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setVideo(\"/path/to/video/video.mp4\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR\n * });\n * ```\n */\n public setVideo(video: string | HTMLElement | { type: string; src: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n }> = {}) {\n if (video) {\n this.setImage(video, {\n projectionType: param.projectionType,\n isVideo: true,\n cubemapConfig: param.cubemapConfig,\n stereoFormat: param.stereoFormat\n });\n }\n\n return this;\n }\n\n /**\n * Get the image information that the viewer is currently using.\n * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다.\n * @return Image Object이미지 객체\n * @example\n * var imageObj = panoViewer.getImage();\n */\n public getImage() {\n if (this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent();\n }\n\n /**\n * Set the image information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.)\n * @param {object} param Additional information이미지 추가 정보\n * @param {string} [param.projectionType=\"equirectangular\"] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setImage(\"/path/to/image/image.png\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP\n * });\n * ```\n */\n public setImage(image: string | HTMLElement | { src: string; type: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n isVideo: boolean;\n }> = {}) {\n const cubemapConfig = {\n ...{\n order: \"RLUDBF\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...param.cubemapConfig\n };\n const stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n const isVideo = !!(param.isVideo);\n\n if (this._image && this._isVideo !== isVideo) {\n /* eslint-disable no-console */\n console.warn(\"PanoViewer is not currently supporting content type changes. (Image <--> Video)\");\n /* eslint-enable no-console */\n return this;\n }\n\n if (image) {\n this._deactivate();\n\n this._image = image as HTMLImageElement;\n this._isVideo = isVideo;\n this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = cubemapConfig;\n this._stereoFormat = stereoFormat;\n\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n return this;\n }\n\n /**\n * Set whether the renderer always updates the texture and renders.\n * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다.\n * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public keepUpdate(doUpdate: boolean) {\n this._photoSphereRenderer!.keepUpdate(doUpdate);\n return this;\n }\n\n /**\n * Get the current projection type (equirectangular/cube)\n * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다.\n * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE}\n */\n public getProjectionType() {\n return this._projectionType;\n }\n\n /**\n * Activate the device's motion sensor, and return the Promise whether the sensor is enabled\n * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element.\n * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다.\n * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다.\n */\n public enableSensor() {\n return new Promise((resolve, reject) => {\n if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\") {\n DeviceMotionEvent.requestPermission().then(permissionState => {\n if (permissionState === \"granted\") {\n resolve();\n } else {\n reject(new Error(\"permission denied\"));\n }\n }).catch(e => {\n // This can happen when this method wasn't triggered by user interaction\n reject(e);\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Disable the device's motion sensor.\n * @ko 디바이스의 모션 센서를 비활성화합니다.\n * @deprecated\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public disableSensor() {\n return this;\n }\n\n /**\n * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred).\n * This method must be used in the context of user interaction, like onclick callback on the button element.\n * It can be rejected when an enabling device sensor fails or image/video is still loading(\"ready\" event not triggered).\n * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다)\n * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우(\"ready\"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다.\n * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요.\n * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error)\n */\n public enterVR(options: {\n requiredFeatures?: any[];\n optionalFeatures?: any[];\n [key: string]: any;\n } = {}): globalThis.Promise {\n if (!this._isReady) {\n return Promise.reject(new Error(\"PanoViewer is not ready to show image.\")) as any;\n }\n\n return new Promise((resolve, reject) => {\n this.enableSensor()\n .then(() => this._photoSphereRenderer!.enterVR(options))\n .then((res: string) => resolve(res))\n .catch(e => reject(e));\n }) as any;\n }\n\n /**\n * Exit VR stereo rendering mode.\n * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public exitVR() {\n this._photoSphereRenderer!.exitVR();\n return this;\n }\n\n /**\n * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}.\n * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다.\n * @param useZoom\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseZoom(useZoom: boolean): this {\n if (typeof useZoom === \"boolean\") {\n this._yawPitchControl!.option(\"useZoom\", useZoom);\n }\n\n return this;\n }\n\n /**\n * When true, enables the keyboard move key control: awsd, arrow keys\n * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키)\n * @param useKeyboard\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseKeyboard(useKeyboard: boolean): this {\n this._yawPitchControl!.option(\"useKeyboard\", useKeyboard);\n return this;\n }\n\n /**\n * Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")\n * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")\n * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE}\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setGyroMode(\"yawPitch\");\n * //equivalent\n * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH);\n * ```\n */\n public setGyroMode(gyroMode: PanoViewer[\"_gyroMode\"]) {\n this._yawPitchControl!.option(\"gyroMode\", gyroMode);\n return this;\n }\n\n /**\n * Set the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 설정합니다.\n * @param range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setFovRange([50, 90]);\n */\n public setFovRange(range: number[]) {\n this._yawPitchControl!.option(\"fovRange\", range);\n return this;\n }\n\n /**\n * Get the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 반환합니다.\n * @return FOV range\n * @example\n * var range = panoViewer.getFovRange(); // [50, 90]\n */\n public getFovRange(): [number, number] {\n return this._yawPitchControl!.option(\"fovRange\") as [number, number];\n }\n\n /**\n * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size.\n * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다.\n * @param {object} [size]\n * @param {number} [size.width=width of the container]\n * @param {number} [size.height=height of the container]\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public updateViewportDimensions(size: Partial<{\n width: number;\n height: number;\n }> = {}): this {\n if (!this._isReady) {\n return this;\n }\n\n let containerSize;\n\n if (size.width === undefined || size.height === undefined) {\n containerSize = window.getComputedStyle(this._container);\n }\n\n const width = size.width || parseInt(containerSize.width, 10);\n const height = size.height || parseInt(containerSize.height, 10);\n\n // Skip if viewport is not changed.\n if (width === this._width && height === this._height) {\n return this;\n }\n\n this._width = width;\n this._height = height;\n\n this._aspectRatio = width / height;\n this._photoSphereRenderer!.updateViewportDimensions(width, height);\n this._yawPitchControl!.option(\"aspectRatio\", this._aspectRatio);\n this._yawPitchControl!.updatePanScale({height});\n\n this.lookAt({}, 0);\n return this;\n }\n\n /**\n * Get the current field of view(FOV)\n * @ko 현재 field of view(FOV) 값을 반환합니다.\n */\n public getFov(): number {\n return this._fov;\n }\n\n /**\n * Get current yaw value\n * @ko 현재 yaw 값을 반환합니다.\n */\n public getYaw() {\n return this._yaw;\n }\n\n /**\n * Get current pitch value\n * @ko 현재 pitch 값을 반환합니다.\n */\n public getPitch() {\n return this._pitch;\n }\n\n /**\n * Get the range of controllable Yaw values\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n */\n public getYawRange(): [number, number] {\n return this._yawPitchControl!.option(\"yawRange\") as [number, number];\n }\n\n /**\n * Get the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다.\n */\n public getPitchRange(): [number, number] {\n return this._yawPitchControl!.option(\"pitchRange\") as [number, number];\n }\n\n /**\n * Set the range of controllable yaw\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setYawRange([-90, 90]);\n */\n public setYawRange(yawRange: number[]) {\n this._yawPitchControl!.option(\"yawRange\", yawRange);\n return this;\n }\n\n /**\n * Set the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 설정합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setPitchRange([-40, 40]);\n */\n public setPitchRange(pitchRange: number[]) {\n this._yawPitchControl!.option(\"pitchRange\", pitchRange);\n return this;\n }\n\n /**\n * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed.\n * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다.\n * @param showPolePoint\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setShowPolePoint(showPolePoint: boolean) {\n this._yawPitchControl!.option(\"showPolePoint\", showPolePoint);\n return this;\n }\n\n /**\n * Set a new view by setting camera configuration. Any parameters not specified remain the same.\n * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다.\n * @param {object} orientation\n * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위)\n * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위)\n * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위)\n * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초)\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * // Change the yaw angle (absolute angle) to 30 degrees for one second.\n * panoViewer.lookAt({yaw: 30}, 1000);\n * ```\n */\n public lookAt(orientation: Partial<{\n yaw: number;\n pitch: number;\n fov: number;\n }>, duration: number = 0) {\n if (!this._isReady) {\n return this;\n }\n\n const yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw;\n const pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch;\n const pitchRange = this._yawPitchControl!.option(\"pitchRange\");\n const verticalAngleOfImage = pitchRange[1] - pitchRange[0];\n let fov = orientation.fov !== undefined ? orientation.fov : this._fov;\n\n if (verticalAngleOfImage < fov) {\n fov = verticalAngleOfImage;\n }\n\n this._yawPitchControl!.lookAt({yaw, pitch, fov}, duration);\n\n if (duration === 0) {\n this._photoSphereRenderer!.renderWithYawPitch(yaw, pitch, fov);\n }\n return this;\n }\n\n /**\n * Set touch direction by which user can control.\n * @ko 사용자가 조작가능한 터치 방향을 지정합니다.\n * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @return PanoViewer instance\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Limit the touch direction to the yaw direction only.\n * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW);\n * ```\n */\n public setTouchDirection(direction: number): this {\n if (PanoViewer._isValidTouchDirection(direction)) {\n this._yawPitchControl!.option(\"touchDirection\", direction);\n }\n\n return this;\n }\n\n /**\n * Returns touch direction by which user can control\n * @ko 사용자가 조작가능한 터치 방향을 반환한다.\n * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Returns the current touch direction.\n * var dir = panoViewer.getTouchDirection();\n * ```\n */\n public getTouchDirection(): number {\n return this._yawPitchControl!.option(\"touchDirection\") ;\n }\n\n /**\n * Destroy viewer. Remove all registered event listeners and remove viewer canvas.\n * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public destroy(): this {\n this._deactivate();\n\n if (this._yawPitchControl) {\n this._yawPitchControl.destroy();\n this._yawPitchControl = null;\n }\n\n return this;\n }\n\n // TODO: Remove parameters as they're just using private values\n private _initRenderer(\n yaw: number,\n pitch: number,\n fov: number,\n projectionType: PanoViewer[\"_projectionType\"],\n cubemapConfig: PanoViewer[\"_cubemapConfig\"]\n ) {\n this._photoSphereRenderer = new PanoImageRenderer(\n this._image,\n this._width,\n this._height,\n this._isVideo,\n this._container,\n this._canvasClass,\n {\n initialYaw: yaw,\n initialPitch: pitch,\n fieldOfView: fov,\n imageType: projectionType,\n cubemapConfig,\n stereoFormat: this._stereoFormat\n },\n );\n this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl!);\n\n this._bindRendererHandler();\n\n this._photoSphereRenderer\n .bindTexture()\n .then(() => this._activate())\n .catch(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_BIND_TEXTURE,\n message: \"failed to bind texture\"\n }));\n });\n }\n\n /**\n * @private\n * update values of YawPitchControl if needed.\n * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image.\n *\n * This function should be called after isReady status is true.\n */\n private _updateYawPitchIfNeeded() {\n if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) {\n // update fov by aspect ratio\n const image = this._photoSphereRenderer!.getContent()! as HTMLImageElement;\n let imageAspectRatio = image.naturalWidth / image.naturalHeight;\n let yawSize;\n let maxFov;\n\n // If height is larger than width, then we assume it's rotated by 90 degree.\n if (imageAspectRatio < 1) {\n // So inverse the aspect ratio.\n imageAspectRatio = 1 / imageAspectRatio;\n }\n\n if (imageAspectRatio < 6) {\n yawSize = mathUtil.toDegree(imageAspectRatio);\n // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5\n maxFov = mathUtil.toDegree(Math.atan(0.5)) * 2;\n } else {\n yawSize = 360;\n maxFov = (360 / imageAspectRatio); // Make it 5 fixed as axes does.\n }\n\n // console.log(\"_updateYawPitchIfNeeded\", maxFov, \"aspectRatio\", image.naturalWidth, image.naturalHeight, \"yawSize\", yawSize);\n const minFov = (this._yawPitchControl!.option(\"fovRange\"))[0];\n\n // this option should be called after fov is set.\n this._yawPitchControl!.option({\n \"fov\": maxFov, /* parameter for internal validation for pitchrange */\n \"yawRange\": [-yawSize / 2, yawSize / 2],\n \"pitchRange\": [-maxFov / 2, maxFov / 2],\n \"fovRange\": [minFov, maxFov]\n });\n this.lookAt({fov: maxFov});\n }\n }\n\n private\t_bindRendererHandler() {\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, e));\n });\n\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, () => {\n this._deactivate();\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERING_CONTEXT_LOST,\n message: \"webgl rendering context lost\"\n }));\n });\n }\n\n private _initYawPitchControl(yawPitchConfig: Partial) {\n this._yawPitchControl = new YawPitchControl(yawPitchConfig);\n\n this._yawPitchControl.on(EVENTS.ANIMATION_END, e => {\n this.trigger(new ComponentEvent(EVENTS.ANIMATION_END, e));\n });\n\n this._yawPitchControl.on(\"change\", e => {\n this._yaw = e.yaw;\n this._pitch = e.pitch;\n this._fov = e.fov;\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(EVENTS.VIEW_CHANGE, {\n yaw: e.yaw,\n pitch: e.pitch,\n fov: e.fov,\n quaternion: e.quaternion,\n isTrusted: e.isTrusted\n }));\n });\n }\n\n private _activate() {\n this._photoSphereRenderer!.attachTo(this._container);\n this._yawPitchControl!.enable();\n\n this.updateViewportDimensions();\n\n this._isReady = true;\n\n // update yawPitchControl after isReady status is true.\n this._updateYawPitchIfNeeded();\n\n this.trigger(new ComponentEvent(EVENTS.READY));\n this._photoSphereRenderer!.startRender();\n }\n\n /**\n * Destroy webgl context and block user interaction and stop rendering\n */\n private _deactivate() {\n // Turn off the video if it has one\n const video = this.getVideo();\n if (video) {\n video.pause();\n }\n\n if (this._isReady) {\n this._photoSphereRenderer!.stopRender();\n this._yawPitchControl!.disable();\n this._isReady = false;\n }\n\n if (this._photoSphereRenderer) {\n this._photoSphereRenderer.destroy();\n this._photoSphereRenderer = null;\n }\n }\n}\n\nexport default PanoViewer;\n\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { VERSION } from \"../version\";\nimport { merge } from \"../utils/utils\";\n\nimport PanoViewer from \"./PanoViewer\";\nimport * as Constants from \"./consts\";\n\nconst PanoViewerModule = {\n PanoViewer,\n VERSION\n};\n\nmerge(PanoViewerModule, Constants);\n\nexport default PanoViewerModule;\n"],"names":["VERSION","merge","target","_i","srcs","forEach","source","Object","keys","key","value","Array","isArray","toImageElement","image","images","parsedImages","map","img","imgEl","Image","crossOrigin","src","length","toVideoElement","videoCandidate","HTMLVideoElement","video_1","document","createElement","setAttribute","v","appendSourceElement","sourceCount","querySelectorAll","readyState","load","video","videoUrl","videoSrc","videoType","type","sourceElement","appendChild","win","window","Math","self","Function","doc","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","IS_IOS","IS_SAFARI_ON_DESKTOP","Float32Array","getComputedStyle","userAgent","SUPPORT_TOUCH","SUPPORT_DEVICEMOTION","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","i","len","SUPPORT_WILLCHANGE","CSS","supports","WEBXR_SUPPORTED","checkXRSupport","xr","isSessionSupported","then","res","catch","supportsSession","quatToVec3","quaternion","baseV","vec3","toDegree","a","PI","util","isPowerOfTwo","n","extractPitchFromQuat","atan2","sqrt","pow","hypot","x","y","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","getRotationDelta","prevQ","curQ","rotateKind","prevQuaternion","quat","curQuaternion","prevPoint","curPoint","rotateDistance","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","distance","abs","projectedPrevPoint","trigonometricRatio","theta","acos","crossVec","thetaDirection","deltaRadian","angleBetweenVec2","v1","v2","det","vec2","yawOffsetBetween","viewDir","targetDir","viewDirXZ","targetDirXZ","sign","Number","toAxis","offset","reduce","acc","version","branch","build","match","exec","parseInt","CHROME_VERSION","IS_CHROME_WITHOUT_DEVICE_MOTION","IS_ANDROID","test","CONTROL_MODE_VR","CONTROL_MODE_YAWPITCH","TOUCH_DIRECTION_NONE","TOUCH_DIRECTION_YAW","TOUCH_DIRECTION_PITCH","TOUCH_DIRECTION_ALL","MC_DECELERATION","MC_MAXIMUM_DURATION","MC_BIND_SCALE","MAX_FIELD_OF_VIEW","PAN_SCALE","YAW_RANGE_HALF","PITCH_RANGE_HALF","CIRCULAR_PITCH_RANGE_HALF","GYRO_MODE","NONE","YAWPITCH","VR","MathUtil","degToRad","radToDeg","Vector2","prototype","constructor","set","copy","subVectors","b","Vector3","z","normalize","scalar","invScalar","multiplyScalar","applyQuaternion","q","qx","qy","qz","qw","w","ix","iy","iz","iw","dot","crossVectors","ax","ay","az","bx","by","bz","Quaternion","undefined","setFromEulerXYZ","c1","cos","c2","c3","s1","sin","s2","s3","setFromEulerYXZ","setFromAxisAngle","axis","angle","halfAngle","s","multiply","multiplyQuaternions","qax","qay","qaz","qaw","qbx","qby","qbz","qbw","inverse","l","slerp","qb","t","cosHalfTheta","halfTheta","sinHalfTheta","ratioA","ratioB","setFromUnitVectors","r","EPS","vFrom","vTo","Util","MIN_TIMESTEP","MAX_TIMESTEP","base64","mimeType","clamp","min","max","lerp","isIOS","platform","isWebViewAndroid","indexOf","isSafari","isFirefoxAndroid","isR7","isLandscapeMode","rtn","orientation","isTimestampDeltaValid","timestampDeltaS","isNaN","getScreenWidth","screen","width","height","getScreenHeight","requestFullscreen","element","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","exitFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","getFullscreenElement","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","linkProgram","gl","vertexSource","fragmentSource","attribLocationMap","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","program","createProgram","attachShader","attribName","bindAttribLocation","deleteShader","getProgramUniforms","uniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","uniformName","uniformInfo","getActiveUniform","replace","getUniformLocation","orthoMatrix","out","left","right","bottom","top","near","far","lr","bt","nf","copyArray","dest","isMobile","check","substr","vendor","opera","extend","hasOwnProperty","safariCssSizeWorkaround","canvas","width_1","height_1","setTimeout","isDebug","getQueryParameter","regex","RegExp","results","location","search","decodeURIComponent","frameDataFromPose","piOver180","rad45","mat4_perspectiveFromFieldOfView","fov","upTan","tan","upDegrees","downTan","downDegrees","leftTan","leftDegrees","rightTan","rightDegrees","xScale","yScale","mat4_fromRotationTranslation","x2","y2","z2","xx","xy","xz","yy","yz","zz","wx","wy","wz","mat4_translate","a00","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","mat4_invert","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b06","b07","b08","b09","b10","b11","defaultOrientation","defaultPosition","updateEyeMatrices","projection","view","pose","parameters","vrDisplay","fieldOfView","depthNear","depthFar","position","frameData","timestamp","leftProjectionMatrix","leftViewMatrix","getEyeParameters","rightProjectionMatrix","rightViewMatrix","isInsideCrossDomainIFrame","isFramed","refDomain","getDomainFromUrl","referrer","thisDomain","href","url","domain","split","predictionTimeS","previousQ","previousTimestampS","deltaQ","outQ","currentQ","gyro","timestampS","angularSpeed","console","log","toFixed","deltaT","predictAngle","STILLNESS_THRESHOLD","__extends","_super","_this","_onDeviceMotion","bind","_onDeviceOrientation","_onChromeWithoutDeviceMotion","isWithoutDeviceMotion","isAndroid","stillGyroVec","rawGyroVec","adjustedGyroVec","_timer","lastDevicemotionTimestamp","_isEnabled","enable","addEventListener","removeEventListener","e","alpha","beta","gamma","trigger","ComponentEvent","inputEvent","deviceorientation","clearTimeout","Date","getTime","isGyroSensorAvailable","rotationRate","isGravitySensorAvailable","accelerationIncludingGravity","interval","devicemotionEvent","__assign","timeStamp","acceleration","adjustedRotationRate","Component","sample","sensorSample","kFilter","vector","currentGyroMeasurement","previousGyroMeasurement","run_","currentAccelMeasurement","SensorSample","filterQ","previousFilterQ","accelQ","isOrientationInitialized","estimatedGravity","measuredGravity","gyroIntegralQ","accelToQuaternion_","gyroDeltaQ","gyroToQuaternionDelta_","invFilterQ","getQuaternionAngle","targetQ","accel","normAccel","dt","ComplementaryFilter","isFilterQuaternionInitialized","getOrientation","K_FILTER","PREDICTION_TIME_S","deviceMotion","DeviceMotion","accelerometer","gyroscope","_onDeviceMotionChange","_onScreenOrientationChange","filter","posePredictor","PosePredictor","filterToWorldQ","isChromeUsingDegrees","inverseWorldToScreenQ","worldToScreenQ","originalPoseAdjustQ","_setScreenTransform","resetQ","on","isEnabled","disable","_deviceOrientationQ","deviceOrientationFixQ","_alpha","outQuat","_convertFusionToPredicted","_prevOrientation","predictedQ","getPrediction","_a","accGravity","rotRate","_triggerChange","addAccelMeasurement","addGyroMeasurement","getDeltaYaw","prvQ","yawDeltaByYaw","yawDeltaByRoll","getDeltaPitch","pitchDelta","el","options","_prevQuaternion","_quaternion","fusionPoseSensor","scale","threshold","_onPoseChange","axes","observer","FusionPoseSensor","_attachEvent","_dettachEvent","destroy","disconnect","event","change","off","screenRotationAngleInst","refCount","_onOrientationChange","_spinR","_screenOrientationAngle","glMatrix","betaR","gammaR","_useRotation","_screenRotationAngle","setUseRotation","useRotation","_userDirection","Axes","DIRECTION_ALL","unref","ScreenRotationAngle","_direction","DIRECTION_HORIZONTAL","connect","properties","useDirection","_getOffset","newOffset","getRadian","cosTheta","sinTheta","DIRECTION_VERTICAL","PanInput","Y_AXIS_VECTOR","_fusionPoseSensor","isTrusted","yaw","yawQ","conj","DEFAULT_YAW_RANGE","DEFAULT_PITCH_RANGE","CIRCULAR_PITCH_RANGE","opt","pitch","showPolePoint","useZoom","useKeyboard","gyroMode","touchDirection","yawRange","pitchRange","fovRange","aspectRatio","_element","_initialFov","_enabled","_isAnimating","_deviceQuaternion","_initAxes","option","param","_axes","get","areaHeight","_axesPanInput","deceleration","newValue","_getOptions","newOptions","changedKeyList","push","_setOptions","_getValidatedOptions","_applyOptions","updatePanScale","persistOrientation","_resetOrientation","duration","pos","p","f","maximumDuration","Infinity","setBy","yawPitch","getCombinedQuaternion","_axesWheelInput","_axesTiltMotionInput","_axesPinchInput","_axesMoveKeyInput","yRange","_updateYawRange","pRange","_updatePitchRange","RotationPanInput","WheelInput","PinchInput","MoveKeyInput","range","circular","_isCircular","bounce","hold","evt","delta","_updateControlScale","release","animationEnd","_getValidYawRange","_getValidPitchRange","arguments","isVR","isYawPitch","some","setTo","prevFov","nextFov","_initDeviceQuaternion","TiltMotionInput","_togglePinchInputByOption","_enableTouch","_inputs","direction","yawEnabled","pitchEnabled","DeviceQuaternion","newYawRange","newFov","newAspectRatio","ratio","_adjustAspectRatio","horizontalFov","isValid","newPitchRange","changeEvt","verticalAngle","halfFov","isPanorama","concat","horizontalAngle","halfHorizontalFov","mathUtil","targetElement","input","inputRange","outputRange","rangeIdx","inputA","inputB","outputA","outputB","_lerp","fraction","YawPitchControl","ERROR_TYPE","INVALID_DEVICE","NO_WEBGL","FAIL_IMAGE_LOAD","FAIL_BIND_TEXTURE","INVALID_RESOURCE","RENDERING_CONTEXT_LOST","PANOVIEWER_EVENTS","READY","VIEW_CHANGE","ANIMATION_END","ERROR","PROJECTION_TYPE","EQUIRECTANGULAR","CUBEMAP","CUBESTRIP","PANORAMA","STEREOSCOPIC_EQUI","STEREO_FORMAT","TOP_BOTTOM","LEFT_RIGHT","PANOVIEWER_OPTIONS","projectionType","cubemapConfig","stereoFormat","canvasClass","DEFAULT_CANVAS_CLASS","WEBGL_ERROR_CODE","webglAvailability","WebGLUtils","shader","success","getShaderParameter","COMPILE_STATUS","error","getShaderInfoLog","LINK_STATUS","deleteProgram","data","itemSize","attr","buffer","createBuffer","bindBuffer","bufferData","STATIC_DRAW","numItems","enableVertexAttribArray","vertexAttribPointer","FLOAT","userContextAttributes","webglIdentifiers","context","contextAttributes","preserveDrawingBuffer","antialias","onWebglcontextcreationerror","statusMessage","webglIdentifiers_1","__values","identifier","getContext","textureTarget","texture","createTexture","bindTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","webglContext","getWebglContext","loseContextExtension","getExtension","loseContext","agentInfo","isStableWebgl","parseFloat","code","pixels","texImage2D","RGBA","UNSIGNED_BYTE","getParameter","MAX_TEXTURE_SIZE","isIE11","majorVersion","EVENTS","_forceDimension","_pixelCanvas","_pixelContext","shaderProgram","indexBuffer","mvMatrix","pMatrix","uniformMatrix4fv","pMatrixUniform","mvMatrixUniform","drawElements","TRIANGLES","UNSIGNED_SHORT","pixelSource","naturalWidth","videoWidth","naturalHeight","videoHeight","forceDimension","isIE11Video","getDimension","contentDimension","textureDimension","drawImage","imageConfig","tileConfig","config","flipHorizontal","rotation","message","Renderer","CubeRenderer","order","_VERTEX_POSITION_DATA","_INDEX_DATA","indexData","vertexPositionData","getVertexPositionData","vertexOrder","extractOrder","base","_extractTileConfig","elemSize","vertexPerTile","trim","texCoords","face","floor","ordermap","shift","unshift","pop","elemPerTile","tileVertex","slice","tileTemp","j","splice","coord","_shrinkCoord","faceCoords","val","coords","baseOrder","orderMap","surfaceIdx","tileIdx","TEXTURE_CUBE_MAP_POSITIVE_X","maxCubeMapTextureSize","getMaxCubeMapTextureSize","tile","extractTileFromImage","_triggerError","TEXTURE_CUBE_MAP","updateTexture","inputTextureSize","outputTextureSize","getSourceTileSize","tilePerRow","MAX_CUBE_MAP_TEXTURE_SIZE","imageWidth","coordData","SHRINK_MULTIPLIER","axisMultipliers","axisIndex","axisDir","notSameDir","_vertices","indices","cols","rows","textureSize","c","tileConfigs","_transformCoord","index","TEXTURE_2D","_getPixelSource","size","maxSize","getMaxTextureSize","_initPixelSource","activeTexture","TEXTURE0","pixelStorei","UNPACK_FLIP_Y_WEBGL","newCoord","_flipHorizontalCoord","_rotateCoord","SHRINK_Y","SHRINK_X","rotationAngle","SIZE","shiftCount","moved","rotatedCoord","latitudeBands","longitudeBands","radius","ANGLE_CORRECTION_FOR_CENTER_ALIGN","textureCoordData","latIdx","lngIdx","phi","sinPhi","cosPhi","u","format","_stereoFormat","ctx","leftEyeScaleOffset","rightEyeScaleOffset","uTexScaleOffset","uniform4fv","render","SphereRenderer","_TEXTURE_COORD_DATA","MIN_ASPECT_RATIO_FOR_FULL_PANORAMA","CylinderRenderer","resizeDimension","_b","imageAspectRatio","cylinderMaxRadian","halfCylinderY","rotated","CYLIDER_Y","startAngleForCenterAlign","yIdx","yLength","VR_DISPLAY_PRESENT_CHANGE","DEFAULT_LEFT_BOUNDS","DEFAULT_RIGHT_BOUNDS","EYES","LEFT","RIGHT","_vrDisplay","removeEndCallback","isPresenting","exitPresent","_clear","_frameData","VRFrameData","Boolean","bindFramebuffer","FRAMEBUFFER","submitFrame","display","halfWidth","drawingBufferWidth","drawingBufferHeight","getFrameData","leftMVMatrix","rightMVMatrix","mat4","_yawOffset","viewport","callback","getVRDisplays","displays","Promise","reject","Error","capabilities","canPresent","requestPresent","leftEye","rightEye","renderWidth","renderHeight","_setDisplay","layers","getLayers","layer","_leftBounds","leftBounds","_rightBounds","rightBounds","addEndCallback","XR_REFERENCE_SPACE","xrSession","_xrSession","end","_options","frame","getViewerPose","_xrRefSpace","session","baseLayer","renderState","framebuffer","glLayer","views","getViewport","transform","matrix","projectionMatrix","_presenting","requiredFeatures","attributes","getContextAttributes","xrCompatible","makeXRCompatible","requestSession","xrLayer","XRWebGLLayer","updateRenderState","requestReferenceSpace","refSpace","_setSession","_xrLayer","args","_callback","_rafId","_context","requestAnimationFrame","_onLoop","before","performance","now","diff","_rafTimer","_onLoopNextTick","cancelAnimationFrame","ImageType","DEVICE_PIXEL_RATIO","BIND_TEXTURE","IMAGE_LOADED","RENDERING_CONTEXT_RESTORE","RENDERER_ERROR","isVideo","container","sphericalConfig","renderingContextAttributes","vr","_vr","animator","_animator","exitVR","_restoreStyle","updateViewportDimensions","_updateViewport","_bindBuffers","_shouldForceDraw","stop","setContext","setCallback","_render","start","time","eyeParams","getEyeParams","beforeRender","eyeIndex","eyeParam","uniform1f","uEye","_draw","afterRender","canRender","minusZDir","mat3","mvInv","pInv","yawOffset","setYawOffset","_renderStereo","_lastQuaternion","_lastYaw","_lastPitch","_lastFieldOfView","textureCoordBuffer","vertexBuffer","_initCanvas","_setDefaultCanvasStyle","_wrapper","_wrapperOrigStyle","_renderingContextAttributes","_image","_imageConfig","_imageIsReady","_keepUpdate","_onContentLoad","_onContentError","WebGLAnimator","setImage","imageType","yawPitchControl","_yawPitchControl","_isVideo","_setImageType","_contentLoader","ImReady","rej","contentLoader","isReady","_bindTexture","once","errorCount","parentElement","_hasExternalCanvas","detach","hasRenderingContext","removeChild","forceContextLoss","_onWebglcontextlost","_onWebglcontextrestored","isContextLost","viewPortChanged","h","doUpdate","isImageLoaded","updateFieldOfView","_renderer","resolve","_requestPresent","_imageType","_isCubeMap","CubeStripRenderer","_initWebGL","canvasInContainer","querySelector","_createCanvas","className","margin","maxHeight","maxWidth","outline","content","_triggerContentLoad","renderer","vsSource","getVertexShaderSource","fsSource","getFragmentShaderSource","getErrorNameFromWebGLErrorCode","getError","useProgram","vertexPositionAttribute","getAttribLocation","samplerUniform","textureCoordAttribute","clear","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","STENCIL_BUFFER_BIT","uniform1i","preventDefault","_initRenderingContext","_initShaderProgram","clearColor","deleteTexture","CULL_FACE","WebGLRenderingContext","getIndexData","getTextureCoordData","initBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","Uint16Array","isEAC","updateShaderData","_initBuffers","getFov","shouldRenderWithQuaternion","getQuaternion","renderWithQuaternion","getYawPitch","renderWithYawPitch","_updateTexture","XRManager","VRManager","_onFirstVRFrame","_setWrapperFullscreen","wrapper","getAttribute","wrapperStyle","zIndex","removeAttribute","PanoImageRenderer","isWebGLAvailable","isStableWebGL","_container","_projectionType","_cubemapConfig","_width","_height","_yaw","_pitch","_fov","_gyroMode","_aspectRatio","_canvasClass","PanoViewer","_isValidTouchDirection","yawPitchConfig","_isReady","_initYawPitchControl","_initRenderer","onDeviceMotionChange","checkGyro","timeout","race","fb","TOUCH_DIRECTION","YAW","PITCH","ALL","_photoSphereRenderer","getContent","warn","_deactivate","keepUpdate","requestPermission","permissionState","enableSensor","enterVR","containerSize","lookAt","verticalAngleOfImage","initialYaw","initialPitch","setYawPitchControl","_bindRendererHandler","_activate","ProjectionType","yawSize","maxFov","atan","minFov","attachTo","_updateYawPitchIfNeeded","startRender","getVideo","pause","stopRender","PanoViewerModule","Constants"],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECnCA;;;;;;;EAqCA,IAAME,UAAU,GAAG,UAACC,UAAD;EACjB,MAAMC,KAAK,GAAGC,UAAA,CAAgB,CAAhB,EAAmB,CAAnB,EAAsB,CAAtB,CAAd;EAEAA,EAAAA,aAAA,CAAmBD,KAAnB,EAA0BA,KAA1B,EAAiCD,UAAjC;EACA,SAAOC,KAAP;EACD,CALD;;EAOA,IAAME,QAAQ,GAAG,UAACC,CAAD;EAAe,SAAAA,CAAC,GAAG,GAAJ,GAAU5C,IAAI,CAAC6C,EAAf;EAAiB,CAAjD;;EAEA,IAAMC,IAAI,GAAQ,EAAlB;;EAEAA,IAAI,CAACC,YAAL,GAAoB,UAACC,CAAD;EAAe,SAAAA,CAAC,IAAI,CAACA,CAAC,GAAIA,CAAC,GAAG,CAAV,MAAkB,CAAvB;EAAwB,CAA3D;;EAEAF,IAAI,CAACG,oBAAL,GAA4B,UAACT,UAAD;EAC1B,MAAMC,KAAK,GAAGF,UAAU,CAACC,UAAD,CAAxB;EAEA,SAAO,CAAC,CAAD,GAAKxC,IAAI,CAACkD,KAAL,CACVT,KAAK,CAAC,CAAD,CADK,EAEVzC,IAAI,CAACmD,IAAL,CAAUnD,IAAI,CAACoD,GAAL,CAASX,KAAK,CAAC,CAAD,CAAd,EAAmB,CAAnB,IAAwBzC,IAAI,CAACoD,GAAL,CAASX,KAAK,CAAC,CAAD,CAAd,EAAmB,CAAnB,CAAlC,CAFU,CAAZ;EAGD,CAND;;EAQAK,IAAI,CAACO,KAAL,GAAarD,IAAI,CAACqD,KAAL,IAAe,UAACC,CAAD,EAAYC,CAAZ;EAA0B,SAAAvD,IAAI,CAACmD,IAAL,CAAUG,CAAC,GAAGA,CAAJ,GAAQC,CAAC,GAAGA,CAAtB,CAAA;EAAwB,CAA9E;EAGA;EACA;;;EACA,IAAMC,eAAe,GAIjB;EACFC,EAAAA,WAAW,EAAE,CADX;EAEFC,EAAAA,iBAAiB,EAAE,CAFjB;EAGFC,EAAAA,gBAAgB,EAAE;EAHhB,CAJJ;EAUAH,eAAe,CAACA,eAAe,CAACC,WAAjB,CAAf,GAA+C;EAC7CG,EAAAA,UAAU,EAAE,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,CADiC;EAE7CC,EAAAA,SAAS,EAAE,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP;EAFkC,CAA/C;EAIAL,eAAe,CAACA,eAAe,CAACE,iBAAjB,CAAf,GAAqD;EACnDE,EAAAA,UAAU,EAAE,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,CADuC;EAEnDC,EAAAA,SAAS,EAAE,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP;EAFwC,CAArD;EAIAL,eAAe,CAACA,eAAe,CAACG,gBAAjB,CAAf,GAAoD;EAClDC,EAAAA,UAAU,EAAE,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,CADsC;EAElDC,EAAAA,SAAS,EAAE,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP;EAFuC,CAApD;;EAKA,IAAMC,gBAAgB,GAAG,UAACC,KAAD,EAAcC,IAAd,EAA0BC,UAA1B;EACvB,MAAML,UAAU,GAAGlB,UAAA,CACjBc,eAAe,CAACS,UAAD,CAAf,CAA4BL,UAA5B,CAAuC,CAAvC,CADiB,EAEjBJ,eAAe,CAACS,UAAD,CAAf,CAA4BL,UAA5B,CAAuC,CAAvC,CAFiB,EAGjBJ,eAAe,CAACS,UAAD,CAAf,CAA4BL,UAA5B,CAAuC,CAAvC,CAHiB,CAAnB;EAKA,MAAMC,SAAS,GAAGL,eAAe,CAACS,UAAD,CAAf,CAA4BJ,SAA9C;EAEA,MAAMK,cAAc,GAAGC,OAAA,CAAWJ,KAAX,CAAvB;EACA,MAAMK,aAAa,GAAGD,OAAA,CAAWH,IAAX,CAAtB;EAEAG,EAAAA,WAAA,CAAeD,cAAf,EAA+BA,cAA/B;EACAC,EAAAA,WAAA,CAAeC,aAAf,EAA8BA,aAA9B;EAEA,MAAIC,SAAS,GAAG3B,UAAA,CAAgB,CAAhB,EAAmB,CAAnB,EAAsB,CAAtB,CAAhB;EACA,MAAI4B,QAAQ,GAAG5B,UAAA,CAAgB,CAAhB,EAAmB,CAAnB,EAAsB,CAAtB,CAAf;EAEAA,EAAAA,aAAA,CAAmB2B,SAAnB,EAA8BA,SAA9B,EAAyCH,cAAzC;EACAxB,EAAAA,aAAA,CAAmB4B,QAAnB,EAA6BA,QAA7B,EAAuCF,aAAvC;EACA1B,EAAAA,aAAA,CAAmBkB,UAAnB,EAA+BA,UAA/B,EAA2CQ,aAA3C;EAEA,MAAMG,cAAc,GAAG7B,GAAA,CAASkB,UAAT,EAAqBlB,KAAA,CAAWA,QAAA,EAAX,EAA0B2B,SAA1B,EAAqCC,QAArC,CAArB,CAAvB;EACA,MAAME,eAAe,GAAGD,cAAc,GAAG,CAAjB,GAAqB,CAArB,GAAyB,CAAC,CAAlD;EAGA;EACA;;EACA,MAAME,UAAU,GAAG/B,UAAA,CAAgBmB,SAAS,CAAC,CAAD,CAAzB,EAA8BA,SAAS,CAAC,CAAD,CAAvC,EAA4CA,SAAS,CAAC,CAAD,CAArD,CAAnB;EAEA,MAAIa,UAAJ;;EAEA,MAAIT,UAAU,KAAKT,eAAe,CAACG,gBAAnC,EAAqD;EACnDe,IAAAA,UAAU,GAAGhC,UAAA,CAAgB,CAAhB,EAAmB8B,eAAnB,EAAoC,CAApC,CAAb;EACD,GAFD,MAEO;EACLE,IAAAA,UAAU,GAAGhC,UAAA,CAAgB8B,eAAhB,EAAiC,CAAjC,EAAoC,CAApC,CAAb;EACD;;EAED9B,EAAAA,aAAA,CAAmB+B,UAAnB,EAA+BA,UAA/B,EAA2CL,aAA3C;EACA1B,EAAAA,aAAA,CAAmBgC,UAAnB,EAA+BA,UAA/B,EAA2CN,aAA3C;EAEA,MAAMO,IAAI,GAAGF,UAAb;EACA,MAAMG,IAAI,GAAGF,UAAb;EACA,MAAMG,IAAI,GAAGnC,QAAA,EAAb;EAEAA,EAAAA,KAAA,CAAWmC,IAAX,EAAiBF,IAAjB,EAAuBC,IAAvB;EACAlC,EAAAA,SAAA,CAAemC,IAAf,EAAqBA,IAArB;EAEA,MAAMC,YAAY,GAAGD,IAAI,CAAC,CAAD,CAAzB;EACA,MAAME,YAAY,GAAGF,IAAI,CAAC,CAAD,CAAzB;EACA,MAAMG,YAAY,GAAGH,IAAI,CAAC,CAAD,CAAzB;EAGA;;EACAP,EAAAA,QAAQ,GAAG5B,UAAA,CAAgBmB,SAAS,CAAC,CAAD,CAAzB,EAA8BA,SAAS,CAAC,CAAD,CAAvC,EAA4CA,SAAS,CAAC,CAAD,CAArD,CAAX;EACAnB,EAAAA,aAAA,CAAmB4B,QAAnB,EAA6BA,QAA7B,EAAuCF,aAAvC;;EAGAC,EAAAA,SAAS,GAAG3B,UAAA,CAAgBmB,SAAS,CAAC,CAAD,CAAzB,EAA8BA,SAAS,CAAC,CAAD,CAAvC,EAA4CA,SAAS,CAAC,CAAD,CAArD,CAAZ;EACAnB,EAAAA,aAAA,CAAmB2B,SAAnB,EAA8BA,SAA9B,EAAyCH,cAAzC;;EAGA,MAAIe,QAAQ,GAAGjF,IAAI,CAACkF,GAAL,CACbb,SAAS,CAAC,CAAD,CAAT,GAAeS,YAAf,GACAT,SAAS,CAAC,CAAD,CAAT,GAAeU,YADf,GAEAV,SAAS,CAAC,CAAD,CAAT,GAAeW,YAHF,CAAf;EAMA,MAAMG,kBAAkB,GAAGzC,QAAA,EAA3B;EAEAA,EAAAA,QAAA,CAAcyC,kBAAd,EAAkCd,SAAlC,EAA6C3B,KAAA,CAAWA,QAAA,EAAX,EAA0BmC,IAA1B,EAAgCI,QAAhC,CAA7C;EAEA,MAAIG,kBAAkB,GACpB,CAACD,kBAAkB,CAAC,CAAD,CAAlB,GAAwBb,QAAQ,CAAC,CAAD,CAAhC,GACDa,kBAAkB,CAAC,CAAD,CAAlB,GAAwBb,QAAQ,CAAC,CAAD,CAD/B,GAEDa,kBAAkB,CAAC,CAAD,CAAlB,GAAwBb,QAAQ,CAAC,CAAD,CAFhC,KAGC5B,MAAA,CAAYyC,kBAAZ,IAAkCzC,MAAA,CAAY4B,QAAZ,CAHnC,CADF;;EAOA,MAAIc,kBAAkB,GAAG,CAAzB,EAA4B;EAC1BA,IAAAA,kBAAkB,GAAG,CAArB;EACD;;EAED,MAAMC,KAAK,GAAGrF,IAAI,CAACsF,IAAL,CAAUF,kBAAV,CAAd;EAEA,MAAMG,QAAQ,GAAG7C,KAAA,CAAWA,QAAA,EAAX,EAA0B4B,QAA1B,EAAoCa,kBAApC,CAAjB;EAEAF,EAAAA,QAAQ,GACNH,YAAY,GAAGS,QAAQ,CAAC,CAAD,CAAvB,GACAR,YAAY,GAAGQ,QAAQ,CAAC,CAAD,CADvB,GAEAP,YAAY,GAAGO,QAAQ,CAAC,CAAD,CAHzB;EAKA,MAAIC,cAAJ;;EAEA,MAAIvB,UAAU,KAAKT,eAAe,CAACG,gBAAnC,EAAqD;EACnD6B,IAAAA,cAAc,GAAGP,QAAQ,GAAG,CAAX,GAAe,CAAf,GAAmB,CAAC,CAArC;EACD,GAFD,MAEO;EACLO,IAAAA,cAAc,GAAGP,QAAQ,GAAG,CAAX,GAAe,CAAf,GAAmB,CAAC,CAArC;EACD;;EAED,MAAMQ,WAAW,GAAGJ,KAAK,GAAGG,cAAR,GAAyBhB,eAA7C;EAEA,SAAO7B,QAAQ,CAAC8C,WAAD,CAAf;EACD,CAtGD;;EAwGA,IAAMC,gBAAgB,GAAG,UAACC,EAAD,EAAWC,EAAX;EACvB,MAAMC,GAAG,GAAGF,EAAE,CAAC,CAAD,CAAF,GAAQC,EAAE,CAAC,CAAD,CAAV,GAAgBA,EAAE,CAAC,CAAD,CAAF,GAAQD,EAAE,CAAC,CAAD,CAAtC;EACA,MAAMN,KAAK,GAAG,CAACrF,IAAI,CAACkD,KAAL,CAAW2C,GAAX,EAAgBC,KAAA,CAASH,EAAT,EAAaC,EAAb,CAAhB,CAAf;EACA,SAAOP,KAAP;EACD,CAJD;;EAMAvC,IAAI,CAACiD,gBAAL,GAAwB,UAACC,OAAD,EAAkBC,SAAlB;EACtB,MAAMC,SAAS,GAAGJ,YAAA,CAAgBE,OAAO,CAAC,CAAD,CAAvB,EAA4BA,OAAO,CAAC,CAAD,CAAnC,CAAlB;EACA,MAAMG,WAAW,GAAGL,YAAA,CAAgBG,SAAS,CAAC,CAAD,CAAzB,EAA8BA,SAAS,CAAC,CAAD,CAAvC,CAApB;EAEAH,EAAAA,WAAA,CAAeI,SAAf,EAA0BA,SAA1B;EACAJ,EAAAA,WAAA,CAAeK,WAAf,EAA4BA,WAA5B;EAEA,MAAMd,KAAK,GAAG,CAACK,gBAAgB,CAACQ,SAAD,EAAYC,WAAZ,CAA/B;EAEA,SAAOd,KAAP;EACD,CAVD;;EAYAvC,IAAI,CAACsD,IAAL,GAAY,UAAC9C,CAAD;EAAe,SAAAtD,IAAI,CAACoG,IAAL,GACvBpG,IAAI,CAACoG,IAAL,CAAU9C,CAAV,CADuB,GAEtB+C,MAAM,CAAC/C,CAAC,GAAG,CAAL,CAAN,GAAgB+C,MAAM,CAAC/C,CAAC,GAAG,CAAL,CAAvB,IAAmC,CAACA,CAFb;EAEc,CAFzC;;EAIAR,IAAI,CAACH,QAAL,GAAgBA,QAAhB;EACAG,IAAI,CAACgB,gBAAL,GAAwBA,gBAAxB;EACAhB,IAAI,CAAC4C,gBAAL,GAAwBA,gBAAxB;;EC/MO,IAAMY,QAAM,GAAG,UAAC9I,MAAD,EAAS+I,MAAT;EAAoB,SAAAA,MAAM,CAACC,MAAP,CAAc,UAACC,GAAD,EAAMxH,CAAN,EAASyC,CAAT;EACtD,QAAIlE,MAAM,CAACkE,CAAD,CAAV,EAAe;EACb+E,MAAAA,GAAG,CAACjJ,MAAM,CAACkE,CAAD,CAAP,CAAH,GAAiBzC,CAAjB;EACD;;EACD,WAAOwH,GAAP;EACD,GALyC,EAKvC,EALuC,CAAA;EAKpC,CALC;;ECNP;;;;;;;EAMA;;;;;;;;EAOA,IAAIC,OAAO,GAAG,CAAC,CAAf;;EACA,IAAIC,MAAM,GAAkB,IAA5B;EACA,IAAIC,KAAK,GAAkB,IAA3B;EAEA,IAAMC,KAAK,GAAG,oDAAoDC,IAApD,CAAyD7F,SAAzD,CAAd;;EAEA,IAAI4F,KAAJ,EAAW;EACTH,EAAAA,OAAO,GAAGK,QAAQ,CAACF,KAAK,CAAC,CAAD,CAAN,EAAW,EAAX,CAAlB;EACAF,EAAAA,MAAM,GAAGE,KAAK,CAAC,CAAD,CAAd;EACAD,EAAAA,KAAK,GAAGC,KAAK,CAAC,CAAD,CAAb;EACD;;EAED,IAAMG,cAAc,GAAGN,OAAvB;EACA,IAAMO,+BAA+B,GAAGP,OAAO,KAAK,EAAZ,IAAkBC,MAAM,KAAK,MAA7B,IAAuCI,QAAQ,CAACH,KAAD,EAAS,EAAT,CAAR,GAAuB,GAAtG;EACA,IAAMM,UAAU,GAAG,WAAWC,IAAX,CAAgBlG,SAAhB,CAAnB;EAEA,IAAMmG,eAAe,GAAG,CAAxB;EACA,IAAMC,qBAAqB,GAAG,CAA9B;EAEA,IAAMC,oBAAoB,GAAG,CAA7B;EACA,IAAMC,mBAAmB,GAAG,CAA5B;EACA,IAAMC,qBAAqB,GAAG,CAA9B;EACA,IAAMC,mBAAmB,GAAGF,mBAAmB,GAAGC,qBAAlD;EAEA;;EACA,IAAME,eAAe,GAAG,MAAxB;EACA,IAAMC,mBAAmB,GAAG,IAA5B;EACA,IAAMC,aAAa,GAAG,CAAC,IAAD,EAAO,IAAP,CAAtB;EAGA,IAAMC,iBAAiB,GAAG,GAA1B;EACA,IAAMC,SAAS,GAAG,GAAlB;;EAUA,IAAMC,cAAc,GAAG,GAAvB;EACA,IAAMC,gBAAgB,GAAG,EAAzB;EACA,IAAMC,yBAAyB,GAAG,GAAlC;EAcA,IAAMC,SAAS,GAIX;EACFC,EAAAA,IAAI,EAAE,MADJ;EAEFC,EAAAA,QAAQ,EAAE,UAFR;EAGFC,EAAAA,EAAE,EAAE;EAHF,CAJJ;;ECvEA;EAkBA,IAAMC,QAAQ,GAAGxI,GAAG,CAACwI,QAAJ,IAAgB,EAAjC;EAEAA,QAAQ,CAACC,QAAT,GAAoBvI,IAAI,CAAC6C,EAAL,GAAU,GAA9B;EACAyF,QAAQ,CAACE,QAAT,GAAoB,MAAMxI,IAAI,CAAC6C,EAA/B;EAGA;;EAGAyF,QAAQ,CAACG,OAAT,GAAmB,UAAUnF,CAAV,EAAaC,CAAb;EACjB,OAAKD,CAAL,GAASA,CAAC,IAAI,CAAd;EACA,OAAKC,CAAL,GAASA,CAAC,IAAI,CAAd;EACD,CAHD;;EAKA+E,QAAQ,CAACG,OAAT,CAAiBC,SAAjB,GAA6B;EAC3BC,EAAAA,WAAW,EAAEL,QAAQ,CAACG,OADK;EAG3BG,EAAAA,GAAG,EAAE,UAAUtF,CAAV,EAAaC,CAAb;EACH,SAAKD,CAAL,GAASA,CAAT;EACA,SAAKC,CAAL,GAASA,CAAT;EAEA,WAAO,IAAP;EACD,GAR0B;EAU3BsF,EAAAA,IAAI,EAAE,UAAU5J,CAAV;EACJ,SAAKqE,CAAL,GAASrE,CAAC,CAACqE,CAAX;EACA,SAAKC,CAAL,GAAStE,CAAC,CAACsE,CAAX;EAEA,WAAO,IAAP;EACD,GAf0B;EAiB3BuF,EAAAA,UAAU,EAAE,UAAUlG,CAAV,EAAamG,CAAb;EACV,SAAKzF,CAAL,GAASV,CAAC,CAACU,CAAF,GAAMyF,CAAC,CAACzF,CAAjB;EACA,SAAKC,CAAL,GAASX,CAAC,CAACW,CAAF,GAAMwF,CAAC,CAACxF,CAAjB;EAEA,WAAO,IAAP;EACD;EAtB0B,CAA7B;;EAyBA+E,QAAQ,CAACU,OAAT,GAAmB,UAAU1F,CAAV,EAAaC,CAAb,EAAgB0F,CAAhB;EACjB,OAAK3F,CAAL,GAASA,CAAC,IAAI,CAAd;EACA,OAAKC,CAAL,GAASA,CAAC,IAAI,CAAd;EACA,OAAK0F,CAAL,GAASA,CAAC,IAAI,CAAd;EACD,CAJD;;EAMAX,QAAQ,CAACU,OAAT,CAAiBN,SAAjB,GAA6B;EAC3BC,EAAAA,WAAW,EAAEL,QAAQ,CAACU,OADK;EAG3BJ,EAAAA,GAAG,EAAE,UAAUtF,CAAV,EAAaC,CAAb,EAAgB0F,CAAhB;EACH,SAAK3F,CAAL,GAASA,CAAT;EACA,SAAKC,CAAL,GAASA,CAAT;EACA,SAAK0F,CAAL,GAASA,CAAT;EAEA,WAAO,IAAP;EACD,GAT0B;EAW3BJ,EAAAA,IAAI,EAAE,UAAU5J,CAAV;EACJ,SAAKqE,CAAL,GAASrE,CAAC,CAACqE,CAAX;EACA,SAAKC,CAAL,GAAStE,CAAC,CAACsE,CAAX;EACA,SAAK0F,CAAL,GAAShK,CAAC,CAACgK,CAAX;EAEA,WAAO,IAAP;EACD,GAjB0B;EAmB3BxK,EAAAA,MAAM,EAAE;EACN,WAAOuB,IAAI,CAACmD,IAAL,CAAW,KAAKG,CAAL,GAAS,KAAKA,CAAd,GAAkB,KAAKC,CAAL,GAAS,KAAKA,CAAhC,GAAoC,KAAK0F,CAAL,GAAS,KAAKA,CAA7D,CAAP;EACD,GArB0B;EAuB3BC,EAAAA,SAAS,EAAE;EACT,QAAMC,MAAM,GAAG,KAAK1K,MAAL,EAAf;;EAEA,QAAK0K,MAAM,KAAK,CAAhB,EAAoB;EAClB,UAAMC,SAAS,GAAG,IAAID,MAAtB;EAEA,WAAKE,cAAL,CAAoBD,SAApB;EACD,KAJD,MAIO;EACL,WAAK9F,CAAL,GAAS,CAAT;EACA,WAAKC,CAAL,GAAS,CAAT;EACA,WAAK0F,CAAL,GAAS,CAAT;EACD;;EAED,WAAO,IAAP;EACD,GArC0B;EAuC3BI,EAAAA,cAAc,EAAE,UAAUF,MAAV;EACd,SAAK7F,CAAL,IAAU6F,MAAV;EACA,SAAK5F,CAAL,IAAU4F,MAAV;EACA,SAAKF,CAAL,IAAUE,MAAV;EACD,GA3C0B;EA6C3BG,EAAAA,eAAe,EAAE,UAAUC,CAAV;EACf,QAAMjG,CAAC,GAAG,KAAKA,CAAf;EACA,QAAMC,CAAC,GAAG,KAAKA,CAAf;EACA,QAAM0F,CAAC,GAAG,KAAKA,CAAf;EAEA,QAAMO,EAAE,GAAGD,CAAC,CAACjG,CAAb;EACA,QAAMmG,EAAE,GAAGF,CAAC,CAAChG,CAAb;EACA,QAAMmG,EAAE,GAAGH,CAAC,CAACN,CAAb;EACA,QAAMU,EAAE,GAAGJ,CAAC,CAACK,CAAb;;EAGA,QAAMC,EAAE,GAAIF,EAAE,GAAGrG,CAAL,GAASmG,EAAE,GAAGR,CAAd,GAAkBS,EAAE,GAAGnG,CAAnC;EACA,QAAMuG,EAAE,GAAIH,EAAE,GAAGpG,CAAL,GAASmG,EAAE,GAAGpG,CAAd,GAAkBkG,EAAE,GAAGP,CAAnC;EACA,QAAMc,EAAE,GAAIJ,EAAE,GAAGV,CAAL,GAASO,EAAE,GAAGjG,CAAd,GAAkBkG,EAAE,GAAGnG,CAAnC;EACA,QAAM0G,EAAE,GAAG,CAAER,EAAF,GAAOlG,CAAP,GAAWmG,EAAE,GAAGlG,CAAhB,GAAoBmG,EAAE,GAAGT,CAApC;;EAGA,SAAK3F,CAAL,GAASuG,EAAE,GAAGF,EAAL,GAAUK,EAAE,GAAG,CAAER,EAAjB,GAAsBM,EAAE,GAAG,CAAEJ,EAA7B,GAAkCK,EAAE,GAAG,CAAEN,EAAlD;EACA,SAAKlG,CAAL,GAASuG,EAAE,GAAGH,EAAL,GAAUK,EAAE,GAAG,CAAEP,EAAjB,GAAsBM,EAAE,GAAG,CAAEP,EAA7B,GAAkCK,EAAE,GAAG,CAAEH,EAAlD;EACA,SAAKT,CAAL,GAASc,EAAE,GAAGJ,EAAL,GAAUK,EAAE,GAAG,CAAEN,EAAjB,GAAsBG,EAAE,GAAG,CAAEJ,EAA7B,GAAkCK,EAAE,GAAG,CAAEN,EAAlD;EAEA,WAAO,IAAP;EACD,GAnE0B;EAqE3BS,EAAAA,GAAG,EAAE,UAAUhL,CAAV;EACH,WAAO,KAAKqE,CAAL,GAASrE,CAAC,CAACqE,CAAX,GAAe,KAAKC,CAAL,GAAStE,CAAC,CAACsE,CAA1B,GAA8B,KAAK0F,CAAL,GAAShK,CAAC,CAACgK,CAAhD;EACD,GAvE0B;EAyE3BiB,EAAAA,YAAY,EAAE,UAAUtH,CAAV,EAAamG,CAAb;EACZ,QAAMoB,EAAE,GAAGvH,CAAC,CAACU,CAAb;EACA,QAAM8G,EAAE,GAAGxH,CAAC,CAACW,CAAb;EACA,QAAM8G,EAAE,GAAGzH,CAAC,CAACqG,CAAb;EACA,QAAMqB,EAAE,GAAGvB,CAAC,CAACzF,CAAb;EACA,QAAMiH,EAAE,GAAGxB,CAAC,CAACxF,CAAb;EACA,QAAMiH,EAAE,GAAGzB,CAAC,CAACE,CAAb;EAEA,SAAK3F,CAAL,GAAS8G,EAAE,GAAGI,EAAL,GAAUH,EAAE,GAAGE,EAAxB;EACA,SAAKhH,CAAL,GAAS8G,EAAE,GAAGC,EAAL,GAAUH,EAAE,GAAGK,EAAxB;EACA,SAAKvB,CAAL,GAASkB,EAAE,GAAGI,EAAL,GAAUH,EAAE,GAAGE,EAAxB;EAEA,WAAO,IAAP;EACD;EAtF0B,CAA7B;;EAyFAhC,QAAQ,CAACmC,UAAT,GAAsB,UAAUnH,CAAV,EAAaC,CAAb,EAAgB0F,CAAhB,EAAmBW,CAAnB;EACpB,OAAKtG,CAAL,GAASA,CAAC,IAAI,CAAd;EACA,OAAKC,CAAL,GAASA,CAAC,IAAI,CAAd;EACA,OAAK0F,CAAL,GAASA,CAAC,IAAI,CAAd;EACA,OAAKW,CAAL,GAAWA,CAAC,KAAKc,SAAR,GAAsBd,CAAtB,GAA0B,CAAnC;EACD,CALD;;EAOAtB,QAAQ,CAACmC,UAAT,CAAoB/B,SAApB,GAAgC;EAC9BC,EAAAA,WAAW,EAAEL,QAAQ,CAACmC,UADQ;EAG9B7B,EAAAA,GAAG,EAAE,UAAUtF,CAAV,EAAaC,CAAb,EAAgB0F,CAAhB,EAAmBW,CAAnB;EACH,SAAKtG,CAAL,GAASA,CAAT;EACA,SAAKC,CAAL,GAASA,CAAT;EACA,SAAK0F,CAAL,GAASA,CAAT;EACA,SAAKW,CAAL,GAASA,CAAT;EAEA,WAAO,IAAP;EACD,GAV6B;EAY9Bf,EAAAA,IAAI,EAAE,UAAUrG,UAAV;EACJ,SAAKc,CAAL,GAASd,UAAU,CAACc,CAApB;EACA,SAAKC,CAAL,GAASf,UAAU,CAACe,CAApB;EACA,SAAK0F,CAAL,GAASzG,UAAU,CAACyG,CAApB;EACA,SAAKW,CAAL,GAASpH,UAAU,CAACoH,CAApB;EAEA,WAAO,IAAP;EACD,GAnB6B;EAqB9Be,EAAAA,eAAe,EAAE,UAAUrH,CAAV,EAAaC,CAAb,EAAgB0F,CAAhB;EACf,QAAM2B,EAAE,GAAG5K,IAAI,CAAC6K,GAAL,CAAUvH,CAAC,GAAG,CAAd,CAAX;EACA,QAAMwH,EAAE,GAAG9K,IAAI,CAAC6K,GAAL,CAAUtH,CAAC,GAAG,CAAd,CAAX;EACA,QAAMwH,EAAE,GAAG/K,IAAI,CAAC6K,GAAL,CAAU5B,CAAC,GAAG,CAAd,CAAX;EACA,QAAM+B,EAAE,GAAGhL,IAAI,CAACiL,GAAL,CAAU3H,CAAC,GAAG,CAAd,CAAX;EACA,QAAM4H,EAAE,GAAGlL,IAAI,CAACiL,GAAL,CAAU1H,CAAC,GAAG,CAAd,CAAX;EACA,QAAM4H,EAAE,GAAGnL,IAAI,CAACiL,GAAL,CAAUhC,CAAC,GAAG,CAAd,CAAX;EAEA,SAAK3F,CAAL,GAAS0H,EAAE,GAAGF,EAAL,GAAUC,EAAV,GAAeH,EAAE,GAAGM,EAAL,GAAUC,EAAlC;EACA,SAAK5H,CAAL,GAASqH,EAAE,GAAGM,EAAL,GAAUH,EAAV,GAAeC,EAAE,GAAGF,EAAL,GAAUK,EAAlC;EACA,SAAKlC,CAAL,GAAS2B,EAAE,GAAGE,EAAL,GAAUK,EAAV,GAAeH,EAAE,GAAGE,EAAL,GAAUH,EAAlC;EACA,SAAKnB,CAAL,GAASgB,EAAE,GAAGE,EAAL,GAAUC,EAAV,GAAeC,EAAE,GAAGE,EAAL,GAAUC,EAAlC;EAEA,WAAO,IAAP;EACD,GAnC6B;EAqC9BC,EAAAA,eAAe,EAAE,UAAU9H,CAAV,EAAaC,CAAb,EAAgB0F,CAAhB;EACf,QAAM2B,EAAE,GAAG5K,IAAI,CAAC6K,GAAL,CAAUvH,CAAC,GAAG,CAAd,CAAX;EACA,QAAMwH,EAAE,GAAG9K,IAAI,CAAC6K,GAAL,CAAUtH,CAAC,GAAG,CAAd,CAAX;EACA,QAAMwH,EAAE,GAAG/K,IAAI,CAAC6K,GAAL,CAAU5B,CAAC,GAAG,CAAd,CAAX;EACA,QAAM+B,EAAE,GAAGhL,IAAI,CAACiL,GAAL,CAAU3H,CAAC,GAAG,CAAd,CAAX;EACA,QAAM4H,EAAE,GAAGlL,IAAI,CAACiL,GAAL,CAAU1H,CAAC,GAAG,CAAd,CAAX;EACA,QAAM4H,EAAE,GAAGnL,IAAI,CAACiL,GAAL,CAAUhC,CAAC,GAAG,CAAd,CAAX;EAEA,SAAK3F,CAAL,GAAS0H,EAAE,GAAGF,EAAL,GAAUC,EAAV,GAAeH,EAAE,GAAGM,EAAL,GAAUC,EAAlC;EACA,SAAK5H,CAAL,GAASqH,EAAE,GAAGM,EAAL,GAAUH,EAAV,GAAeC,EAAE,GAAGF,EAAL,GAAUK,EAAlC;EACA,SAAKlC,CAAL,GAAS2B,EAAE,GAAGE,EAAL,GAAUK,EAAV,GAAeH,EAAE,GAAGE,EAAL,GAAUH,EAAlC;EACA,SAAKnB,CAAL,GAASgB,EAAE,GAAGE,EAAL,GAAUC,EAAV,GAAeC,EAAE,GAAGE,EAAL,GAAUC,EAAlC;EAEA,WAAO,IAAP;EACD,GAnD6B;EAqD9BE,EAAAA,gBAAgB,EAAE,UAAUC,IAAV,EAAgBC,KAAhB;EAChB;EACA;EAEA,QAAMC,SAAS,GAAGD,KAAK,GAAG,CAA1B;EACA,QAAME,CAAC,GAAGzL,IAAI,CAACiL,GAAL,CAAUO,SAAV,CAAV;EAEA,SAAKlI,CAAL,GAASgI,IAAI,CAAChI,CAAL,GAASmI,CAAlB;EACA,SAAKlI,CAAL,GAAS+H,IAAI,CAAC/H,CAAL,GAASkI,CAAlB;EACA,SAAKxC,CAAL,GAASqC,IAAI,CAACrC,CAAL,GAASwC,CAAlB;EACA,SAAK7B,CAAL,GAAS5J,IAAI,CAAC6K,GAAL,CAAUW,SAAV,CAAT;EAEA,WAAO,IAAP;EACD,GAlE6B;EAoE9BE,EAAAA,QAAQ,EAAE,UAAUnC,CAAV;EACR,WAAO,KAAKoC,mBAAL,CAA0B,IAA1B,EAAgCpC,CAAhC,CAAP;EACD,GAtE6B;EAwE9BoC,EAAAA,mBAAmB,EAAE,UAAU/I,CAAV,EAAamG,CAAb;EACnB;EAEA,QAAM6C,GAAG,GAAGhJ,CAAC,CAACU,CAAd;EACA,QAAMuI,GAAG,GAAGjJ,CAAC,CAACW,CAAd;EACA,QAAMuI,GAAG,GAAGlJ,CAAC,CAACqG,CAAd;EACA,QAAM8C,GAAG,GAAGnJ,CAAC,CAACgH,CAAd;EACA,QAAMoC,GAAG,GAAGjD,CAAC,CAACzF,CAAd;EACA,QAAM2I,GAAG,GAAGlD,CAAC,CAACxF,CAAd;EACA,QAAM2I,GAAG,GAAGnD,CAAC,CAACE,CAAd;EACA,QAAMkD,GAAG,GAAGpD,CAAC,CAACa,CAAd;EAEA,SAAKtG,CAAL,GAASsI,GAAG,GAAGO,GAAN,GAAYJ,GAAG,GAAGC,GAAlB,GAAwBH,GAAG,GAAGK,GAA9B,GAAoCJ,GAAG,GAAGG,GAAnD;EACA,SAAK1I,CAAL,GAASsI,GAAG,GAAGM,GAAN,GAAYJ,GAAG,GAAGE,GAAlB,GAAwBH,GAAG,GAAGE,GAA9B,GAAoCJ,GAAG,GAAGM,GAAnD;EACA,SAAKjD,CAAL,GAAS6C,GAAG,GAAGK,GAAN,GAAYJ,GAAG,GAAGG,GAAlB,GAAwBN,GAAG,GAAGK,GAA9B,GAAoCJ,GAAG,GAAGG,GAAnD;EACA,SAAKpC,CAAL,GAASmC,GAAG,GAAGI,GAAN,GAAYP,GAAG,GAAGI,GAAlB,GAAwBH,GAAG,GAAGI,GAA9B,GAAoCH,GAAG,GAAGI,GAAnD;EAEA,WAAO,IAAP;EACD,GA1F6B;EA4F9BE,EAAAA,OAAO,EAAE;EACP,SAAK9I,CAAL,IAAU,CAAC,CAAX;EACA,SAAKC,CAAL,IAAU,CAAC,CAAX;EACA,SAAK0F,CAAL,IAAU,CAAC,CAAX;EAEA,SAAKC,SAAL;EAEA,WAAO,IAAP;EACD,GApG6B;EAsG9BA,EAAAA,SAAS,EAAE;EACT,QAAImD,CAAC,GAAGrM,IAAI,CAACmD,IAAL,CAAW,KAAKG,CAAL,GAAS,KAAKA,CAAd,GAAkB,KAAKC,CAAL,GAAS,KAAKA,CAAhC,GAAoC,KAAK0F,CAAL,GAAS,KAAKA,CAAlD,GAAsD,KAAKW,CAAL,GAAS,KAAKA,CAA/E,CAAR;;EAEA,QAAKyC,CAAC,KAAK,CAAX,EAAe;EACb,WAAK/I,CAAL,GAAS,CAAT;EACA,WAAKC,CAAL,GAAS,CAAT;EACA,WAAK0F,CAAL,GAAS,CAAT;EACA,WAAKW,CAAL,GAAS,CAAT;EACD,KALD,MAKO;EACLyC,MAAAA,CAAC,GAAG,IAAIA,CAAR;EAEA,WAAK/I,CAAL,GAAS,KAAKA,CAAL,GAAS+I,CAAlB;EACA,WAAK9I,CAAL,GAAS,KAAKA,CAAL,GAAS8I,CAAlB;EACA,WAAKpD,CAAL,GAAS,KAAKA,CAAL,GAASoD,CAAlB;EACA,WAAKzC,CAAL,GAAS,KAAKA,CAAL,GAASyC,CAAlB;EACD;;EAED,WAAO,IAAP;EACD,GAxH6B;EA0H9BC,EAAAA,KAAK,EAAE,UAAUC,EAAV,EAAcC,CAAd;EACL,QAAKA,CAAC,KAAK,CAAX,EAAe,OAAO,IAAP;EACf,QAAKA,CAAC,KAAK,CAAX,EAAe,OAAO,KAAK3D,IAAL,CAAW0D,EAAX,CAAP;EAEf,QAAMjJ,CAAC,GAAG,KAAKA,CAAf;EACA,QAAMC,CAAC,GAAG,KAAKA,CAAf;EACA,QAAM0F,CAAC,GAAG,KAAKA,CAAf;EACA,QAAMW,CAAC,GAAG,KAAKA,CAAf;;EAIA,QAAI6C,YAAY,GAAG7C,CAAC,GAAG2C,EAAE,CAAC3C,CAAP,GAAWtG,CAAC,GAAGiJ,EAAE,CAACjJ,CAAlB,GAAsBC,CAAC,GAAGgJ,EAAE,CAAChJ,CAA7B,GAAiC0F,CAAC,GAAGsD,EAAE,CAACtD,CAA3D;;EAEA,QAAKwD,YAAY,GAAG,CAApB,EAAwB;EACtB,WAAK7C,CAAL,GAAS,CAAE2C,EAAE,CAAC3C,CAAd;EACA,WAAKtG,CAAL,GAAS,CAAEiJ,EAAE,CAACjJ,CAAd;EACA,WAAKC,CAAL,GAAS,CAAEgJ,EAAE,CAAChJ,CAAd;EACA,WAAK0F,CAAL,GAAS,CAAEsD,EAAE,CAACtD,CAAd;EAEAwD,MAAAA,YAAY,GAAG,CAAEA,YAAjB;EACD,KAPD,MAOO;EACL,WAAK5D,IAAL,CAAW0D,EAAX;EACD;;EAED,QAAKE,YAAY,IAAI,GAArB,EAA2B;EACzB,WAAK7C,CAAL,GAASA,CAAT;EACA,WAAKtG,CAAL,GAASA,CAAT;EACA,WAAKC,CAAL,GAASA,CAAT;EACA,WAAK0F,CAAL,GAASA,CAAT;EAEA,aAAO,IAAP;EACD;;EAED,QAAMyD,SAAS,GAAG1M,IAAI,CAACsF,IAAL,CAAWmH,YAAX,CAAlB;EACA,QAAME,YAAY,GAAG3M,IAAI,CAACmD,IAAL,CAAW,MAAMsJ,YAAY,GAAGA,YAAhC,CAArB;;EAEA,QAAKzM,IAAI,CAACkF,GAAL,CAAUyH,YAAV,IAA2B,KAAhC,EAAwC;EACtC,WAAK/C,CAAL,GAAS,OAAQA,CAAC,GAAG,KAAKA,CAAjB,CAAT;EACA,WAAKtG,CAAL,GAAS,OAAQA,CAAC,GAAG,KAAKA,CAAjB,CAAT;EACA,WAAKC,CAAL,GAAS,OAAQA,CAAC,GAAG,KAAKA,CAAjB,CAAT;EACA,WAAK0F,CAAL,GAAS,OAAQA,CAAC,GAAG,KAAKA,CAAjB,CAAT;EAEA,aAAO,IAAP;EACD;;EAED,QAAM2D,MAAM,GAAG5M,IAAI,CAACiL,GAAL,CAAU,CAAE,IAAIuB,CAAN,IAAYE,SAAtB,IAAoCC,YAAnD;EACA,QAAME,MAAM,GAAG7M,IAAI,CAACiL,GAAL,CAAUuB,CAAC,GAAGE,SAAd,IAA4BC,YAA3C;EAEA,SAAK/C,CAAL,GAAWA,CAAC,GAAGgD,MAAJ,GAAa,KAAKhD,CAAL,GAASiD,MAAjC;EACA,SAAKvJ,CAAL,GAAWA,CAAC,GAAGsJ,MAAJ,GAAa,KAAKtJ,CAAL,GAASuJ,MAAjC;EACA,SAAKtJ,CAAL,GAAWA,CAAC,GAAGqJ,MAAJ,GAAa,KAAKrJ,CAAL,GAASsJ,MAAjC;EACA,SAAK5D,CAAL,GAAWA,CAAC,GAAG2D,MAAJ,GAAa,KAAK3D,CAAL,GAAS4D,MAAjC;EAEA,WAAO,IAAP;EACD,GAhL6B;EAkL9BC,EAAAA,kBAAkB,EAAE;EAClB;EACA;EAEA,QAAInH,EAAJ;EACA,QAAIoH,CAAJ;EACA,QAAMC,GAAG,GAAG,QAAZ;EAEA,WAAO,UAAUC,KAAV,EAAiBC,GAAjB;EACL,UAAKvH,EAAE,KAAK+E,SAAZ,EAAwB/E,EAAE,GAAG,IAAI2C,QAAQ,CAACU,OAAb,EAAL;EAExB+D,MAAAA,CAAC,GAAGE,KAAK,CAAChD,GAAN,CAAWiD,GAAX,IAAmB,CAAvB;;EAEA,UAAKH,CAAC,GAAGC,GAAT,EAAe;EACbD,QAAAA,CAAC,GAAG,CAAJ;;EAEA,YAAK/M,IAAI,CAACkF,GAAL,CAAU+H,KAAK,CAAC3J,CAAhB,IAAsBtD,IAAI,CAACkF,GAAL,CAAU+H,KAAK,CAAChE,CAAhB,CAA3B,EAAiD;EAC/CtD,UAAAA,EAAE,CAACiD,GAAH,CAAQ,CAAEqE,KAAK,CAAC1J,CAAhB,EAAmB0J,KAAK,CAAC3J,CAAzB,EAA4B,CAA5B;EACD,SAFD,MAEO;EACLqC,UAAAA,EAAE,CAACiD,GAAH,CAAQ,CAAR,EAAW,CAAEqE,KAAK,CAAChE,CAAnB,EAAsBgE,KAAK,CAAC1J,CAA5B;EACD;EACF,OARD,MAQO;EACLoC,QAAAA,EAAE,CAACuE,YAAH,CAAiB+C,KAAjB,EAAwBC,GAAxB;EACD;;EAED,WAAK5J,CAAL,GAASqC,EAAE,CAACrC,CAAZ;EACA,WAAKC,CAAL,GAASoC,EAAE,CAACpC,CAAZ;EACA,WAAK0F,CAAL,GAAStD,EAAE,CAACsD,CAAZ;EACA,WAAKW,CAAL,GAASmD,CAAT;EAEA,WAAK7D,SAAL;EAEA,aAAO,IAAP;EACD,KAzBD;EA0BD,GAlCmB;EAlLU,CAAhC;;EC/JA;;EACA;;;;;;;;;;;;;;;EAmBA,IAAMjI,WAAS,SAAGb,GAAG,SAAH,IAAAA,GAAG,WAAH,SAAA,GAAAA,GAAG,CAAEa,4CAAa,EAApC;EACA,IAAMkM,IAAI,GAAIrN,GAAD,CAAOqN,IAAP,IAAe,EAA5B;EAEAA,IAAI,CAACC,YAAL,GAAoB,KAApB;EACAD,IAAI,CAACE,YAAL,GAAoB,CAApB;;EAEAF,IAAI,CAACG,MAAL,GAAc,UAASC,QAAT,EAAmBD,MAAnB;EACZ,SAAO,UAAUC,QAAV,GAAqB,UAArB,GAAkCD,MAAzC;EACD,CAFD;;EAIAH,IAAI,CAACK,KAAL,GAAa,UAAS5P,KAAT,EAAgB6P,GAAhB,EAAqBC,GAArB;EACX,SAAO1N,IAAI,CAACyN,GAAL,CAASzN,IAAI,CAAC0N,GAAL,CAASD,GAAT,EAAc7P,KAAd,CAAT,EAA+B8P,GAA/B,CAAP;EACD,CAFD;;EAIAP,IAAI,CAACQ,IAAL,GAAY,UAAS/K,CAAT,EAAYmG,CAAZ,EAAeyD,CAAf;EACV,SAAO5J,CAAC,GAAI,CAACmG,CAAC,GAAGnG,CAAL,IAAU4J,CAAtB;EACD,CAFD;;EAIAW,IAAI,CAACS,KAAL,GAAc;EACZ,MAAMA,KAAK,GAAG,mBAAmBzG,IAAnB,CAAwB/G,GAAG,SAAH,IAAAA,GAAG,WAAH,SAAA,GAAAA,GAAG,CAAEyN,QAA7B,CAAd;EACA,SAAO;EACL,WAAOD,KAAP;EACD,GAFD;EAGD,CALY,EAAb;;EAOAT,IAAI,CAACW,gBAAL,GAAyB;EACvB,MAAMA,gBAAgB,GAAG7M,WAAS,CAAC8M,OAAV,CAAkB,SAAlB,MAAiC,CAAC,CAAlC,IACvB9M,WAAS,CAAC8M,OAAV,CAAkB,SAAlB,MAAiC,CAAC,CADX,IAEvB9M,WAAS,CAAC8M,OAAV,CAAkB,QAAlB,MAAgC,CAAC,CAFnC;EAGA,SAAO;EACL,WAAOD,gBAAP;EACD,GAFD;EAGD,CAPuB,EAAxB;;EASAX,IAAI,CAACa,QAAL,GAAiB;EACf,MAAMA,QAAQ,GAAG,iCAAiC7G,IAAjC,CAAsClG,WAAtC,CAAjB;EACA,SAAO;EACL,WAAO+M,QAAP;EACD,GAFD;EAGD,CALe,EAAhB;;EAOAb,IAAI,CAACc,gBAAL,GAAyB;EACvB,MAAMA,gBAAgB,GAAGhN,WAAS,CAAC8M,OAAV,CAAkB,SAAlB,MAAiC,CAAC,CAAlC,IACvB9M,WAAS,CAAC8M,OAAV,CAAkB,SAAlB,MAAiC,CAAC,CADpC;EAEA,SAAO;EACL,WAAOE,gBAAP;EACD,GAFD;EAGD,CANuB,EAAxB;;EAQAd,IAAI,CAACe,IAAL,GAAa;EACX,MAAMA,IAAI,GAAGjN,WAAS,CAAC8M,OAAV,CAAkB,UAAlB,MAAkC,CAAC,CAAhD;EACA,SAAO;EACL,WAAOG,IAAP;EACD,GAFD;EAGD,CALW,EAAZ;;EAOAf,IAAI,CAACgB,eAAL,GAAuB;EACrB,MAAMC,GAAG,GAAItO,GAAG,CAACuO,WAAJ,KAAoB,EAApB,IAA0BvO,GAAG,CAACuO,WAAJ,KAAoB,CAAC,EAA5D;EACA,SAAOlB,IAAI,CAACe,IAAL,KAAc,CAACE,GAAf,GAAqBA,GAA5B;EACD,CAHD;;;EAMAjB,IAAI,CAACmB,qBAAL,GAA6B,UAASC,eAAT;EAC3B,MAAIC,KAAK,CAACD,eAAD,CAAT,EAA4B;EAC1B,WAAO,KAAP;EACD;;EACD,MAAIA,eAAe,IAAIpB,IAAI,CAACC,YAA5B,EAA0C;EACxC,WAAO,KAAP;EACD;;EACD,MAAImB,eAAe,GAAGpB,IAAI,CAACE,YAA3B,EAAyC;EACvC,WAAO,KAAP;EACD;;EACD,SAAO,IAAP;EACD,CAXD;;EAaAF,IAAI,CAACsB,cAAL,GAAsB;EACpB,SAAOzO,IAAI,CAAC0N,GAAL,CAAS5N,GAAG,CAAC4O,MAAJ,CAAWC,KAApB,EAA2B7O,GAAG,CAAC4O,MAAJ,CAAWE,MAAtC,IACH9O,GAAG,CAACuB,gBADR;EAED,CAHD;;EAKA8L,IAAI,CAAC0B,eAAL,GAAuB;EACrB,SAAO7O,IAAI,CAACyN,GAAL,CAAS3N,GAAG,CAAC4O,MAAJ,CAAWC,KAApB,EAA2B7O,GAAG,CAAC4O,MAAJ,CAAWE,MAAtC,IACH9O,GAAG,CAACuB,gBADR;EAED,CAHD;;EAKA8L,IAAI,CAAC2B,iBAAL,GAAyB,UAASC,OAAT;EACvB,MAAI5B,IAAI,CAACW,gBAAL,EAAJ,EAA6B;EAC3B,WAAO,KAAP;EACD;;EACD,MAAIiB,OAAO,CAACD,iBAAZ,EAA+B;EAC7BC,IAAAA,OAAO,CAACD,iBAAR;EACD,GAFD,MAEO,IAAIC,OAAO,CAACC,uBAAZ,EAAqC;EAC1CD,IAAAA,OAAO,CAACC,uBAAR;EACD,GAFM,MAEA,IAAID,OAAO,CAACE,oBAAZ,EAAkC;EACvCF,IAAAA,OAAO,CAACE,oBAAR;EACD,GAFM,MAEA,IAAIF,OAAO,CAACG,mBAAZ,EAAiC;EACtCH,IAAAA,OAAO,CAACG,mBAAR;EACD,GAFM,MAEA;EACL,WAAO,KAAP;EACD;;EAED,SAAO,IAAP;EACD,CAjBD;;EAmBA/B,IAAI,CAACgC,cAAL,GAAsB;EACpB,MAAIhP,GAAG,CAACgP,cAAR,EAAwB;EACtBhP,IAAAA,GAAG,CAACgP,cAAJ;EACD,GAFD,MAEO,IAAIhP,GAAG,CAACiP,oBAAR,EAA8B;EACnCjP,IAAAA,GAAG,CAACiP,oBAAJ;EACD,GAFM,MAEA,IAAIjP,GAAG,CAACkP,mBAAR,EAA6B;EAClClP,IAAAA,GAAG,CAACkP,mBAAJ;EACD,GAFM,MAEA,IAAIlP,GAAG,CAACmP,gBAAR,EAA0B;EAC/BnP,IAAAA,GAAG,CAACmP,gBAAJ;EACD,GAFM,MAEA;EACL,WAAO,KAAP;EACD;;EAED,SAAO,IAAP;EACD,CAdD;;EAgBAnC,IAAI,CAACoC,oBAAL,GAA4B;EAC1B,SAAOpP,GAAG,CAACqP,iBAAJ,IACLrP,GAAG,CAACsP,uBADC,IAELtP,GAAG,CAACuP,oBAFC,IAGLvP,GAAG,CAACwP,mBAHN;EAID,CALD;;EAOAxC,IAAI,CAACyC,WAAL,GAAmB,UAASC,EAAT,EAAaC,YAAb,EAA2BC,cAA3B,EAA2CC,iBAA3C;EACjB;EACA,MAAMC,YAAY,GAAGJ,EAAE,CAACK,YAAH,CAAgBL,EAAE,CAACM,aAAnB,CAArB;EACAN,EAAAA,EAAE,CAACO,YAAH,CAAgBH,YAAhB,EAA8BH,YAA9B;EACAD,EAAAA,EAAE,CAACQ,aAAH,CAAiBJ,YAAjB;EAEA,MAAMK,cAAc,GAAGT,EAAE,CAACK,YAAH,CAAgBL,EAAE,CAACU,eAAnB,CAAvB;EACAV,EAAAA,EAAE,CAACO,YAAH,CAAgBE,cAAhB,EAAgCP,cAAhC;EACAF,EAAAA,EAAE,CAACQ,aAAH,CAAiBC,cAAjB;EAEA,MAAME,OAAO,GAAGX,EAAE,CAACY,aAAH,EAAhB;EACAZ,EAAAA,EAAE,CAACa,YAAH,CAAgBF,OAAhB,EAAyBP,YAAzB;EACAJ,EAAAA,EAAE,CAACa,YAAH,CAAgBF,OAAhB,EAAyBF,cAAzB;;EAEA,OAAK,IAAMK,UAAX,IAAyBX,iBAAzB,EACEH,EAAE,CAACe,kBAAH,CAAsBJ,OAAtB,EAA+BR,iBAAiB,CAACW,UAAD,CAAhD,EAA8DA,UAA9D;;EAEFd,EAAAA,EAAE,CAACD,WAAH,CAAeY,OAAf;EAEAX,EAAAA,EAAE,CAACgB,YAAH,CAAgBZ,YAAhB;EACAJ,EAAAA,EAAE,CAACgB,YAAH,CAAgBP,cAAhB;EAEA,SAAOE,OAAP;EACD,CAvBD;;EAyBArD,IAAI,CAAC2D,kBAAL,GAA0B,UAASjB,EAAT,EAAaW,OAAb;EACxB,MAAMO,QAAQ,GAAG,EAAjB;EACA,MAAMC,YAAY,GAAGnB,EAAE,CAACoB,mBAAH,CAAuBT,OAAvB,EAAgCX,EAAE,CAACqB,eAAnC,CAArB;EACA,MAAIC,WAAW,GAAG,EAAlB;;EACA,OAAK,IAAIzP,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGsP,YAApB,EAAkCtP,CAAC,EAAnC,EAAuC;EACrC,QAAM0P,WAAW,GAAGvB,EAAE,CAACwB,gBAAH,CAAoBb,OAApB,EAA6B9O,CAA7B,CAApB;EACAyP,IAAAA,WAAW,GAAGC,WAAW,CAAC1Q,IAAZ,CAAiB4Q,OAAjB,CAAyB,KAAzB,EAAgC,EAAhC,CAAd;EACAP,IAAAA,QAAQ,CAACI,WAAD,CAAR,GAAwBtB,EAAE,CAAC0B,kBAAH,CAAsBf,OAAtB,EAA+BW,WAA/B,CAAxB;EACD;;EACD,SAAOJ,QAAP;EACD,CAVD;;EAYA5D,IAAI,CAACqE,WAAL,GAAmB,UAASC,GAAT,EAAcC,IAAd,EAAoBC,KAApB,EAA2BC,MAA3B,EAAmCC,GAAnC,EAAwCC,IAAxC,EAA8CC,GAA9C;EACjB,MAAMC,EAAE,GAAG,KAAKN,IAAI,GAAGC,KAAZ,CAAX;EACA,MAAMM,EAAE,GAAG,KAAKL,MAAM,GAAGC,GAAd,CAAX;EACA,MAAMK,EAAE,GAAG,KAAKJ,IAAI,GAAGC,GAAZ,CAAX;EACAN,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAC,CAAD,GAAKO,EAAd;EACAP,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAC,CAAD,GAAKQ,EAAd;EACAR,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,EAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,EAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,IAAIS,EAAd;EACAT,EAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAAV;EACAA,EAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAACC,IAAI,GAAGC,KAAR,IAAiBK,EAA3B;EACAP,EAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAACI,GAAG,GAAGD,MAAP,IAAiBK,EAA3B;EACAR,EAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAACM,GAAG,GAAGD,IAAP,IAAeI,EAAzB;EACAT,EAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAAV;EACA,SAAOA,GAAP;EACD,CArBD;;EAuBAtE,IAAI,CAACgF,SAAL,GAAiB,UAAS3U,MAAT,EAAiB4U,IAAjB;EACf,OAAK,IAAI1Q,CAAC,GAAG,CAAR,EAAWsB,CAAC,GAAGxF,MAAM,CAACiB,MAA3B,EAAmCiD,CAAC,GAAGsB,CAAvC,EAA0CtB,CAAC,EAA3C,EAA+C;EAC7C0Q,IAAAA,IAAI,CAAC1Q,CAAD,CAAJ,GAAUlE,MAAM,CAACkE,CAAD,CAAhB;EACD;EACF,CAJD;;EAMAyL,IAAI,CAACkF,QAAL,GAAgB;EACd,MAAIC,KAAK,GAAG,KAAZ;;EACA,GAAC,UAAS1P,CAAT;EACC,QAAI,2TAA2TuE,IAA3T,CAAgUvE,CAAhU,KAAsU,0kDAA0kDuE,IAA1kD,CAA+kDvE,CAAC,CAAC2P,MAAF,CAAS,CAAT,EAAY,CAAZ,CAA/kD,CAA1U,EAAy6DD,KAAK,GAAG,IAAR;EAC16D,GAFD,EAEGrR,WAAS,KAAIb,GAAG,SAAH,IAAAA,GAAG,WAAH,SAAA,GAAAA,GAAG,CAAEoS,MAAT,CAAT,IAA4B1S,GAAG,CAAC2S,KAFnC;;EAGA,SAAOH,KAAP;EACD,CAND;;EAQAnF,IAAI,CAACuF,MAAL,GAAc,UAASN,IAAT,EAAe5T,GAAf;EACZ,OAAK,IAAMb,GAAX,IAAkBa,GAAlB,EAAuB;EACrB,QAAIA,GAAG,CAACmU,cAAJ,CAAmBhV,GAAnB,CAAJ,EAA6B;EAC3ByU,MAAAA,IAAI,CAACzU,GAAD,CAAJ,GAAYa,GAAG,CAACb,GAAD,CAAf;EACD;EACF;;EAED,SAAOyU,IAAP;EACD,CARD;;EAUAjF,IAAI,CAACyF,uBAAL,GAA+B,UAASC,MAAT;EAC7B;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAI1F,IAAI,CAACS,KAAL,EAAJ,EAAkB;EAChB,QAAMkF,OAAK,GAAGD,MAAM,CAACpR,KAAP,CAAakN,KAA3B;EACA,QAAMoE,QAAM,GAAGF,MAAM,CAACpR,KAAP,CAAamN,MAA5B;EACAiE,IAAAA,MAAM,CAACpR,KAAP,CAAakN,KAAb,GAAsB5H,QAAQ,CAAC+L,OAAD,CAAR,GAAkB,CAAnB,GAAwB,IAA7C;EACAD,IAAAA,MAAM,CAACpR,KAAP,CAAamN,MAAb,GAAuB7H,QAAQ,CAACgM,QAAD,CAAT,GAAqB,IAA3C;EACAC,IAAAA,UAAU,CAAC;EACTH,MAAAA,MAAM,CAACpR,KAAP,CAAakN,KAAb,GAAqBmE,OAArB;EACAD,MAAAA,MAAM,CAACpR,KAAP,CAAamN,MAAb,GAAsBmE,QAAtB;EACD,KAHS,EAGP,GAHO,CAAV;EAID;;;EAGDjT,EAAAA,GAAG,CAACqN,IAAJ,GAAWA,IAAX;EACArN,EAAAA,GAAG,CAAC+S,MAAJ,GAAaA,MAAb;EACD,CAtBD;;EAwBA1F,IAAI,CAAC8F,OAAL,GAAe;EACb,SAAO9F,IAAI,CAAC+F,iBAAL,CAAuB,OAAvB,CAAP;EACD,CAFD;;EAIA/F,IAAI,CAAC+F,iBAAL,GAAyB,UAASxS,IAAT;EACvBA,EAAAA,IAAI,GAAGA,IAAI,CAAC4Q,OAAL,CAAa,MAAb,EAAqB,KAArB,EAA4BA,OAA5B,CAAoC,MAApC,EAA4C,KAA5C,CAAP;EACA,MAAM6B,KAAK,GAAG,IAAIC,MAAJ,CAAW,WAAW1S,IAAX,GAAkB,WAA7B,CAAd;EACA,MAAM2S,OAAO,GAAGF,KAAK,CAACrM,IAAN,CAAWwM,QAAQ,CAACC,MAApB,CAAhB;EACA,SAAOF,OAAO,KAAK,IAAZ,GAAmB,EAAnB,GAAwBG,kBAAkB,CAACH,OAAO,CAAC,CAAD,CAAP,CAAW/B,OAAX,CAAmB,KAAnB,EAA0B,GAA1B,CAAD,CAAjD;EACD,CALD;;EAOAnE,IAAI,CAACsG,iBAAL,GAA0B;EACxB,MAAMC,SAAS,GAAG1T,IAAI,CAAC6C,EAAL,GAAU,KAA5B;EACA,MAAM8Q,KAAK,GAAG3T,IAAI,CAAC6C,EAAL,GAAU,IAAxB;;EAGA,WAAS+Q,+BAAT,CAAyCnC,GAAzC,EAA8CoC,GAA9C,EAAmD/B,IAAnD,EAAyDC,GAAzD;EACE,QAAM+B,KAAK,GAAG9T,IAAI,CAAC+T,GAAL,CAASF,GAAG,GAAIA,GAAG,CAACG,SAAJ,GAAgBN,SAApB,GAAiCC,KAA7C,CAAd;EACA,QAAMM,OAAO,GAAGjU,IAAI,CAAC+T,GAAL,CAASF,GAAG,GAAIA,GAAG,CAACK,WAAJ,GAAkBR,SAAtB,GAAmCC,KAA/C,CAAhB;EACA,QAAMQ,OAAO,GAAGnU,IAAI,CAAC+T,GAAL,CAASF,GAAG,GAAIA,GAAG,CAACO,WAAJ,GAAkBV,SAAtB,GAAmCC,KAA/C,CAAhB;EACA,QAAMU,QAAQ,GAAGrU,IAAI,CAAC+T,GAAL,CAASF,GAAG,GAAIA,GAAG,CAACS,YAAJ,GAAmBZ,SAAvB,GAAoCC,KAAhD,CAAjB;EACA,QAAMY,MAAM,GAAG,OAAOJ,OAAO,GAAGE,QAAjB,CAAf;EACA,QAAMG,MAAM,GAAG,OAAOV,KAAK,GAAGG,OAAf,CAAf;EAEAxC,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS8C,MAAT;EACA9C,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,GAAT;EACAA,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,GAAT;EACAA,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,GAAT;EACAA,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,GAAT;EACAA,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS+C,MAAT;EACA/C,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,GAAT;EACAA,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,GAAT;EACAA,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,EAAE,CAAC0C,OAAO,GAAGE,QAAX,IAAuBE,MAAvB,GAAgC,GAAlC,CAAT;EACA9C,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAU,CAACqC,KAAK,GAAGG,OAAT,IAAoBO,MAApB,GAA6B,GAAvC;EACA/C,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAUM,GAAG,IAAID,IAAI,GAAGC,GAAX,CAAb;EACAN,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAAC,GAAX;EACAA,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,GAAV;EACAA,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,GAAV;EACAA,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAWM,GAAG,GAAGD,IAAP,IAAgBA,IAAI,GAAGC,GAAvB,CAAV;EACAN,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,GAAV;EACA,WAAOA,GAAP;EACD;;EAED,WAASgD,4BAAT,CAAsChD,GAAtC,EAA2ClI,CAA3C,EAA8CtK,CAA9C;EACE;EACA,QAAMqE,CAAC,GAAGiG,CAAC,CAAC,CAAD,CAAX;EACA,QAAMhG,CAAC,GAAGgG,CAAC,CAAC,CAAD,CAAX;EACA,QAAMN,CAAC,GAAGM,CAAC,CAAC,CAAD,CAAX;EACA,QAAMK,CAAC,GAAGL,CAAC,CAAC,CAAD,CAAX;EACA,QAAMmL,EAAE,GAAGpR,CAAC,GAAGA,CAAf;EACA,QAAMqR,EAAE,GAAGpR,CAAC,GAAGA,CAAf;EACA,QAAMqR,EAAE,GAAG3L,CAAC,GAAGA,CAAf;EAEA,QAAM4L,EAAE,GAAGvR,CAAC,GAAGoR,EAAf;EACA,QAAMI,EAAE,GAAGxR,CAAC,GAAGqR,EAAf;EACA,QAAMI,EAAE,GAAGzR,CAAC,GAAGsR,EAAf;EACA,QAAMI,EAAE,GAAGzR,CAAC,GAAGoR,EAAf;EACA,QAAMM,EAAE,GAAG1R,CAAC,GAAGqR,EAAf;EACA,QAAMM,EAAE,GAAGjM,CAAC,GAAG2L,EAAf;EACA,QAAMO,EAAE,GAAGvL,CAAC,GAAG8K,EAAf;EACA,QAAMU,EAAE,GAAGxL,CAAC,GAAG+K,EAAf;EACA,QAAMU,EAAE,GAAGzL,CAAC,GAAGgL,EAAf;EAEAnD,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,KAAKuD,EAAE,GAAGE,EAAV,CAAT;EACAzD,IAAAA,GAAG,CAAC,CAAD,CAAH,GAASqD,EAAE,GAAGO,EAAd;EACA5D,IAAAA,GAAG,CAAC,CAAD,CAAH,GAASsD,EAAE,GAAGK,EAAd;EACA3D,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,IAAAA,GAAG,CAAC,CAAD,CAAH,GAASqD,EAAE,GAAGO,EAAd;EACA5D,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,KAAKoD,EAAE,GAAGK,EAAV,CAAT;EACAzD,IAAAA,GAAG,CAAC,CAAD,CAAH,GAASwD,EAAE,GAAGE,EAAd;EACA1D,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAT;EACAA,IAAAA,GAAG,CAAC,CAAD,CAAH,GAASsD,EAAE,GAAGK,EAAd;EACA3D,IAAAA,GAAG,CAAC,CAAD,CAAH,GAASwD,EAAE,GAAGE,EAAd;EACA1D,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,KAAKoD,EAAE,GAAGG,EAAV,CAAV;EACAvD,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAAV;EACAA,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAUxS,CAAC,CAAC,CAAD,CAAX;EACAwS,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAUxS,CAAC,CAAC,CAAD,CAAX;EACAwS,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAUxS,CAAC,CAAC,CAAD,CAAX;EACAwS,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAAV;EAEA,WAAOA,GAAP;EACD;;EAED,WAAS6D,cAAT,CAAwB7D,GAAxB,EAA6B7O,CAA7B,EAAgC3D,CAAhC;EACE,QAAMqE,CAAC,GAAGrE,CAAC,CAAC,CAAD,CAAX;EACA,QAAMsE,CAAC,GAAGtE,CAAC,CAAC,CAAD,CAAX;EACA,QAAMgK,CAAC,GAAGhK,CAAC,CAAC,CAAD,CAAX;EACA,QAAIsW,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;EACA,QAAIC,GAAJ;;EAEA,QAAItT,CAAC,KAAK6O,GAAV,EAAe;EACbA,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAU7O,CAAC,CAAC,CAAD,CAAD,GAAOU,CAAP,GAAWV,CAAC,CAAC,CAAD,CAAD,GAAOW,CAAlB,GAAsBX,CAAC,CAAC,CAAD,CAAD,GAAOqG,CAA7B,GAAiCrG,CAAC,CAAC,EAAD,CAA5C;EACA6O,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAU7O,CAAC,CAAC,CAAD,CAAD,GAAOU,CAAP,GAAWV,CAAC,CAAC,CAAD,CAAD,GAAOW,CAAlB,GAAsBX,CAAC,CAAC,CAAD,CAAD,GAAOqG,CAA7B,GAAiCrG,CAAC,CAAC,EAAD,CAA5C;EACA6O,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAU7O,CAAC,CAAC,CAAD,CAAD,GAAOU,CAAP,GAAWV,CAAC,CAAC,CAAD,CAAD,GAAOW,CAAlB,GAAsBX,CAAC,CAAC,EAAD,CAAD,GAAQqG,CAA9B,GAAkCrG,CAAC,CAAC,EAAD,CAA7C;EACA6O,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAU7O,CAAC,CAAC,CAAD,CAAD,GAAOU,CAAP,GAAWV,CAAC,CAAC,CAAD,CAAD,GAAOW,CAAlB,GAAsBX,CAAC,CAAC,EAAD,CAAD,GAAQqG,CAA9B,GAAkCrG,CAAC,CAAC,EAAD,CAA7C;EACD,KALD,MAKO;EACL2S,MAAAA,GAAG,GAAG3S,CAAC,CAAC,CAAD,CAAP;EAAY4S,MAAAA,GAAG,GAAG5S,CAAC,CAAC,CAAD,CAAP;EAAY6S,MAAAA,GAAG,GAAG7S,CAAC,CAAC,CAAD,CAAP;EAAY8S,MAAAA,GAAG,GAAG9S,CAAC,CAAC,CAAD,CAAP;EACpC+S,MAAAA,GAAG,GAAG/S,CAAC,CAAC,CAAD,CAAP;EAAYgT,MAAAA,GAAG,GAAGhT,CAAC,CAAC,CAAD,CAAP;EAAYiT,MAAAA,GAAG,GAAGjT,CAAC,CAAC,CAAD,CAAP;EAAYkT,MAAAA,GAAG,GAAGlT,CAAC,CAAC,CAAD,CAAP;EACpCmT,MAAAA,GAAG,GAAGnT,CAAC,CAAC,CAAD,CAAP;EAAYoT,MAAAA,GAAG,GAAGpT,CAAC,CAAC,CAAD,CAAP;EAAYqT,MAAAA,GAAG,GAAGrT,CAAC,CAAC,EAAD,CAAP;EAAasT,MAAAA,GAAG,GAAGtT,CAAC,CAAC,EAAD,CAAP;EAErC6O,MAAAA,GAAG,CAAC,CAAD,CAAH,GAAS8D,GAAT;EAAc9D,MAAAA,GAAG,CAAC,CAAD,CAAH,GAAS+D,GAAT;EAAc/D,MAAAA,GAAG,CAAC,CAAD,CAAH,GAASgE,GAAT;EAAchE,MAAAA,GAAG,CAAC,CAAD,CAAH,GAASiE,GAAT;EAC1CjE,MAAAA,GAAG,CAAC,CAAD,CAAH,GAASkE,GAAT;EAAclE,MAAAA,GAAG,CAAC,CAAD,CAAH,GAASmE,GAAT;EAAcnE,MAAAA,GAAG,CAAC,CAAD,CAAH,GAASoE,GAAT;EAAcpE,MAAAA,GAAG,CAAC,CAAD,CAAH,GAASqE,GAAT;EAC1CrE,MAAAA,GAAG,CAAC,CAAD,CAAH,GAASsE,GAAT;EAActE,MAAAA,GAAG,CAAC,CAAD,CAAH,GAASuE,GAAT;EAAcvE,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAUwE,GAAV;EAAexE,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAUyE,GAAV;EAE3CzE,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAU8D,GAAG,GAAGjS,CAAN,GAAUqS,GAAG,GAAGpS,CAAhB,GAAoBwS,GAAG,GAAG9M,CAA1B,GAA8BrG,CAAC,CAAC,EAAD,CAAzC;EACA6O,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAU+D,GAAG,GAAGlS,CAAN,GAAUsS,GAAG,GAAGrS,CAAhB,GAAoByS,GAAG,GAAG/M,CAA1B,GAA8BrG,CAAC,CAAC,EAAD,CAAzC;EACA6O,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAUgE,GAAG,GAAGnS,CAAN,GAAUuS,GAAG,GAAGtS,CAAhB,GAAoB0S,GAAG,GAAGhN,CAA1B,GAA8BrG,CAAC,CAAC,EAAD,CAAzC;EACA6O,MAAAA,GAAG,CAAC,EAAD,CAAH,GAAUiE,GAAG,GAAGpS,CAAN,GAAUwS,GAAG,GAAGvS,CAAhB,GAAoB2S,GAAG,GAAGjN,CAA1B,GAA8BrG,CAAC,CAAC,EAAD,CAAzC;EACD;;EAED,WAAO6O,GAAP;EACD;;EAED,WAAS0E,WAAT,CAAqB1E,GAArB,EAA0B7O,CAA1B;EACE,QAAM2S,GAAG,GAAG3S,CAAC,CAAC,CAAD,CAAb;EACA,QAAM4S,GAAG,GAAG5S,CAAC,CAAC,CAAD,CAAb;EACA,QAAM6S,GAAG,GAAG7S,CAAC,CAAC,CAAD,CAAb;EACA,QAAM8S,GAAG,GAAG9S,CAAC,CAAC,CAAD,CAAb;EACA,QAAM+S,GAAG,GAAG/S,CAAC,CAAC,CAAD,CAAb;EACA,QAAMgT,GAAG,GAAGhT,CAAC,CAAC,CAAD,CAAb;EACA,QAAMiT,GAAG,GAAGjT,CAAC,CAAC,CAAD,CAAb;EACA,QAAMkT,GAAG,GAAGlT,CAAC,CAAC,CAAD,CAAb;EACA,QAAMmT,GAAG,GAAGnT,CAAC,CAAC,CAAD,CAAb;EACA,QAAMoT,GAAG,GAAGpT,CAAC,CAAC,CAAD,CAAb;EACA,QAAMqT,GAAG,GAAGrT,CAAC,CAAC,EAAD,CAAb;EACA,QAAMsT,GAAG,GAAGtT,CAAC,CAAC,EAAD,CAAb;EACA,QAAMwT,GAAG,GAAGxT,CAAC,CAAC,EAAD,CAAb;EACA,QAAMyT,GAAG,GAAGzT,CAAC,CAAC,EAAD,CAAb;EACA,QAAM0T,GAAG,GAAG1T,CAAC,CAAC,EAAD,CAAb;EACA,QAAM2T,GAAG,GAAG3T,CAAC,CAAC,EAAD,CAAb;EAEA,QAAM4T,GAAG,GAAGjB,GAAG,GAAGK,GAAN,GAAYJ,GAAG,GAAGG,GAA9B;EACA,QAAMc,GAAG,GAAGlB,GAAG,GAAGM,GAAN,GAAYJ,GAAG,GAAGE,GAA9B;EACA,QAAMe,GAAG,GAAGnB,GAAG,GAAGO,GAAN,GAAYJ,GAAG,GAAGC,GAA9B;EACA,QAAMgB,GAAG,GAAGnB,GAAG,GAAGK,GAAN,GAAYJ,GAAG,GAAGG,GAA9B;EACA,QAAMgB,GAAG,GAAGpB,GAAG,GAAGM,GAAN,GAAYJ,GAAG,GAAGE,GAA9B;EACA,QAAMiB,GAAG,GAAGpB,GAAG,GAAGK,GAAN,GAAYJ,GAAG,GAAGG,GAA9B;EACA,QAAMiB,GAAG,GAAGf,GAAG,GAAGM,GAAN,GAAYL,GAAG,GAAGI,GAA9B;EACA,QAAMW,GAAG,GAAGhB,GAAG,GAAGO,GAAN,GAAYL,GAAG,GAAGG,GAA9B;EACA,QAAMY,GAAG,GAAGjB,GAAG,GAAGQ,GAAN,GAAYL,GAAG,GAAGE,GAA9B;EACA,QAAMa,GAAG,GAAGjB,GAAG,GAAGM,GAAN,GAAYL,GAAG,GAAGI,GAA9B;EACA,QAAMa,GAAG,GAAGlB,GAAG,GAAGO,GAAN,GAAYL,GAAG,GAAGG,GAA9B;EACA,QAAMc,GAAG,GAAGlB,GAAG,GAAGM,GAAN,GAAYL,GAAG,GAAGI,GAA9B;;EAGA,QAAIzQ,GAAG,GAAG2Q,GAAG,GAAGW,GAAN,GAAYV,GAAG,GAAGS,GAAlB,GAAwBR,GAAG,GAAGO,GAA9B,GAAoCN,GAAG,GAAGK,GAA1C,GAAgDJ,GAAG,GAAGG,GAAtD,GAA4DF,GAAG,GAAGC,GAA5E;;EAEA,QAAI,CAACjR,GAAL,EAAU;EACR,aAAO,IAAP;EACD;;EACDA,IAAAA,GAAG,GAAG,MAAMA,GAAZ;EAEA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAACmE,GAAG,GAAGuB,GAAN,GAAYtB,GAAG,GAAGqB,GAAlB,GAAwBpB,GAAG,GAAGmB,GAA/B,IAAsCpR,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAACgE,GAAG,GAAGyB,GAAN,GAAY1B,GAAG,GAAG2B,GAAlB,GAAwBzB,GAAG,GAAGuB,GAA/B,IAAsCpR,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAC4E,GAAG,GAAGQ,GAAN,GAAYP,GAAG,GAAGM,GAAlB,GAAwBL,GAAG,GAAGI,GAA/B,IAAsC9Q,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAACwE,GAAG,GAAGW,GAAN,GAAYZ,GAAG,GAAGa,GAAlB,GAAwBX,GAAG,GAAGS,GAA/B,IAAsC9Q,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAACoE,GAAG,GAAGmB,GAAN,GAAYrB,GAAG,GAAGwB,GAAlB,GAAwBrB,GAAG,GAAGiB,GAA/B,IAAsClR,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAC8D,GAAG,GAAG4B,GAAN,GAAY1B,GAAG,GAAGuB,GAAlB,GAAwBtB,GAAG,GAAGqB,GAA/B,IAAsClR,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAC6E,GAAG,GAAGI,GAAN,GAAYN,GAAG,GAAGS,GAAlB,GAAwBN,GAAG,GAAGE,GAA/B,IAAsC5Q,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAACsE,GAAG,GAAGc,GAAN,GAAYZ,GAAG,GAAGS,GAAlB,GAAwBR,GAAG,GAAGO,GAA/B,IAAsC5Q,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAACkE,GAAG,GAAGuB,GAAN,GAAYtB,GAAG,GAAGoB,GAAlB,GAAwBlB,GAAG,GAAGgB,GAA/B,IAAsCjR,GAA/C;EACA4L,IAAAA,GAAG,CAAC,CAAD,CAAH,GAAS,CAAC+D,GAAG,GAAGwB,GAAN,GAAYzB,GAAG,GAAG2B,GAAlB,GAAwBxB,GAAG,GAAGoB,GAA/B,IAAsCjR,GAA/C;EACA4L,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAAC2E,GAAG,GAAGQ,GAAN,GAAYP,GAAG,GAAGK,GAAlB,GAAwBH,GAAG,GAAGC,GAA/B,IAAsC3Q,GAAhD;EACA4L,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAACuE,GAAG,GAAGU,GAAN,GAAYX,GAAG,GAAGa,GAAlB,GAAwBV,GAAG,GAAGM,GAA/B,IAAsC3Q,GAAhD;EACA4L,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAACmE,GAAG,GAAGmB,GAAN,GAAYpB,GAAG,GAAGsB,GAAlB,GAAwBpB,GAAG,GAAGiB,GAA/B,IAAsCjR,GAAhD;EACA4L,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAAC8D,GAAG,GAAG0B,GAAN,GAAYzB,GAAG,GAAGuB,GAAlB,GAAwBtB,GAAG,GAAGqB,GAA/B,IAAsCjR,GAAhD;EACA4L,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAAC4E,GAAG,GAAGI,GAAN,GAAYL,GAAG,GAAGO,GAAlB,GAAwBL,GAAG,GAAGE,GAA/B,IAAsC3Q,GAAhD;EACA4L,IAAAA,GAAG,CAAC,EAAD,CAAH,GAAU,CAACsE,GAAG,GAAGY,GAAN,GAAYX,GAAG,GAAGS,GAAlB,GAAwBR,GAAG,GAAGO,GAA/B,IAAsC3Q,GAAhD;EAEA,WAAO4L,GAAP;EACD;;EAED,MAAM2F,kBAAkB,GAAG,IAAIrW,YAAJ,CAAiB,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAU,CAAV,CAAjB,CAA3B;EACA,MAAMsW,eAAe,GAAG,IAAItW,YAAJ,CAAiB,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,CAAjB,CAAxB;;EAEA,WAASuW,iBAAT,CAA2BC,UAA3B,EAAuCC,IAAvC,EAA6CC,IAA7C,EAAmDC,UAAnD,EAA+DC,SAA/D;EACE/D,IAAAA,+BAA+B,CAAC2D,UAAD,EAAaG,UAAU,GAAGA,UAAU,CAACE,WAAd,GAA4B,IAAnD,EAAyDD,SAAS,CAACE,SAAnE,EAA8EF,SAAS,CAACG,QAAxF,CAA/B;EAEA,QAAMzJ,WAAW,GAAGoJ,IAAI,CAACpJ,WAAL,IAAoB+I,kBAAxC;EACA,QAAMW,QAAQ,GAAGN,IAAI,CAACM,QAAL,IAAiBV,eAAlC;EAEA5C,IAAAA,4BAA4B,CAAC+C,IAAD,EAAOnJ,WAAP,EAAoB0J,QAApB,CAA5B;EACA,QAAIL,UAAJ,EACEpC,cAAc,CAACkC,IAAD,EAAOA,IAAP,EAAaE,UAAU,CAACnR,MAAxB,CAAd;EACF4P,IAAAA,WAAW,CAACqB,IAAD,EAAOA,IAAP,CAAX;EACD;;EAED,SAAO,UAASQ,SAAT,EAAoBP,IAApB,EAA0BE,SAA1B;EACL,QAAI,CAACK,SAAD,IAAc,CAACP,IAAnB,EACE,OAAO,KAAP;EAEFO,IAAAA,SAAS,CAACP,IAAV,GAAiBA,IAAjB;EACAO,IAAAA,SAAS,CAACC,SAAV,GAAsBR,IAAI,CAACQ,SAA3B;EAEAX,IAAAA,iBAAiB,CACfU,SAAS,CAACE,oBADK,EACiBF,SAAS,CAACG,cAD3B,EAEfV,IAFe,EAETE,SAAS,CAACS,gBAAV,CAA2B,MAA3B,CAFS,EAE2BT,SAF3B,CAAjB;EAGAL,IAAAA,iBAAiB,CACfU,SAAS,CAACK,qBADK,EACkBL,SAAS,CAACM,eAD5B,EAEfb,IAFe,EAETE,SAAS,CAACS,gBAAV,CAA2B,OAA3B,CAFS,EAE4BT,SAF5B,CAAjB;EAIA,WAAO,IAAP;EACD,GAfD;EAgBD,CA1MwB,EAAzB;;EA4MAxK,IAAI,CAACoL,yBAAL,GAAiC;EAC/B,MAAMC,QAAQ,GAAI1Y,GAAG,CAACG,IAAJ,KAAaH,GAAG,CAAC+R,GAAnC;EACA,MAAM4G,SAAS,GAAGtL,IAAI,CAACuL,gBAAL,CAAsBvY,GAAG,CAACwY,QAA1B,CAAlB;EACA,MAAMC,UAAU,GAAGzL,IAAI,CAACuL,gBAAL,CAAsB5Y,GAAG,CAACwT,QAAJ,CAAauF,IAAnC,CAAnB;EAEA,SAAOL,QAAQ,IAAKC,SAAS,KAAKG,UAAlC;EACD,CAND;;;EASAzL,IAAI,CAACuL,gBAAL,GAAwB,UAASI,GAAT;EACtB,MAAIC,MAAJ;;EAEA,MAAID,GAAG,CAAC/K,OAAJ,CAAY,KAAZ,IAAqB,CAAC,CAA1B,EAA6B;EAC3BgL,IAAAA,MAAM,GAAGD,GAAG,CAACE,KAAJ,CAAU,GAAV,EAAe,CAAf,CAAT;EACD,GAFD,MAEO;EACLD,IAAAA,MAAM,GAAGD,GAAG,CAACE,KAAJ,CAAU,GAAV,EAAe,CAAf,CAAT;EACD;;;EAGDD,EAAAA,MAAM,GAAGA,MAAM,CAACC,KAAP,CAAa,GAAb,EAAkB,CAAlB,CAAT;EAEA,SAAOD,MAAP;EACD,CAbD;;EC/dA;EAmBA;;;;;;;;;EAQA;;;EAOE,wBAAA,CAAmBE,eAAnB;EACE,SAAKA,eAAL,GAAuBA,eAAvB;;EAGA,SAAKC,SAAL,GAAiB,IAAI5Q,QAAQ,CAACmC,UAAb,EAAjB;;EAEA,SAAK0O,kBAAL,GAA0B,IAA1B;;EAGA,SAAKC,MAAL,GAAc,IAAI9Q,QAAQ,CAACmC,UAAb,EAAd;;EAEA,SAAK4O,IAAL,GAAY,IAAI/Q,QAAQ,CAACmC,UAAb,EAAZ;EACD;;;;EAEM,uBAAA,GAAP,UAAqB6O,QAArB,EAA+BC,IAA/B,EAAqCC,UAArC;EACE,QAAI,CAAC,KAAKL,kBAAV,EAA8B;EAC5B,WAAKD,SAAL,CAAerQ,IAAf,CAAoByQ,QAApB;EACA,WAAKH,kBAAL,GAA0BK,UAA1B;EACA,aAAOF,QAAP;EACD;;;EAGD,QAAMhO,IAAI,GAAG,IAAIhD,QAAQ,CAACU,OAAb,EAAb;EACAsC,IAAAA,IAAI,CAACzC,IAAL,CAAU0Q,IAAV;EACAjO,IAAAA,IAAI,CAACpC,SAAL;EAEA,QAAMuQ,YAAY,GAAGF,IAAI,CAAC9a,MAAL,EAArB;;EAGA,QAAIgb,YAAY,GAAGnR,QAAQ,CAACC,QAAT,GAAoB,EAAvC,EAA2C;EACzC,UAAI4E,IAAI,CAAC8F,OAAL,EAAJ,EAAoB;EAClByG,QAAAA,OAAO,CAACC,GAAR,CAAY,2CAAZ,EACE,CAACrR,QAAQ,CAACE,QAAT,GAAoBiR,YAArB,EAAmCG,OAAnC,CAA2C,CAA3C,CADF;EAED;;EACD,WAAKP,IAAL,CAAUxQ,IAAV,CAAeyQ,QAAf;EACA,WAAKJ,SAAL,CAAerQ,IAAf,CAAoByQ,QAApB;EACA,aAAO,KAAKD,IAAZ;EACD;;;EAGD,QAAMQ,MAAM,GAAGL,UAAU,GAAG,KAAKL,kBAAjC;EACA,QAAMW,YAAY,GAAGL,YAAY,GAAG,KAAKR,eAAzC;EAEA,SAAKG,MAAL,CAAY/N,gBAAZ,CAA6BC,IAA7B,EAAmCwO,YAAnC;EACA,SAAKT,IAAL,CAAUxQ,IAAV,CAAe,KAAKqQ,SAApB;EACA,SAAKG,IAAL,CAAU3N,QAAV,CAAmB,KAAK0N,MAAxB;EAEA,SAAKF,SAAL,CAAerQ,IAAf,CAAoByQ,QAApB;EACA,SAAKH,kBAAL,GAA0BK,UAA1B;EAEA,WAAO,KAAKH,IAAZ;EACD,GArCM;;EAsCT,sBAAA;EAAC,GA3DD;;ECpBA,IAAMU,mBAAmB,GAAG,GAA5B;;EAEA;;;EAA0CC,EAAAA,+BAAA;;EAsBxC,uBAAA;EAAA,gBACEC,WAAA,KAAA,SADF;;EAEEC,IAAAA,KAAI,CAACC,eAAL,GAAuBD,KAAI,CAACC,eAAL,CAAqBC,IAArB,CAA0BF,KAA1B,CAAvB;EACAA,IAAAA,KAAI,CAACG,oBAAL,GAA4BH,KAAI,CAACG,oBAAL,CAA0BD,IAA1B,CAA+BF,KAA/B,CAA5B;EACAA,IAAAA,KAAI,CAACI,4BAAL,GAAoCJ,KAAI,CAACI,4BAAL,CAAkCF,IAAlC,CAAuCF,KAAvC,CAApC;EAEAA,IAAAA,KAAI,CAACK,qBAAL,GAA6BtT,+BAA7B;EACAiT,IAAAA,KAAI,CAACM,SAAL,GAAiBtT,UAAjB;EAEAgT,IAAAA,KAAI,CAACO,YAAL,GAAoB/X,QAAA,EAApB;EACAwX,IAAAA,KAAI,CAACQ,UAAL,GAAkBhY,QAAA,EAAlB;EACAwX,IAAAA,KAAI,CAACS,eAAL,GAAuBjY,QAAA,EAAvB;EAEAwX,IAAAA,KAAI,CAACU,MAAL,GAAc,CAAC,CAAf;EAEAV,IAAAA,KAAI,CAACW,yBAAL,GAAiC,CAAjC;EACAX,IAAAA,KAAI,CAACY,UAAL,GAAkB,KAAlB;;EACAZ,IAAAA,KAAI,CAACa,MAAL;;;EACD;;;;EAEM,gBAAA,GAAP;EACE,QAAI,KAAKP,SAAT,EAAoB;EAClBza,MAAAA,GAAM,CAACib,gBAAP,CAAwB,mBAAxB,EAA6C,KAAKX,oBAAlD;EACD;;EACD,QAAI,KAAKE,qBAAT,EAAgC;EAC9Bxa,MAAAA,GAAM,CAACib,gBAAP,CAAwB,mBAAxB,EAA6C,KAAKV,4BAAlD;EACD,KAFD,MAEO;EACLva,MAAAA,GAAM,CAACib,gBAAP,CAAwB,cAAxB,EAAwC,KAAKb,eAA7C;EACD;;EACD,SAAKW,UAAL,GAAkB,IAAlB;EACD,GAVM;;EAYA,iBAAA,GAAP;EACE/a,IAAAA,GAAM,CAACkb,mBAAP,CAA2B,mBAA3B,EAAgD,KAAKZ,oBAArD;EACAta,IAAAA,GAAM,CAACkb,mBAAP,CAA2B,mBAA3B,EAAgD,KAAKX,4BAArD;EACAva,IAAAA,GAAM,CAACkb,mBAAP,CAA2B,cAA3B,EAA2C,KAAKd,eAAhD;EACA,SAAKW,UAAL,GAAkB,KAAlB;EACD,GALM;;EAOC,sCAAA,GAAR,UAAqCI,CAArC;EACO,QAAAC,KAAK,GAAiBD,CAAC,MAAvB;EAAA,QAAOE,IAAI,GAAWF,CAAC,KAAvB;EAAA,QAAaG,KAAK,GAAIH,CAAC,MAAvB;EAGL;;EACA,QAAIC,KAAK,KAAK,IAAd,EAAoB;EAClB;EACD;;;EAGDA,IAAAA,KAAK,GAAG,CAACA,KAAK,IAAI,CAAV,IAAenb,IAAI,CAAC6C,EAApB,GAAyB,GAAjC;EACAuY,IAAAA,IAAI,GAAG,CAACA,IAAI,IAAI,CAAT,IAAcpb,IAAI,CAAC6C,EAAnB,GAAwB,GAA/B;EACAwY,IAAAA,KAAK,GAAG,CAACA,KAAK,IAAI,CAAV,IAAerb,IAAI,CAAC6C,EAApB,GAAyB,GAAjC;EAEA,SAAKyY,OAAL,CAAa,IAAIC,gBAAJ,CAAmB,cAAnB,EAAmC;EAC9CC,MAAAA,UAAU,EAAE;EACVC,QAAAA,iBAAiB,EAAE;EACjBN,UAAAA,KAAK,OADY;EAEjBC,UAAAA,IAAI,MAFa;EAGjBC,UAAAA,KAAK,EAAE,CAACA;EAHS;EADT;EADkC,KAAnC,CAAb;EASD,GAvBO;;EAyBA,8BAAA,GAAR;EAAA,oBAAA;;EACE,QAAI,KAAKT,MAAT,EAAiB;EACfc,MAAAA,YAAY,CAAC,KAAKd,MAAN,CAAZ;EACD;;EAED,SAAKA,MAAL,GAAc7a,GAAM,CAACiT,UAAP,CAAkB;EAC9B,UAAK,IAAI2I,IAAJ,GAAWC,OAAX,KAAuB1B,KAAI,CAACW,yBAA7B,GAA0Dd,mBAA9D,EAAmF;EACjFrX,QAAAA,IAAA,CAAUwX,KAAI,CAACO,YAAf,EAA6BP,KAAI,CAACQ,UAAlC;EACD;EACF,KAJa,EAIXX,mBAJW,CAAd;EAKD,GAVO;;EAYA,yBAAA,GAAR,UAAwBmB,CAAxB;EACE;EACA;EACA,QAAMW,qBAAqB,GAAG,EAAEX,CAAC,CAACY,YAAF,CAAgBX,KAAhB,IAAyB,IAA3B,CAA9B;EACA,QAAMY,wBAAwB,GAAG,EAAEb,CAAC,CAACc,4BAAF,CAAgC1Y,CAAhC,IAAqC,IAAvC,CAAjC;;EAEA,QAAI4X,CAAC,CAACe,QAAF,KAAe,CAAf,IAAoB,EAAEJ,qBAAqB,IAAIE,wBAA3B,CAAxB,EAA8E;EAC5E;EACD;;EAED,QAAMG,iBAAiB,GAAGC,aAAIjB,EAA9B;;EAEAgB,IAAAA,iBAAiB,CAACD,QAAlB,GAA6Bf,CAAC,CAACe,QAA/B;EACAC,IAAAA,iBAAiB,CAACE,SAAlB,GAA8BlB,CAAC,CAACkB,SAAhC;EACAF,IAAAA,iBAAiB,CAACvc,IAAlB,GAAyBub,CAAC,CAACvb,IAA3B;EACAuc,IAAAA,iBAAiB,CAACJ,YAAlB,GAAiC;EAC/BX,MAAAA,KAAK,EAAED,CAAC,CAACY,YAAF,CAAgBX,KADQ;EAE/BC,MAAAA,IAAI,EAAEF,CAAC,CAACY,YAAF,CAAgBV,IAFS;EAG/BC,MAAAA,KAAK,EAAEH,CAAC,CAACY,YAAF,CAAgBT;EAHQ,KAAjC;EAKAa,IAAAA,iBAAiB,CAACF,4BAAlB,GAAiD;EAC/C1Y,MAAAA,CAAC,EAAE4X,CAAC,CAACc,4BAAF,CAAgC1Y,CADY;EAE/CC,MAAAA,CAAC,EAAE2X,CAAC,CAACc,4BAAF,CAAgCzY,CAFY;EAG/C0F,MAAAA,CAAC,EAAEiS,CAAC,CAACc,4BAAF,CAAgC/S;EAHY,KAAjD;EAKAiT,IAAAA,iBAAiB,CAACG,YAAlB,GAAiC;EAC/B/Y,MAAAA,CAAC,EAAE4X,CAAC,CAACmB,YAAF,CAAgB/Y,CADY;EAE/BC,MAAAA,CAAC,EAAE2X,CAAC,CAACmB,YAAF,CAAgB9Y,CAFY;EAG/B0F,MAAAA,CAAC,EAAEiS,CAAC,CAACmB,YAAF,CAAgBpT;EAHY,KAAjC;;EAMA,QAAI,KAAKuR,SAAT,EAAoB;EAClB9X,MAAAA,GAAA,CACE,KAAKgY,UADP,EAEEQ,CAAC,CAACY,YAAF,CAAgBX,KAAhB,IAAyB,CAF3B,EAGED,CAAC,CAACY,YAAF,CAAgBV,IAAhB,IAAwB,CAH1B,EAIEF,CAAC,CAACY,YAAF,CAAgBT,KAAhB,IAAyB,CAJ3B;EAKA3Y,MAAAA,QAAA,CAAc,KAAKiY,eAAnB,EAAoC,KAAKD,UAAzC,EAAqD,KAAKD,YAA1D;EACA,WAAKI,yBAAL,GAAiC,IAAIc,IAAJ,GAAWC,OAAX,EAAjC;EAECM,MAAAA,iBAAyB,CAACI,oBAA1B,GAAiD;EAChDnB,QAAAA,KAAK,EAAE,KAAKR,eAAL,CAAqB,CAArB,CADyC;EAEhDS,QAAAA,IAAI,EAAE,KAAKT,eAAL,CAAqB,CAArB,CAF0C;EAGhDU,QAAAA,KAAK,EAAE,KAAKV,eAAL,CAAqB,CAArB;EAHyC,OAAjD;EAIF;;EAED,SAAKW,OAAL,CAAa,IAAIC,gBAAJ,CAAmB,cAAnB,EAAmC;EAC9CC,MAAAA,UAAU,EAAEU;EADkC,KAAnC,CAAb;EAGD,GAjDO;;EAkDV,qBAAA;EApJA,EAA0CK,UAA1C;;ECTA;;;EAIE,uBAAA,CAAmBC,MAAnB,EAA4BhD,UAA5B;EACE,SAAK5Q,GAAL,CAAS4T,MAAT,EAAiBhD,UAAjB;EACD;;;;EAEM,aAAA,GAAP,UAAWgD,MAAX,EAAmBhD,UAAnB;EACE,SAAKgD,MAAL,GAAcA,MAAd;EACA,SAAKhD,UAAL,GAAkBA,UAAlB;EACD,GAHM;;EAKA,cAAA,GAAP,UAAYiD,YAAZ;EACE,SAAK7T,GAAL,CAAS6T,YAAY,CAACD,MAAtB,EAA8BC,YAAY,CAACjD,UAA3C;EACD,GAFM;;EAGT,qBAAA;EAAC,GAhBD;;ECAA;EAoBA;;;;;;;;;;;;;;;EAcA;;;EAaE,8BAAA,CAAYkD,OAAZ;EAkCO,2BAAA,GAAqB,UAASC,MAAT,EAAiBnD,UAAjB;EAC1B,WAAKoD,sBAAL,CAA4BhU,GAA5B,CAAgC+T,MAAhC,EAAwCnD,UAAxC;EAEA,UAAMK,MAAM,GAAGL,UAAU,GAAG,KAAKqD,uBAAL,CAA6BrD,UAAzD;;EACA,UAAIrM,IAAI,CAACmB,qBAAL,CAA2BuL,MAA3B,CAAJ,EAAwC;EACtC,aAAKiD,IAAL;EACD;;EAED,WAAKD,uBAAL,CAA6BhU,IAA7B,CAAkC,KAAK+T,sBAAvC;EACD,KATM;;EAjCL,SAAKF,OAAL,GAAeA,OAAf;;EAGA,SAAKK,uBAAL,GAA+B,IAAIC,YAAJ,EAA/B;EACA,SAAKJ,sBAAL,GAA8B,IAAII,YAAJ,EAA9B;EACA,SAAKH,uBAAL,GAA+B,IAAIG,YAAJ,EAA/B;;EAGA,QAAI7P,IAAI,CAACS,KAAL,EAAJ,EAAkB;EAChB,WAAKqP,OAAL,GAAe,IAAI3U,QAAQ,CAACmC,UAAb,CAAwB,CAAC,CAAzB,EAA4B,CAA5B,EAA+B,CAA/B,EAAkC,CAAlC,CAAf;EACD,KAFD,MAEO;EACL,WAAKwS,OAAL,GAAe,IAAI3U,QAAQ,CAACmC,UAAb,CAAwB,CAAxB,EAA2B,CAA3B,EAA8B,CAA9B,EAAiC,CAAjC,CAAf;EACD;;EACD,SAAKyS,eAAL,GAAuB,IAAI5U,QAAQ,CAACmC,UAAb,EAAvB;EACA,SAAKyS,eAAL,CAAqBrU,IAArB,CAA0B,KAAKoU,OAA/B;;EAGA,SAAKE,MAAL,GAAc,IAAI7U,QAAQ,CAACmC,UAAb,EAAd;;EAEA,SAAK2S,wBAAL,GAAgC,KAAhC;;EAEA,SAAKC,gBAAL,GAAwB,IAAI/U,QAAQ,CAACU,OAAb,EAAxB;;EAEA,SAAKsU,eAAL,GAAuB,IAAIhV,QAAQ,CAACU,OAAb,EAAvB;;EAGA,SAAKuU,aAAL,GAAqB,IAAIjV,QAAQ,CAACmC,UAAb,EAArB;EACD;;;;EAEM,6BAAA,GAAP,UAA2BkS,MAA3B,EAAmCnD,UAAnC;EACE,SAAKuD,uBAAL,CAA6BnU,GAA7B,CAAiC+T,MAAjC,EAAyCnD,UAAzC;EACD,GAFM;;EAeA,wBAAA,GAAP;EACE,WAAO,KAAKyD,OAAZ;EACD,GAFM;;EAIA,cAAA,GAAP;EACE,QAAI,CAAC,KAAKG,wBAAV,EAAoC;EAClC,WAAKD,MAAL,GAAc,KAAKK,kBAAL,CAAwB,KAAKT,uBAAL,CAA6BP,MAArD,CAAd;EACA,WAAKU,eAAL,CAAqBrU,IAArB,CAA0B,KAAKsU,MAA/B;EACA,WAAKC,wBAAL,GAAgC,IAAhC;EACA;EACD;;EAED,QAAMvD,MAAM,GAAG,KAAK+C,sBAAL,CAA4BpD,UAA5B,GACX,KAAKqD,uBAAL,CAA6BrD,UADjC;;EAIA,QAAMiE,UAAU,GAAG,KAAKC,sBAAL,CAA4B,KAAKd,sBAAL,CAA4BJ,MAAxD,EAAgE3C,MAAhE,CAAnB;EACA,SAAK0D,aAAL,CAAmB7R,QAAnB,CAA4B+R,UAA5B;;EAGA,SAAKR,OAAL,CAAapU,IAAb,CAAkB,KAAKqU,eAAvB;EACA,SAAKD,OAAL,CAAavR,QAAb,CAAsB+R,UAAtB;EAGA;;EACA,QAAME,UAAU,GAAG,IAAIrV,QAAQ,CAACmC,UAAb,EAAnB;EACAkT,IAAAA,UAAU,CAAC9U,IAAX,CAAgB,KAAKoU,OAArB;EACAU,IAAAA,UAAU,CAACvR,OAAX;EAEA,SAAKiR,gBAAL,CAAsBzU,GAAtB,CAA0B,CAA1B,EAA6B,CAA7B,EAAgC,CAAC,CAAjC;EACA,SAAKyU,gBAAL,CAAsB/T,eAAtB,CAAsCqU,UAAtC;EACA,SAAKN,gBAAL,CAAsBnU,SAAtB;EAEA,SAAKoU,eAAL,CAAqBzU,IAArB,CAA0B,KAAKkU,uBAAL,CAA6BP,MAAvD;EACA,SAAKc,eAAL,CAAqBpU,SAArB;EAGA;;EACA,QAAMkQ,MAAM,GAAG,IAAI9Q,QAAQ,CAACmC,UAAb,EAAf;EACA2O,IAAAA,MAAM,CAACtM,kBAAP,CAA0B,KAAKuQ,gBAA/B,EAAiD,KAAKC,eAAtD;EACAlE,IAAAA,MAAM,CAAChN,OAAP;;EAEA,QAAIe,IAAI,CAAC8F,OAAL,EAAJ,EAAoB;EAClByG,MAAAA,OAAO,CAACC,GAAR,CAAY,0DAAZ,EACErR,QAAQ,CAACE,QAAT,GAAoB2E,IAAI,CAACyQ,kBAAL,CAAwBxE,MAAxB,CADtB,EAEG,KAAKiE,gBAAL,CAAsB/Z,CAAvB,CAA0BsW,OAA1B,CAAkC,CAAlC,CAFF,EAGG,KAAKyD,gBAAL,CAAsB9Z,CAAvB,CAA0BqW,OAA1B,CAAkC,CAAlC,CAHF,EAIG,KAAKyD,gBAAL,CAAsBpU,CAAvB,CAA0B2Q,OAA1B,CAAkC,CAAlC,CAJF,EAKG,KAAK0D,eAAL,CAAqBha,CAAtB,CAAyBsW,OAAzB,CAAiC,CAAjC,CALF,EAMG,KAAK0D,eAAL,CAAqB/Z,CAAtB,CAAyBqW,OAAzB,CAAiC,CAAjC,CANF,EAOG,KAAK0D,eAAL,CAAqBrU,CAAtB,CAAyB2Q,OAAzB,CAAiC,CAAjC,CAPF;EAQD;EAGD;;;EACA,QAAMiE,OAAO,GAAG,IAAIvV,QAAQ,CAACmC,UAAb,EAAhB;EACAoT,IAAAA,OAAO,CAAChV,IAAR,CAAa,KAAKoU,OAAlB;EACAY,IAAAA,OAAO,CAACnS,QAAR,CAAiB0N,MAAjB;;EAGA,SAAK6D,OAAL,CAAa3Q,KAAb,CAAmBuR,OAAnB,EAA4B,IAAI,KAAKnB,OAArC;EAEA,SAAKQ,eAAL,CAAqBrU,IAArB,CAA0B,KAAKoU,OAA/B;EACD,GA3DM;;EA6DC,4BAAA,GAAR,UAA2Ba,KAA3B;EACE,QAAMC,SAAS,GAAG,IAAIzV,QAAQ,CAACU,OAAb,EAAlB;EACA+U,IAAAA,SAAS,CAAClV,IAAV,CAAeiV,KAAf;EACAC,IAAAA,SAAS,CAAC7U,SAAV;EACA,QAAM/E,IAAI,GAAG,IAAImE,QAAQ,CAACmC,UAAb,EAAb;EACAtG,IAAAA,IAAI,CAAC2I,kBAAL,CAAwB,IAAIxE,QAAQ,CAACU,OAAb,CAAqB,CAArB,EAAwB,CAAxB,EAA2B,CAAC,CAA5B,CAAxB,EAAwD+U,SAAxD;EACA5Z,IAAAA,IAAI,CAACiI,OAAL;EACA,WAAOjI,IAAP;EACD,GARO;;EAUA,gCAAA,GAAR,UAA+BoV,IAA/B,EAAqCyE,EAArC;EACE;EACA,QAAM7Z,IAAI,GAAG,IAAImE,QAAQ,CAACmC,UAAb,EAAb;EACA,QAAMa,IAAI,GAAG,IAAIhD,QAAQ,CAACU,OAAb,EAAb;EACAsC,IAAAA,IAAI,CAACzC,IAAL,CAAU0Q,IAAV;EACAjO,IAAAA,IAAI,CAACpC,SAAL;EACA/E,IAAAA,IAAI,CAACkH,gBAAL,CAAsBC,IAAtB,EAA4BiO,IAAI,CAAC9a,MAAL,KAAgBuf,EAA5C;EACA,WAAO7Z,IAAP;EACD,GARO;;EASV,4BAAA;EAAC,GA9ID;;EC/BA8Z,mBAAmB,CAACvV,SAApB,CAA8BoU,IAA9B,GAAqC;EACnC,MAAI,CAAC,KAAKM,wBAAV,EAAoC;EAClC,SAAKD,MAAL,GAAc,KAAKK,kBAAL,CAAwB,KAAKT,uBAAL,CAA6BP,MAArD,CAAd;EACA,SAAKU,eAAL,CAAqBrU,IAArB,CAA0B,KAAKsU,MAA/B;EACA,SAAKC,wBAAL,GAAgC,IAAhC;EACA;EACD;;EAED,MAAMvD,MAAM,GAAG,KAAK+C,sBAAL,CAA4BpD,UAA5B,GACf,KAAKqD,uBAAL,CAA6BrD,UAD7B;;EAIA,MAAMiE,UAAU,GAAG,KAAKC,sBAAL,CAA4B,KAAKd,sBAAL,CAA4BJ,MAAxD,EAAgE3C,MAAhE,CAAnB;EAEA,OAAK0D,aAAL,CAAmB7R,QAAnB,CAA4B+R,UAA5B;;EAGA,OAAKR,OAAL,CAAapU,IAAb,CAAkB,KAAKqU,eAAvB;EACA,OAAKD,OAAL,CAAavR,QAAb,CAAsB+R,UAAtB;EAGA;;EACA,MAAME,UAAU,GAAG,IAAIrV,QAAQ,CAACmC,UAAb,EAAnB;EAEAkT,EAAAA,UAAU,CAAC9U,IAAX,CAAgB,KAAKoU,OAArB;EACAU,EAAAA,UAAU,CAACvR,OAAX;EAEA,OAAKiR,gBAAL,CAAsBzU,GAAtB,CAA0B,CAA1B,EAA6B,CAA7B,EAAgC,CAAC,CAAjC;EACA,OAAKyU,gBAAL,CAAsB/T,eAAtB,CAAsCqU,UAAtC;EACA,OAAKN,gBAAL,CAAsBnU,SAAtB;EAEA,OAAKoU,eAAL,CAAqBzU,IAArB,CAA0B,KAAKkU,uBAAL,CAA6BP,MAAvD;EACA,OAAKc,eAAL,CAAqBpU,SAArB;EAGA;;EACA,MAAMkQ,MAAM,GAAG,IAAI9Q,QAAQ,CAACmC,UAAb,EAAf;EAEA2O,EAAAA,MAAM,CAACtM,kBAAP,CAA0B,KAAKuQ,gBAA/B,EAAiD,KAAKC,eAAtD;EACAlE,EAAAA,MAAM,CAAChN,OAAP;EAGA;;EACA,MAAMyR,OAAO,GAAG,IAAIvV,QAAQ,CAACmC,UAAb,EAAhB;EAEAoT,EAAAA,OAAO,CAAChV,IAAR,CAAa,KAAKoU,OAAlB;EACAY,EAAAA,OAAO,CAACnS,QAAR,CAAiB0N,MAAjB;;EAGA,OAAK6D,OAAL,CAAa3Q,KAAb,CAAmBuR,OAAnB,EAA4B,IAAI,KAAKnB,OAArC;EAEA,OAAKQ,eAAL,CAAqBrU,IAArB,CAA0B,KAAKoU,OAA/B;;EAEA,MAAI,CAAC,KAAKiB,6BAAV,EAAyC;EACvC,SAAKA,6BAAL,GAAqC,IAArC;EACD;EACF,CAxDD;;EA0DAD,mBAAmB,CAACvV,SAApB,CAA8ByV,cAA9B,GAA+C;EAC7C,MAAI,KAAKD,6BAAT,EAAwC;EACtC,WAAO,KAAKjB,OAAZ;EACD,GAFD,MAEO;EACL,WAAO,IAAP;EACD;EACF,CAND;;EChDA,IAAMmB,QAAQ,GAAG,IAAjB;EACA,IAAMC,iBAAiB,GAAG,KAA1B;;EAEA;;;EAA8CrE,EAAAA,mCAAA;;EA2B5C,2BAAA;EAAA,gBACEC,WAAA,KAAA,SADF;;EAGEC,IAAAA,KAAI,CAACoE,YAAL,GAAoB,IAAIC,YAAJ,EAApB;EAEArE,IAAAA,KAAI,CAACsE,aAAL,GAAqB,IAAIlW,QAAQ,CAACU,OAAb,EAArB;EACAkR,IAAAA,KAAI,CAACuE,SAAL,GAAiB,IAAInW,QAAQ,CAACU,OAAb,EAAjB;EAEAkR,IAAAA,KAAI,CAACwE,qBAAL,GAA6BxE,KAAI,CAACwE,qBAAL,CAA2BtE,IAA3B,CAAgCF,KAAhC,CAA7B;EACAA,IAAAA,KAAI,CAACyE,0BAAL,GAAkCzE,KAAI,CAACyE,0BAAL,CAAgCvE,IAAhC,CAAqCF,KAArC,CAAlC;EAEAA,IAAAA,KAAI,CAAC0E,MAAL,GAAc,IAAIX,mBAAJ,CAAwBG,QAAxB,CAAd;EACAlE,IAAAA,KAAI,CAAC2E,aAAL,GAAqB,IAAIC,aAAJ,CAAkBT,iBAAlB,CAArB;EAEAnE,IAAAA,KAAI,CAAC6E,cAAL,GAAsB,IAAIzW,QAAQ,CAACmC,UAAb,EAAtB;EAEAyP,IAAAA,KAAI,CAACjM,gBAAL,GAAwBd,IAAI,CAACc,gBAAL,EAAxB;;EAEAiM,IAAAA,KAAI,CAACtM,KAAL,GAAa/M,MAAM,IAAIC,oBAAvB;;EAGAoZ,IAAAA,KAAI,CAAC8E,oBAAL,GAA4BhY,cAAc,IAAI,EAA9C;EAEAkT,IAAAA,KAAI,CAACY,UAAL,GAAkB,KAAlB;;EAGA,QAAIZ,KAAI,CAACtM,KAAT,EAAgB;EACdsM,MAAAA,KAAI,CAAC6E,cAAL,CAAoB1T,gBAApB,CAAqC,IAAI/C,QAAQ,CAACU,OAAb,CAAqB,CAArB,EAAwB,CAAxB,EAA2B,CAA3B,CAArC,EAAoEhJ,IAAI,CAAC6C,EAAL,GAAU,CAA9E;EACD,KAFD,MAEO;EACLqX,MAAAA,KAAI,CAAC6E,cAAL,CAAoB1T,gBAApB,CAAqC,IAAI/C,QAAQ,CAACU,OAAb,CAAqB,CAArB,EAAwB,CAAxB,EAA2B,CAA3B,CAArC,EAAoE,CAAChJ,IAAI,CAAC6C,EAAN,GAAW,CAA/E;EACD;;EAEDqX,IAAAA,KAAI,CAAC+E,qBAAL,GAA6B,IAAI3W,QAAQ,CAACmC,UAAb,EAA7B;EACAyP,IAAAA,KAAI,CAACgF,cAAL,GAAsB,IAAI5W,QAAQ,CAACmC,UAAb,EAAtB;EACAyP,IAAAA,KAAI,CAACiF,mBAAL,GAA2B,IAAI7W,QAAQ,CAACmC,UAAb,EAA3B;;EACAyP,IAAAA,KAAI,CAACiF,mBAAL,CAAyB9T,gBAAzB,CAA0C,IAAI/C,QAAQ,CAACU,OAAb,CAAqB,CAArB,EAAwB,CAAxB,EAA2B,CAA3B,CAA1C,EACE,CAACjJ,GAAM,CAACsO,WAAR,GAAsBrO,IAAI,CAAC6C,EAA3B,GAAgC,GADlC;;EAGAqX,IAAAA,KAAI,CAACkF,mBAAL;;;EAEA,QAAIjS,IAAI,CAACgB,eAAL,EAAJ,EAA4B;EAC1B+L,MAAAA,KAAI,CAAC6E,cAAL,CAAoBrT,QAApB,CAA6BwO,KAAI,CAAC+E,qBAAlC;EACD;;;EAGD/E,IAAAA,KAAI,CAACmF,MAAL,GAAc,IAAI/W,QAAQ,CAACmC,UAAb,EAAd;;EAEAyP,IAAAA,KAAI,CAACoE,YAAL,CAAkBgB,EAAlB,CAAqB,cAArB,EAAqCpF,KAAI,CAACwE,qBAA1C;;EACAxE,IAAAA,KAAI,CAACa,MAAL;;;EACD;;;;EAEM,gBAAA,GAAP;EACE,QAAI,KAAKwE,SAAL,EAAJ,EAAsB;EACpB;EACD;;EACD,SAAKjB,YAAL,CAAmBvD,MAAnB;EACA,SAAKD,UAAL,GAAkB,IAAlB;EACA/a,IAAAA,GAAM,CAACib,gBAAP,CAAwB,mBAAxB,EAA6C,KAAK2D,0BAAlD;EACD,GAPM;;EASA,iBAAA,GAAP;EACE,QAAI,CAAC,KAAKY,SAAL,EAAL,EAAuB;EACrB;EACD;;EACD,SAAKjB,YAAL,CAAmBkB,OAAnB;EACA,SAAK1E,UAAL,GAAkB,KAAlB;EACA/a,IAAAA,GAAM,CAACkb,mBAAP,CAA2B,mBAA3B,EAAgD,KAAK0D,0BAArD;EACD,GAPM;;EASA,mBAAA,GAAP;EACE,WAAO,KAAK7D,UAAZ;EACD,GAFM;;EAIA,iBAAA,GAAP;EACE,SAAK0E,OAAL;EACA,SAAKlB,YAAL,GAAoB,IAApB;EACD,GAHM;;EAKA,wBAAA,GAAP;EAAA,oBAAA;;EACE,QAAIjQ,WAAJ;;EAGA,QAAI,KAAKiQ,YAAL,CAAmB/D,qBAAnB,IAA4C,KAAKkF,mBAArD,EAA0E;EACxE,WAAKC,qBAAL,GAA6B,KAAKA,qBAAL,IAA+B;EAC1D,YAAMnc,CAAC,GAAG,IAAI+E,QAAQ,CAACmC,UAAb,GACPY,gBADO,CACU,IAAI/C,QAAQ,CAACU,OAAb,CAAqB,CAArB,EAAwB,CAAxB,EAA2B,CAA3B,CADV,EACyC,CAACkR,KAAI,CAACyF,MAD/C,CAAV;EAGA,eAAOpc,CAAP;EACD,OAL0D,EAA3D;;EAOA8K,MAAAA,WAAW,GAAG,KAAKoR,mBAAnB;EACA,UAAMhO,GAAG,GAAG,IAAInJ,QAAQ,CAACmC,UAAb,EAAZ;EAEAgH,MAAAA,GAAG,CAAC5I,IAAJ,CAASwF,WAAT;EACAoD,MAAAA,GAAG,CAAC/F,QAAJ,CAAa,KAAKqT,cAAlB;EACAtN,MAAAA,GAAG,CAAC/F,QAAJ,CAAa,KAAK2T,MAAlB;EACA5N,MAAAA,GAAG,CAAC/F,QAAJ,CAAa,KAAKwT,cAAlB;EACAzN,MAAAA,GAAG,CAAC9F,mBAAJ,CAAwB,KAAK+T,qBAA7B,EAAoDjO,GAApD,EAfwE;;EAkBxE,UAAMmO,OAAO,GAAGzb,YAAA,CACdsN,GAAG,CAACnO,CADU,EAEdmO,GAAG,CAAClO,CAFU,EAGdkO,GAAG,CAACxI,CAHU,EAIdwI,GAAG,CAAC7H,CAJU,CAAhB;EAOA,aAAOzF,WAAA,CAAeyb,OAAf,EAAwBA,OAAxB,CAAP;EACD,KA1BD,MA0BO;EACL;EACA;EACAvR,MAAAA,WAAW,GAAG,KAAKuQ,MAAL,CAAYT,cAAZ,EAAd;;EAEA,UAAI,CAAC9P,WAAL,EAAkB;EAChB,eAAO,IAAP;EACD;;EAED,UAAMoD,GAAG,GAAG,KAAKoO,yBAAL,CAA+BxR,WAA/B,CAAZ,CATK;;;EAYL,UAAMuR,OAAO,GAAGzb,YAAA,CACdsN,GAAG,CAACnO,CADU,EAEdmO,GAAG,CAAClO,CAFU,EAGdkO,GAAG,CAACxI,CAHU,EAIdwI,GAAG,CAAC7H,CAJU,CAAhB;EAOA,aAAOzF,WAAA,CAAeyb,OAAf,EAAwBA,OAAxB,CAAP;EACD;EACF,GAnDM;;EAqDC,wBAAA,GAAR;EACE,QAAMvR,WAAW,GAAG,KAAK8P,cAAL,EAApB;;EAGA,QAAI,CAAC9P,WAAL,EAAkB;EAChB;EACD;;EAED,QAAI,CAAC,KAAKyR,gBAAV,EAA4B;EAC1B,WAAKA,gBAAL,GAAwBzR,WAAxB;EACA;EACD;;EAED,QAAIlK,QAAA,CAAY,KAAK2b,gBAAjB,EAAmCzR,WAAnC,CAAJ,EAAqD;EACnD;EACD;;EAED,SAAKiN,OAAL,CAAa,IAAIC,gBAAJ,CAAmB,QAAnB,EAA6B;EAAE/Y,MAAAA,UAAU,EAAE6L;EAAd,KAA7B,CAAb;EACD,GAlBO;;EAoBA,mCAAA,GAAR,UAAkCA,WAAlC;EACE;EACA,SAAK0R,UAAL,GACE,KAAKlB,aAAL,CAAmBmB,aAAnB,CAAiC3R,WAAjC,EAA8C,KAAKoQ,SAAnD,EAA8D,KAAKtF,kBAAnE,CADF;;EAIA,QAAM1H,GAAG,GAAG,IAAInJ,QAAQ,CAACmC,UAAb,EAAZ;EAEAgH,IAAAA,GAAG,CAAC5I,IAAJ,CAAS,KAAKkW,cAAd;EACAtN,IAAAA,GAAG,CAAC/F,QAAJ,CAAa,KAAK2T,MAAlB;EACA5N,IAAAA,GAAG,CAAC/F,QAAJ,CAAa,KAAKqU,UAAlB;EACAtO,IAAAA,GAAG,CAAC/F,QAAJ,CAAa,KAAKwT,cAAlB;EAEA,WAAOzN,GAAP;EACD,GAdO;;EAgBA,+BAAA,GAAR,UAA8BwO,EAA9B;UAAgCzE,UAAU;EACxC,QAAMC,iBAAiB,GAAGD,UAAU,CAACC,iBAArC;EACA,QAAM6C,YAAY,GAAG9C,UAArB;EACA,QAAM0E,UAAU,GAAG5B,YAAY,CAACtC,4BAAhC;EACA,QAAMmE,OAAO,GAAG7B,YAAY,CAAChC,oBAAb,IAAqCgC,YAAY,CAACxC,YAAlE;EACA,QAAItC,UAAU,GAAG8E,YAAY,CAAClC,SAAb,GAAyB,IAA1C;;EAEA,QAAIX,iBAAJ,EAAuB;EACrB,UAAI,CAAC,KAAKkE,MAAV,EAAkB;EAChB,aAAKA,MAAL,GAAclE,iBAAiB,CAACN,KAAhC;EACD;;EACD,WAAKsE,mBAAL,GAA2B,KAAKA,mBAAL,IAA4B,IAAInX,QAAQ,CAACmC,UAAb,EAAvD;;EACA,WAAKgV,mBAAL,CAAyBrU,eAAzB,CACEqQ,iBAAiB,CAACL,IADpB,EAEEK,iBAAiB,CAACN,KAFpB,EAGEM,iBAAiB,CAACJ,KAHpB;;EAMA,WAAK+E,cAAL;EACD,KAZD,MAYO;EACL;EACA,UAAI,KAAKnS,gBAAT,EAA2B;EACzBuL,QAAAA,UAAU,IAAI,IAAd;EACD;;EAED,WAAKgF,aAAL,CAAmB5V,GAAnB,CAAuB,CAACsX,UAAU,CAAC5c,CAAnC,EAAsC,CAAC4c,UAAU,CAAC3c,CAAlD,EAAqD,CAAC2c,UAAU,CAACjX,CAAjE;EACA,WAAKwV,SAAL,CAAe7V,GAAf,CAAmBuX,OAAO,CAAChF,KAA3B,EAAkCgF,OAAO,CAAC/E,IAA1C,EAAgD+E,OAAO,CAAC9E,KAAxD,EAPK;EAUL;;EACA,UAAI,KAAKzN,KAAL,IAAc,KAAKK,gBAAnB,IAAuC,KAAK+Q,oBAAhD,EAAsE;EACpE,aAAKP,SAAL,CAAepV,cAAf,CAA8BrJ,IAAI,CAAC6C,EAAL,GAAU,GAAxC;EACD;;EAED,WAAK+b,MAAL,CAAYyB,mBAAZ,CAAgC,KAAK7B,aAArC,EAAoDhF,UAApD;EACA,WAAKoF,MAAL,CAAY0B,kBAAZ,CAA+B,KAAK7B,SAApC,EAA+CjF,UAA/C;;EAEA,WAAK4G,cAAL;;EAEA,WAAKjH,kBAAL,GAA0BK,UAA1B;EACD;EACF,GAzCO;;EA2CA,oCAAA,GAAR;EACE,SAAK4F,mBAAL;EACD,GAFO;;EAIA,6BAAA,GAAR;EACE,SAAKF,cAAL,CAAoBtW,GAApB,CAAwB,CAAxB,EAA2B,CAA3B,EAA8B,CAA9B,EAAiC,CAAjC;EAEA,QAAMyF,WAAW,GAAGtO,GAAM,CAACsO,WAA3B;;EAEA,YAAQA,WAAR;EACE,WAAK,CAAL;EACE;;EACF,WAAK,EAAL;EACA,WAAK,CAAC,EAAN;EACA,WAAK,GAAL;EACE,aAAK6Q,cAAL,CACG7T,gBADH,CACoB,IAAI/C,QAAQ,CAACU,OAAb,CAAqB,CAArB,EAAwB,CAAxB,EAA2B,CAA3B,CADpB,EACmDqF,WAAW,GAAG,CAAC,GAAf,GAAqBrO,IAAI,CAAC6C,EAD7E;EAEA;EARJ;;EAYA,SAAKoc,qBAAL,CAA2BpW,IAA3B,CAAgC,KAAKqW,cAArC;EACA,SAAKD,qBAAL,CAA2B7S,OAA3B;EACD,GAnBO;;EAoBV,yBAAA;EArQA,EAA8CmQ,UAA9C;;ECPA,IAAMgE,WAAW,GAAG,UAACC,IAAD,EAAaxc,IAAb;EAClB,MAAMyc,aAAa,GAAG3d,IAAI,CAACgB,gBAAL,CAAsB0c,IAAtB,EAA4Bxc,IAA5B,EAAkCR,eAAe,CAACG,gBAAlD,CAAtB;EACA,MAAM+c,cAAc,GAAG5d,IAAI,CAACgB,gBAAL,CAAsB0c,IAAtB,EAA4Bxc,IAA5B,EAAkCR,eAAe,CAACE,iBAAlD,IACrB1D,IAAI,CAACiL,GAAL,CAASnI,IAAI,CAACG,oBAAL,CAA0Be,IAA1B,CAAT,CADF;EAGA,SAAO0c,cAAc,GAAGD,aAAxB;EACD,CAND;;EAQA,IAAME,aAAa,GAAG,UAACH,IAAD,EAAaxc,IAAb;EACpB,MAAM4c,UAAU,GAAG9d,IAAI,CAACgB,gBAAL,CAAsB0c,IAAtB,EAA4Bxc,IAA5B,EAAkCR,eAAe,CAACC,WAAlD,CAAnB;EAEA,SAAOmd,UAAP;EACD,CAJD;;;EAOA;;;EAA6C5G,EAAAA,kCAAA;;EAU3C,0BAAA,CAAmB6G,EAAnB,EAAoCC,OAApC;EAAoC,0BAAA,EAAA;EAAAA,MAAAA,YAAA;;;EAApC,gBACE7G,WAAA,KAAA,SADF;;EAEEC,IAAAA,KAAI,CAACnL,OAAL,GAAe8R,EAAf;EAEA3G,IAAAA,KAAI,CAAC6G,eAAL,GAAuB,IAAvB;EACA7G,IAAAA,KAAI,CAAC8G,WAAL,GAAmB,IAAnB;EAEA9G,IAAAA,KAAI,CAAC+G,gBAAL,GAAwB,IAAxB;EAEA/G,IAAAA,KAAI,CAAC4G,OAAL,YACK;EACDI,MAAAA,KAAK,EAAE,CADN;EAEDC,MAAAA,SAAS,EAAE;EAFV,OAGGL,QAJR;EAOA5G,IAAAA,KAAI,CAACkH,aAAL,GAAqBlH,KAAI,CAACkH,aAAL,CAAmBhH,IAAnB,CAAwBF,KAAxB,CAArB;;EACD;;;;EAEM,iBAAA,GAAP,UAAemH,IAAf;EACE,SAAKA,IAAL,GAAYA,IAAZ;EACD,GAFM;;EAIA,iBAAA,GAAP,UAAeC,QAAf;EACE,QAAI,KAAKA,QAAT,EAAmB;EACjB,aAAO,IAAP;EACD;;EACD,SAAKA,QAAL,GAAgBA,QAAhB;EACA,SAAKL,gBAAL,GAAwB,IAAIM,gBAAJ,EAAxB;EACA,SAAKN,gBAAL,CAAsBlG,MAAtB;;EACA,SAAKyG,YAAL;;EACA,WAAO,IAAP;EACD,GATM;;EAWA,oBAAA,GAAP;EACE,QAAI,CAAC,KAAKF,QAAV,EAAoB;EAClB,aAAO,IAAP;EACD;;EAED,SAAKG,aAAL;;EACA,SAAKR,gBAAL,CAAuBzB,OAAvB;EACA,SAAKyB,gBAAL,CAAuBS,OAAvB;EACA,SAAKT,gBAAL,GAAwB,IAAxB;EACA,SAAKK,QAAL,GAAgB,IAAhB;EACA,WAAO,IAAP;EACD,GAXM;;EAaA,iBAAA,GAAP;EACE,SAAKK,UAAL;EACC,SAAK5S,OAAL,GAAuB,IAAvB;EACA,SAAK+R,OAAL,GAAuB,IAAvB;EACA,SAAKO,IAAL,GAAoB,IAApB;EACD,SAAKN,eAAL,GAAuB,IAAvB;EACA,SAAKC,WAAL,GAAmB,IAAnB;EACD,GAPM;;EASC,uBAAA,GAAR,UAAsBY,KAAtB;EACE,QAAI,CAAC,KAAKb,eAAV,EAA2B;EACzB,WAAKA,eAAL,GAAuB5c,OAAA,CAAWyd,KAAK,CAACpf,UAAjB,CAAvB;EACA,WAAKwe,WAAL,GAAmB7c,OAAA,CAAWyd,KAAK,CAACpf,UAAjB,CAAnB;EACA;EACD;;EAED2B,IAAAA,MAAA,CAAU,KAAK4c,eAAf,EAAgC,KAAKC,WAArC;EACA7c,IAAAA,MAAA,CAAU,KAAK6c,WAAf,EAA6BY,KAAK,CAACpf,UAAnC;EAEA,SAAK8e,QAAL,CAAeO,MAAf,CAAsB,IAAtB,EAA4BD,KAA5B,EAAmCtb,QAAM,CAAC,KAAK+a,IAAN,EAAY,CACnDd,WAAW,CAAC,KAAKQ,eAAN,EAAuB,KAAKC,WAA5B,CADwC,EAEnDL,aAAa,CAAC,KAAKI,eAAN,EAAuB,KAAKC,WAA5B,CAFsC,CAAZ,CAAzC;EAID,GAdO;;EAgBA,sBAAA,GAAR;EACE,SAAKC,gBAAL,CAAuB3B,EAAvB,CAA0B,QAA1B,EAAoC,KAAK8B,aAAzC;EACD,GAFO;;EAIA,uBAAA,GAAR;EACE,SAAKH,gBAAL,CAAuBa,GAAvB,CAA2B,QAA3B,EAAqC,KAAKV,aAA1C;EACD,GAFO;;EAGV,wBAAA;EAzFA,EAA6C7E,UAA7C;;ECnBA,IAAIwF,uBAAuB,GAA+B,IAA1D;EACA,IAAIC,QAAQ,GAAG,CAAf;;EAEA;;;EAIE,8BAAA;EACEA,IAAAA,QAAQ;;EAER,QAAID,uBAAJ,EAA6B;EAC3B,aAAOA,uBAAP;EACD;EACD;;;EACAA,IAAAA,uBAAuB,GAAG,IAA1B;EACA;;EACA,SAAK1H,oBAAL,GAA4B,KAAKA,oBAAL,CAA0BD,IAA1B,CAA+B,IAA/B,CAA5B;EACA,SAAK6H,oBAAL,GAA4B,KAAKA,oBAAL,CAA0B7H,IAA1B,CAA+B,IAA/B,CAA5B;EAEA,SAAK8H,MAAL,GAAc,CAAd;EAEA,SAAKC,uBAAL,GAA+B,CAA/B;EACApiB,IAAAA,GAAM,CAACib,gBAAP,CAAwB,mBAAxB,EAA6C,KAAKX,oBAAlD;EACAta,IAAAA,GAAM,CAACib,gBAAP,CAAwB,mBAAxB,EAA6C,KAAKiH,oBAAlD;EACD;;;;EAEM,mBAAA,GAAP;EACE;EACA;EACA,WAAO,KAAKC,MAAL,GAAcE,QAAA,CAAkB,KAAKD,uBAAvB,CAArB;EACD,GAJM;;EAMA,eAAA,GAAP;EACE,QAAI,EAAEH,QAAF,GAAa,CAAjB,EAAoB;EAClB;EACD;;EAEDjiB,IAAAA,GAAM,CAACkb,mBAAP,CAA2B,mBAA3B,EAAgD,KAAKZ,oBAArD;EACAta,IAAAA,GAAM,CAACkb,mBAAP,CAA2B,mBAA3B,EAAgD,KAAKgH,oBAArD;EAEA,SAAKC,MAAL,GAAc,CAAd;EACA,SAAKC,uBAAL,GAA+B,CAA/B;EACA;;EACAJ,IAAAA,uBAAuB,GAAG,IAA1B;EACA;;EACAC,IAAAA,QAAQ,GAAG,CAAX;EACD,GAdM;;EAgBC,8BAAA,GAAR,UAA6B9G,CAA7B;EACE,QAAIA,CAAC,CAACE,IAAF,KAAW,IAAX,IAAmBF,CAAC,CAACG,KAAF,KAAY,IAAnC,EAAyC;EACvC;EACA;EACD;;;EAGD,QAAMgH,KAAK,GAAGD,QAAA,CAAkBlH,CAAC,CAACE,IAApB,CAAd;EACA,QAAMkH,MAAM,GAAGF,QAAA,CAAkBlH,CAAC,CAACG,KAApB,CAAf;EAEA;;EACA,SAAK6G,MAAL,GAAcliB,IAAI,CAACkD,KAAL,CAAWlD,IAAI,CAAC6K,GAAL,CAASwX,KAAT,IAAkBriB,IAAI,CAACiL,GAAL,CAASqX,MAAT,CAA7B,EAA+CtiB,IAAI,CAACiL,GAAL,CAASoX,KAAT,CAA/C,CAAd;EACD,GAZO;;EAcA,8BAAA,GAAR;EACE,QAAItiB,GAAM,CAAC2O,MAAP,IAAiB3O,GAAM,CAAC2O,MAAP,CAAcL,WAA/B,IAA8CtO,GAAM,CAAC2O,MAAP,CAAcL,WAAd,CAA0B9C,KAA1B,KAAoCb,SAAtF,EAAiG;EAC/F,WAAKyX,uBAAL,GAA+BzT,MAAM,CAACL,WAAP,CAAmB9C,KAAlD;EACD,KAFD,MAEO,IAAIxL,GAAM,CAACsO,WAAP,KAAuB3D,SAA3B,EAAsC;EAC3C;EACA,WAAKyX,uBAAL,GAA+BpiB,GAAM,CAACsO,WAAP,IAAsB,CAAtB,GAC7BtO,GAAM,CAACsO,WADsB,GACR,MAAOtO,GAAM,CAACsO,WADrC;EAED;EACF,GARO;;EASV,4BAAA;EAAC,GApED;;ECFA;;;;;;;;;;EASA;;;EAA8C2L,EAAAA,mCAAA;EAK5C;;;;;;;;;EAOA,2BAAA,CAAmB6G,EAAnB,EAAoCC,OAApC;EAAoC,0BAAA,EAAA;EAAAA,MAAAA,YAAA;;;EAApC,gBACE7G,WAAA,KAAA,EAAM4G,EAAN,EAAUC,OAAV,SADF;;EAGE5G,IAAAA,KAAI,CAACqI,YAAL,GAAoB,KAApB;EACArI,IAAAA,KAAI,CAACsI,oBAAL,GAA4B,IAA5B;;EAEAtI,IAAAA,KAAI,CAACuI,cAAL,CAAoB,CAAC,EAAE3B,OAAO,IAAIA,OAAO,CAAC4B,WAArB,CAArB;;EAEAxI,IAAAA,KAAI,CAACyI,cAAL,GAAsBC,IAAI,CAACC,aAA3B;;EACD;;;;EAEM,wBAAA,GAAP,UAAsBH,WAAtB;EACE,SAAKH,YAAL,GAAoBG,WAApB;;EAEA,QAAI,KAAKF,oBAAT,EAA+B;EAC7B,WAAKA,oBAAL,CAA0BM,KAA1B;;EACA,WAAKN,oBAAL,GAA4B,IAA5B;EACD;;EAED,QAAI,KAAKD,YAAT,EAAuB;EACrB,WAAKC,oBAAL,GAA4B,IAAIO,mBAAJ,EAA5B;EACD;EACF,GAXM;;EAaA,iBAAA,GAAP,UAAezB,QAAf;EACE;EACA,SAAKqB,cAAL,GAAsB,KAAKK,UAA3B;EAGA;EACA;;EACA,QAAI,KAAKT,YAAL,IAAsB,KAAKS,UAAL,GAAkBJ,IAAI,CAACC,aAAjD,EAAiE;EAC/D,WAAKG,UAAL,GAAkBJ,IAAI,CAACK,oBAAvB;EACD;;EAED,WAAOhJ,gBAAA,CAAMiJ,OAAN,KAAA,KAAA,EAAc5B,QAAd,CAAP;EACD,GAZM;;EAcA,iBAAA,GAAP;EACE,QAAI,KAAKiB,YAAL,IAAqB,KAAKC,oBAA9B,EAAoD;EAClD,WAAKA,oBAAL,CAA0BM,KAA1B;EACD;;EAED7I,IAAAA,gBAAA,CAAMyH,OAAN,KAAA,KAAA;EACD,GANM;;EAQG,oBAAA,GAAV,UAAqByB,UAArB,EAA2CC,YAA3C;EACE,QAAI,KAAKb,YAAL,KAAsB,KAA1B,EAAiC;EAC/B,aAAOtI,gBAAA,CAAMoJ,UAAN,KAAA,KAAA,EAAiBF,UAAjB,EAA6BC,YAA7B,CAAP;EACD;;EAED,QAAM7c,MAAM,GAAG0T,gBAAA,CAAMoJ,UAAN,KAAA,KAAA,EAAiBF,UAAjB,EAA6B,CAAC,IAAD,EAAO,IAAP,CAA7B,CAAf;;EACA,QAAMG,SAAS,GAAG,CAAC,CAAD,EAAI,CAAJ,CAAlB;;EAEA,QAAMje,KAAK,GAAG,KAAKmd,oBAAL,CAA2Be,SAA3B,EAAd;;EAEA,QAAMC,QAAQ,GAAGxjB,IAAI,CAAC6K,GAAL,CAASxF,KAAT,CAAjB;EACA,QAAMoe,QAAQ,GAAGzjB,IAAI,CAACiL,GAAL,CAAS5F,KAAT,CAAjB;;EAGAie,IAAAA,SAAS,CAAC,CAAD,CAAT,GAAe/c,MAAM,CAAC,CAAD,CAAN,GAAYid,QAAZ,GAAuBjd,MAAM,CAAC,CAAD,CAAN,GAAYkd,QAAlD;EACAH,IAAAA,SAAS,CAAC,CAAD,CAAT,GAAe/c,MAAM,CAAC,CAAD,CAAN,GAAYid,QAAZ,GAAuBjd,MAAM,CAAC,CAAD,CAAN,GAAYkd,QAAlD;;EAGA,QAAI,EAAE,KAAKd,cAAL,GAAsBC,IAAI,CAACK,oBAA7B,CAAJ,EAAwD;EACtDK,MAAAA,SAAS,CAAC,CAAD,CAAT,GAAe,CAAf;EACD,KAFD,MAEO,IAAI,EAAE,KAAKX,cAAL,GAAsBC,IAAI,CAACc,kBAA7B,CAAJ,EAAsD;EAC3DJ,MAAAA,SAAS,CAAC,CAAD,CAAT,GAAe,CAAf;EACD;;EAED,WAAOA,SAAP;EACD,GAzBS;;EA0BZ,yBAAA;EApFA,EAA8CK,SAA9C;EAsFA;;;;;;EAMA;EACA;EACA;;ECxGA,IAAMC,aAAa,GAAGlhB,UAAA,CAAgB,CAAhB,EAAmB,CAAnB,EAAsB,CAAtB,CAAtB;;EAEA;;;EAA8CsX,EAAAA,mCAAA;;EAQ5C,2BAAA;EAAA,gBACEC,WAAA,KAAA,SADF;;EAGEC,IAAAA,KAAI,CAAC2J,iBAAL,GAAyB,IAAItC,gBAAJ,EAAzB;EACArH,IAAAA,KAAI,CAAC8G,WAAL,GAAmB7c,QAAA,EAAnB;;EAEA+V,IAAAA,KAAI,CAAC2J,iBAAL,CAAuB9I,MAAvB;;EACAb,IAAAA,KAAI,CAAC2J,iBAAL,CAAuBvE,EAAvB,CAA0B,QAA1B,EAAoC,UAAApE,CAAA;EAClChB,MAAAA,KAAI,CAAC8G,WAAL,GAAmB9F,CAAC,CAAC1Y,UAArB;;EAEA0X,MAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmB,QAAnB,EAA6B;EAAEuI,QAAAA,SAAS,EAAE;EAAb,OAA7B,CAAb;EACD,KAJD;;;EAKD;;;;EAEM,+BAAA,GAAP,UAA6BC,GAA7B;EACE,QAAMC,IAAI,GAAG7f,YAAA,CAAkBA,QAAA,EAAlB,EAAiCyf,aAAjC,EAAgDxB,QAAA,CAAkB,CAAC2B,GAAnB,CAAhD,CAAb;EACA,QAAME,IAAI,GAAG9f,SAAA,CAAeA,QAAA,EAAf,EAA8B,KAAK6c,WAAnC,CAAb;;EAEA,QAAM3H,IAAI,GAAGlV,QAAA,CAAcA,QAAA,EAAd,EAA6B8f,IAA7B,EAAmCD,IAAnC,CAAb;EAEA,WAAO3K,IAAP;EACD,GAPM;;EASA,iBAAA,GAAP;EACE;EACA,SAAKyI,GAAL;;EAEA,QAAI,KAAK+B,iBAAT,EAA4B;EAC1B,WAAKA,iBAAL,CAAuB/B,GAAvB;;EACA,WAAK+B,iBAAL,CAAuBnC,OAAvB;;EACA,WAAKmC,iBAAL,GAAyB,IAAzB;EACD;EACF,GATM;;EAUT,yBAAA;EAzCA,EAA8CtH,UAA9C;;ECwBA,IAAM2H,iBAAiB,GAAG,CAAC,CAACnc,cAAF,EAAkBA,cAAlB,CAA1B;EACA,IAAMoc,mBAAmB,GAAG,CAAC,CAACnc,gBAAF,EAAoBA,gBAApB,CAA5B;EACA,IAAMoc,oBAAoB,GAAG,CAAC,CAACnc,yBAAF,EAA6BA,yBAA7B,CAA7B;EAkCA;;;;;;;;EAOA;;;EAA8B+R,EAAAA,kCAAA;EAyB5B;;;;;;;;;;;;;;;;;;EAgBA,0BAAA,CAAmB8G,OAAnB;EAAA,gBACE7G,WAAA,KAAA,SADF;;EAEEC,IAAAA,KAAI,CAAC4G,OAAL,GAAe,EAAf;;EAEA,QAAMuD,GAAG,YACJ;EACDtV,MAAAA,OAAO,EAAE,IADR;EAEDgV,MAAAA,GAAG,EAAE,CAFJ;EAGDO,MAAAA,KAAK,EAAE,CAHN;EAIDzQ,MAAAA,GAAG,EAAE,EAJJ;EAKD0Q,MAAAA,aAAa,EAAE,KALd;EAMDC,MAAAA,OAAO,EAAE,IANR;EAODC,MAAAA,WAAW,EAAE,IAPZ;EAQDC,MAAAA,QAAQ,EAAExc,SAAS,CAACE,QARnB;EASDuc,MAAAA,cAAc,EAAEld,mBATf;EAUDmd,MAAAA,QAAQ,EAAEV,iBAVT;EAWDW,MAAAA,UAAU,EAAEV,mBAXX;EAYDW,MAAAA,QAAQ,EAAE,CAAC,EAAD,EAAK,GAAL,CAZT;EAaDC,MAAAA,WAAW,EAAE;EAAE;;EAbd,OAcGjE,QAfR;;EAkBA5G,IAAAA,KAAI,CAAC8K,QAAL,GAAgBX,GAAG,CAACtV,OAApB;EACAmL,IAAAA,KAAI,CAAC+K,WAAL,GAAmBZ,GAAG,CAACxQ,GAAvB;EACAqG,IAAAA,KAAI,CAACgL,QAAL,GAAgB,KAAhB;EACAhL,IAAAA,KAAI,CAACiL,YAAL,GAAoB,KAApB;EACAjL,IAAAA,KAAI,CAACkL,iBAAL,GAAyB,IAAzB;;EAEAlL,IAAAA,KAAI,CAACmL,SAAL,CAAehB,GAAf;;EACAnK,IAAAA,KAAI,CAACoL,MAAL,CAAYjB,GAAZ;;;EACD;EAED;;;;;;;;;;;EAOO,wBAAA,GAAP,UAAsBkB,KAAtB;EAAsB,wBAAA,EAAA;EAAAA,MAAAA,UAAA;;;EAGpB,QAAM1R,GAAG,GAAG,KAAK2R,KAAL,CAAWC,GAAX,GAAiB5R,GAA7B;;EACA,QAAM6R,UAAU,GAAGH,KAAK,CAAC3W,MAAN,IAAgB7H,QAAQ,CAAChH,MAAM,CAACiB,gBAAP,CAAwB,KAAKgkB,QAA7B,EAAwCpW,MAAzC,EAAiD,EAAjD,CAA3C;EACA,QAAMsS,KAAK,GAAGtZ,aAAa,CAAC,CAAD,CAAb,GAAmBiM,GAAnB,GAAyB,KAAKoR,WAA9B,GAA4Cnd,SAA5C,GAAwD4d,UAAtE;EAEA,SAAKC,aAAL,CAAmB7E,OAAnB,CAA2BI,KAA3B,GAAmC,CAACA,KAAD,EAAQA,KAAR,CAAnC;EACA,SAAKsE,KAAL,CAAW1E,OAAX,CAAmB8E,YAAnB,GAAkCle,eAAe,GAAGmM,GAAlB,GAAwBhM,iBAA1D;EAEA,WAAO,IAAP;EACD,GAXM;EAiBP;;;;;;;;EAMO,gBAAA,GAAP,UAAsDlK,GAAtD,EAAiGkoB,QAAjG;EACE;EACA,QAAI,CAACloB,GAAL,EAAU;EACR,aAAO,KAAKmoB,WAAL,EAAP;EACD,KAFD,MAEO,IAAInoB,GAAG,IAAI,OAAOA,GAAP,KAAe,QAAtB,IAAkC,OAAOkoB,QAAP,KAAoB,WAA1D,EAAuE;EAC5E,aAAO,KAAKC,WAAL,CAAiBnoB,GAAjB,CAAP;EACD;;;EAGD,QAAIooB,UAAU,GAAoC,EAAlD;EACA,QAAIC,cAAc,GAAa,EAA/B;;EAEA,QAAI,OAAOroB,GAAP,KAAe,QAAnB,EAA6B;EAC3BqoB,MAAAA,cAAc,CAACC,IAAf,CAAoBtoB,GAApB;EACAooB,MAAAA,UAAU,CAACpoB,GAAD,CAAV,GAAkBkoB,QAAlB;EACD,KAHD,MAGO;EACL,UAAM/E,OAAO,GAAGnjB,GAAhB,CADK;;EAELqoB,MAAAA,cAAc,GAAGvoB,MAAM,CAACC,IAAP,CAAYojB,OAAZ,CAAjB;EACAiF,MAAAA,UAAU,gBAAOjF,QAAjB;EACD;;EAED,SAAKoF,WAAL,CAAiB,KAAKC,oBAAL,CAA0BJ,UAA1B,CAAjB;;EACA,SAAKK,aAAL,CAAmBJ,cAAnB;;EACA,WAAO,IAAP;EACD,GAxBM;EA0BP;;;;;;EAIO,gBAAA,GAAP;EACE,QAAI,KAAKd,QAAT,EAAmB;EACjB,aAAO,IAAP;EACD;;EAED,SAAKA,QAAL,GAAgB,IAAhB;;EAGA,SAAKkB,aAAL,CAAmB3oB,MAAM,CAACC,IAAP,CAAY,KAAKojB,OAAjB,CAAnB;;;EAGA,SAAKuF,cAAL;EAEA,WAAO,IAAP;EACD,GAdM;EAgBP;;;;;;EAIO,iBAAA,GAAP,UAAeC,kBAAf;EAAe,qCAAA,EAAA;EAAAA,MAAAA,0BAAA;;;EACb,QAAI,CAAC,KAAKpB,QAAV,EAAoB;EAClB,aAAO,IAAP;EACD;;;EAGD,QAAI,CAACoB,kBAAL,EAAyB;EACvB,WAAKC,iBAAL;EACD;;EACD,SAAKf,KAAL,CAAW7D,UAAX;;EACA,SAAKuD,QAAL,GAAgB,KAAhB;EACA,WAAO,IAAP;EACD,GAZM;EAcP;;;;;;;EAKO,gBAAA,GAAP,UAAcjF,EAAd,EAAiCuG,QAAjC;UAAezC,GAAG;UAAEO,KAAK;UAAEzQ,GAAG;;EAC5B,QAAM4S,GAAG,GAAG,KAAKjB,KAAL,CAAWC,GAAX,EAAZ;;EAEA,QAAMliB,CAAC,GAAGwgB,GAAG,KAAKrZ,SAAR,GAAoB,CAApB,GAAwBqZ,GAAG,GAAG0C,GAAG,CAAC1C,GAA5C;EACA,QAAM2C,CAAC,GAAGpC,KAAK,KAAK5Z,SAAV,GAAsB,CAAtB,GAA0B4Z,KAAK,GAAGmC,GAAG,CAACnC,KAAhD;EACA,QAAMqC,CAAC,GAAG9S,GAAG,KAAKnJ,SAAR,GAAoB,CAApB,GAAwBmJ,GAAG,GAAG4S,GAAG,CAAC5S,GAA5C;;EAGA,SAAK2R,KAAL,CAAW1E,OAAX,CAAmB8F,eAAnB,GAAqCC,QAArC;;EAEA,SAAKrB,KAAL,CAAWsB,KAAX,CAAiB;EACf/C,MAAAA,GAAG,EAAExgB,CADU;EAEf+gB,MAAAA,KAAK,EAAEoC,CAFQ;EAGf7S,MAAAA,GAAG,EAAE8S;EAHU,KAAjB,EAIGH,QAJH;EAKD,GAfM;;EAiBA,qBAAA,GAAP;EACE,QAAMO,QAAQ,GAAG,KAAKvB,KAAL,CAAWC,GAAX,EAAjB;;EAEA,WAAO;EACL1B,MAAAA,GAAG,EAAEgD,QAAQ,CAAChD,GADT;EAELO,MAAAA,KAAK,EAAEyC,QAAQ,CAACzC;EAFX,KAAP;EAID,GAPM;;EASA,gBAAA,GAAP;EACE,WAAO,KAAKkB,KAAL,CAAWC,GAAX,GAAiB5R,GAAxB;EACD,GAFM;;EAIA,uBAAA,GAAP;EACE,QAAM4S,GAAG,GAAG,KAAKjB,KAAL,CAAWC,GAAX,EAAZ;;EAEA,WAAO,KAAKL,iBAAL,CAAwB4B,qBAAxB,CAA8CP,GAAG,CAAC1C,GAAlD,CAAP;EACD,GAJM;;EAMA,oCAAA,GAAP;EACE,WAAO,KAAKjD,OAAL,CAAa4D,QAAb,KAA0Bxc,SAAS,CAACG,EAA3C;EACD,GAFM;EAIP;;;;;EAGO,iBAAA,GAAP;EACE;EACA,SAAKmd,KAAL,IAAc,KAAKA,KAAL,CAAW9D,OAAX,EAAd;EACA,SAAKiE,aAAL,IAAsB,KAAKA,aAAL,CAAmBjE,OAAnB,EAAtB;EACA,SAAKuF,eAAL,IAAwB,KAAKA,eAAL,CAAqBvF,OAArB,EAAxB;EACA,SAAKwF,oBAAL,IAA6B,KAAKA,oBAAL,CAA0BxF,OAA1B,EAA7B;EACA,SAAKyF,eAAL,IAAwB,KAAKA,eAAL,CAAqBzF,OAArB,EAAxB;EACA,SAAK0F,iBAAL,IAA0B,KAAKA,iBAAL,CAAuB1F,OAAvB,EAA1B;EACA,SAAK0D,iBAAL,IAA0B,KAAKA,iBAAL,CAAuB1D,OAAvB,EAA1B;EACA;EACD,GAVM;;EAYC,mBAAA,GAAR,UAAkB2C,GAAlB;EAAA,oBAAA;;EACE,QAAMgD,MAAM,GAAG,KAAKC,eAAL,CAAqBjD,GAAG,CAACO,QAAzB,EAAmCP,GAAG,CAACxQ,GAAvC,EAA4CwQ,GAAG,CAACU,WAAhD,CAAf;;EACA,QAAMwC,MAAM,GAAG,KAAKC,iBAAL,CAAuBnD,GAAG,CAACQ,UAA3B,EAAuCR,GAAG,CAACxQ,GAA3C,EAAgDwQ,GAAG,CAACE,aAApD,CAAf;;EACA,QAAM7B,WAAW,GAAG2B,GAAG,CAACK,QAAJ,KAAiBxc,SAAS,CAACG,EAA/C;EAEA,SAAKsd,aAAL,GAAqB,IAAI8B,gBAAJ,CAAqB,KAAKzC,QAA1B,EAAqC;EAACtC,MAAAA,WAAW;EAAZ,KAArC,CAArB;EACA,SAAKuE,eAAL,GAAuB,IAAIS,UAAJ,CAAe,KAAK1C,QAApB,EAA8B;EAAC9D,MAAAA,KAAK,EAAE,CAAC;EAAT,KAA9B,CAAvB;EACA,SAAKgG,oBAAL,GAA4B,IAA5B;EACA,SAAKC,eAAL,GAAuBjmB,aAAa,GAAG,IAAIymB,UAAJ,CAAe,KAAK3C,QAApB,EAA8B;EAAC9D,MAAAA,KAAK,EAAE,CAAC;EAAT,KAA9B,CAAH,GAAgD,IAApF;EACA,SAAKkG,iBAAL,GAAyB,IAAIQ,YAAJ,CAAiB,KAAK5C,QAAtB,EAAgC;EAAC9D,MAAAA,KAAK,EAAE,CAAC,CAAC,CAAF,EAAK,CAAL;EAAR,KAAhC,CAAzB;EAEA,SAAKsE,KAAL,GAAa,IAAI5C,IAAJ,CAAS;EACpBmB,MAAAA,GAAG,EAAE;EACH8D,QAAAA,KAAK,EAAER,MADJ;EAEHS,QAAAA,QAAQ,EAAE,KAAKC,WAAL,CAAiBV,MAAjB,CAFP;EAGHW,QAAAA,MAAM,EAAE,CAAC,CAAD,EAAI,CAAJ;EAHL,OADe;EAMpB1D,MAAAA,KAAK,EAAE;EACLuD,QAAAA,KAAK,EAAEN,MADF;EAELO,QAAAA,QAAQ,EAAE,KAAKC,WAAL,CAAiBR,MAAjB,CAFL;EAGLS,QAAAA,MAAM,EAAE,CAAC,CAAD,EAAI,CAAJ;EAHH,OANa;EAWpBnU,MAAAA,GAAG,EAAE;EACHgU,QAAAA,KAAK,EAAExD,GAAG,CAACS,QADR;EAEHgD,QAAAA,QAAQ,EAAE,CAAC,KAAD,EAAQ,KAAR,CAFP;EAGHE,QAAAA,MAAM,EAAE,CAAC,CAAD,EAAI,CAAJ;EAHL;EAXe,KAAT,EAgBV;EACDpC,MAAAA,YAAY,EAAEle,eADb;EAEDkf,MAAAA,eAAe,EAAEjf;EAFhB,KAhBU,EAmBV;EACDoc,MAAAA,GAAG,EAAEM,GAAG,CAACN,GADR;EAEDO,MAAAA,KAAK,EAAED,GAAG,CAACC,KAFV;EAGDzQ,MAAAA,GAAG,EAAEwQ,GAAG,CAACxQ;EAHR,KAnBU,EAuBVyL,EAvBU,CAuBP;EACJ;EACA2I,MAAAA,IAAI,EAAE,UAACC,GAAD;EACJ;EACAhO,QAAAA,KAAI,CAACsL,KAAL,CAAW1E,OAAX,CAAmB8F,eAAnB,GAAqCjf,mBAArC;;EAEAuS,QAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmB,MAAnB,EAA2B;EAAEuI,UAAAA,SAAS,EAAEoE,GAAG,CAACpE;EAAjB,SAA3B,CAAb;EACD,OAPG;EAQJjC,MAAAA,MAAM,EAAE,UAACqG,GAAD;EACN,YAAIA,GAAG,CAACC,KAAJ,CAAUtU,GAAV,KAAkB,CAAtB,EAAyB;EACvBqG,UAAAA,KAAI,CAACkO,mBAAL,CAAyBF,GAAzB;;EACAhO,UAAAA,KAAI,CAACmM,cAAL;EACD;;EACDnM,QAAAA,KAAI,CAACkG,cAAL,CAAoB8H,GAApB;EACD,OAdG;EAeJG,MAAAA,OAAO,EAAE,UAAAH,GAAA;EACPhO,QAAAA,KAAI,CAACkG,cAAL,CAAoB8H,GAApB;EACD,OAjBG;EAkBJI,MAAAA,YAAY,EAAE,UAACJ,GAAD;EACZhO,QAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmB,cAAnB,EAAmC;EAAEuI,UAAAA,SAAS,EAAEoE,GAAG,CAACpE;EAAjB,SAAnC,CAAb;EACD;EApBG,KAvBO,CAAb;EA6CD,GAxDO;;EA0DA,8BAAA,GAAR,UAA6BiC,UAA7B;EACE,QAAIA,UAAU,CAACnB,QAAf,EAAyB;EACvBmB,MAAAA,UAAU,CAACnB,QAAX,GACE,KAAK2D,iBAAL,CAAuBxC,UAAU,CAACnB,QAAlC,EAA4CmB,UAAU,CAAClS,GAAvD,EAA4DkS,UAAU,CAAChB,WAAvE,CADF;EAED;;EACD,QAAIgB,UAAU,CAAClB,UAAf,EAA2B;EACzBkB,MAAAA,UAAU,CAAClB,UAAX,GAAwB,KAAK2D,mBAAL,CAAyBzC,UAAU,CAAClB,UAApC,EAAgDkB,UAAU,CAAClS,GAA3D,CAAxB;EACD;;EACD,WAAOkS,UAAP;EACD,GATO;;EAaA,qBAAA,GAAR,UAA4DpoB,GAA5D;EACE,QAAIC,KAAJ;;EAEA,QAAI,OAAOD,GAAP,KAAe,QAAnB,EAA6B;EAC3BC,MAAAA,KAAK,GAAG,KAAKkjB,OAAL,CAAanjB,GAAb,CAAR;EACD,KAFD,MAEO,IAAI8qB,SAAS,CAAChqB,MAAV,KAAqB,CAAzB,EAA4B;EACjCb,MAAAA,KAAK,GAAG,KAAKkjB,OAAb;EACD;;EACD,WAAOljB,KAAP;EACD,GATO;;EAWA,qBAAA,GAAR,UAAoBkjB,OAApB;EACE,SAAK,IAAMnjB,GAAX,IAAkBmjB,OAAlB,EAA2B;EACzB,WAAKA,OAAL,CAAanjB,GAAb,IAAoBmjB,OAAO,CAACnjB,GAAD,CAA3B;EACD;EACF,GAJO;;EAMA,uBAAA,GAAR,UAAsBD,IAAtB;EACE,QAAMojB,OAAO,GAAG,KAAKA,OAArB;EACA,QAAMO,IAAI,GAAG,KAAKmE,KAAlB;EACA,QAAMkD,IAAI,GAAG5H,OAAO,CAAC4D,QAAR,KAAqBxc,SAAS,CAACG,EAA5C;EACA,QAAMsgB,UAAU,GAAG7H,OAAO,CAAC4D,QAAR,KAAqBxc,SAAS,CAACE,QAAlD;;EAEA,QAAMuc,cAAc,GAAG+D,IAAI,GACxBnhB,mBAAmB,GAAGuZ,OAAO,CAAC6D,cADN,GAEzB7D,OAAO,CAAC6D,cAFV;;EAKA,QAAIjnB,IAAI,CAACkrB,IAAL,CAAU,UAAAjrB,GAAA;EACZ,aAAAA,GAAG,KAAK,eAAR,IAA2BA,GAAG,KAAK,KAAnC,IAA4CA,GAAG,KAAK,aAApD,IACAA,GAAG,KAAK,UADR,IACsBA,GAAG,KAAK,YAD9B;EAC0C,KAFxC,CAAJ,EAGG;EACD;EACA,UAAID,IAAI,CAACqQ,OAAL,CAAa,KAAb,KAAuB,CAA3B,EAA8B;EAC5BsT,QAAAA,IAAI,CAACwH,KAAL,CAAW;EAAC,iBAAO/H,OAAO,CAACjN;EAAhB,SAAX;EACA,aAAKwS,cAAL;EACD;;EAED,WAAK+B,mBAAL;EACD;;EAED,QAAI1qB,IAAI,CAACkrB,IAAL,CAAU,UAAAjrB,GAAA;EAAO,aAAAA,GAAG,KAAK,UAAR;EAAkB,KAAnC,CAAJ,EAA0C;EACxC,UAAMmnB,QAAQ,GAAGhE,OAAO,CAACgE,QAAzB;EACA,UAAMgE,OAAO,GAAGzH,IAAI,CAACoE,GAAL,GAAW5R,GAA3B;EACA,UAAIkV,OAAO,GAAG1H,IAAI,CAACoE,GAAL,GAAW5R,GAAzB;EAEA/N,MAAAA,MAAA,CAAUub,IAAI,CAAC/V,IAAL,CAAUuI,GAAV,CAAcgU,KAAxB,EAAuC/C,QAAvC;;EAEA,UAAIiE,OAAO,GAAGjE,QAAQ,CAAC,CAAD,CAAtB,EAA2B;EACzBiE,QAAAA,OAAO,GAAGjE,QAAQ,CAAC,CAAD,CAAlB;EACD,OAFD,MAEO,IAAIgE,OAAO,GAAGhE,QAAQ,CAAC,CAAD,CAAtB,EAA2B;EAChCiE,QAAAA,OAAO,GAAGjE,QAAQ,CAAC,CAAD,CAAlB;EACD;;EAED,UAAIgE,OAAO,KAAKC,OAAhB,EAAyB;EACvB1H,QAAAA,IAAI,CAACwH,KAAL,CAAW;EACThV,UAAAA,GAAG,EAAEkV;EADI,SAAX,EAEG,CAFH;;EAGA,aAAKX,mBAAL;;EACA,aAAK/B,cAAL;EACD;EACF;;EAED,QAAI3oB,IAAI,CAACkrB,IAAL,CAAU,UAAAjrB,GAAA;EAAO,aAAAA,GAAG,KAAK,UAAR;EAAkB,KAAnC,KAAwCwD,oBAA5C,EAAkE;EAChE;EACA,UAAI,KAAK+lB,oBAAT,EAA+B;EAC7B,aAAK1B,KAAL,CAAW7D,UAAX,CAAsB,KAAKuF,oBAA3B;;EACA,aAAKA,oBAAL,CAA0BxF,OAA1B;;EACA,aAAKwF,oBAAL,GAA4B,IAA5B;EACD;;EAED,UAAI,KAAK9B,iBAAT,EAA4B;EAC1B,aAAKA,iBAAL,CAAuB1D,OAAvB;;EACA,aAAK0D,iBAAL,GAAyB,IAAzB;EACD;;EAED,UAAIsD,IAAJ,EAAU;EACR,aAAKM,qBAAL;EACD,OAFD,MAEO,IAAIL,UAAJ,EAAgB;EACrB,aAAKzB,oBAAL,GAA4B,IAAI+B,eAAJ,CAAoB,KAAKjE,QAAzB,CAA5B;;EACA,aAAKQ,KAAL,CAAWtC,OAAX,CAAmB,CAAC,KAAD,EAAQ,OAAR,CAAnB,EAAqC,KAAKgE,oBAA1C;EACD;;EAED,WAAKvB,aAAL,CAAmBlD,cAAnB,CAAkCiG,IAAlC;EACD;;EAED,QAAIhrB,IAAI,CAACkrB,IAAL,CAAU,UAAAjrB,GAAA;EAAO,aAAAA,GAAG,KAAK,aAAR;EAAqB,KAAtC,CAAJ,EAA6C;EAC3C,UAAM8mB,WAAW,GAAG3D,OAAO,CAAC2D,WAA5B;;EAEA,UAAIA,WAAJ,EAAiB;EACfpD,QAAAA,IAAI,CAAC6B,OAAL,CAAa,CAAC,KAAD,EAAQ,OAAR,CAAb,EAA+B,KAAKkE,iBAApC;EACD,OAFD,MAEO;EACL/F,QAAAA,IAAI,CAACM,UAAL,CAAgB,KAAKyF,iBAArB;EACD;EACF;;EAED,QAAI1pB,IAAI,CAACkrB,IAAL,CAAU,UAAAjrB,GAAA;EAAO,aAAAA,GAAG,KAAK,SAAR;EAAiB,KAAlC,CAAJ,EAAyC;EACvC,UAAM6mB,OAAO,GAAG1D,OAAO,CAAC0D,OAAxB,CADuC;;EAIvCnD,MAAAA,IAAI,CAACM,UAAL,CAAgB,KAAKsF,eAArB;;EACA,UAAIzC,OAAJ,EAAa;EACXnD,QAAAA,IAAI,CAAC6B,OAAL,CAAa,CAAC,KAAD,CAAb,EAAsB,KAAK+D,eAA3B;EACD;EACF;;EAED,SAAKiC,yBAAL,CAA+BpI,OAAO,CAAC6D,cAAvC,EAAuD7D,OAAO,CAAC0D,OAA/D;;EAEA,QAAI9mB,IAAI,CAACkrB,IAAL,CAAU,UAAAjrB,GAAA;EAAO,aAAAA,GAAG,KAAK,gBAAR;EAAwB,KAAzC,KAA8C,KAAKunB,QAAvD,EAAiE;EAC/D,WAAKiE,YAAL,CAAkBxE,cAAlB;EACD;EACF,GA9FO;;EAgGA,mCAAA,GAAR,UAAkCA,cAAlC,EAA4FH,OAA5F;EACE,QAAI,KAAK2C,eAAT,EAA0B;EACxB;EACA,WAAK3B,KAAL,CAAW7D,UAAX,CAAsB,KAAKwF,eAA3B,EAFwB;;;EAKxB,UACE3C,OAAO,IACPG,cAAc,KAAKld,mBADnB;EAGC,WAAK+d,KAAL,CAAmB4D,OAAnB,CAA2Brb,OAA3B,CAAmC,KAAKoZ,eAAxC,MAA6D,CAAC,CAJjE,EAKE;EACA,aAAK3B,KAAL,CAAWtC,OAAX,CAAmB,CAAC,KAAD,CAAnB,EAA4B,KAAKiE,eAAjC;EACD;EACF;EACF,GAfO;;EAiBA,sBAAA,GAAR,UAAqBkC,SAArB;EACE;EACA,QAAI,KAAK1D,aAAT,EAAwB;EACtB,WAAKH,KAAL,CAAW7D,UAAX,CAAsB,KAAKgE,aAA3B;EACD;;EAED,QAAM2D,UAAU,GAAGD,SAAS,GAAG9hB,mBAAZ,GAAkC,KAAlC,GAA0C,IAA7D;EACA,QAAMgiB,YAAY,GAAGF,SAAS,GAAG7hB,qBAAZ,GAAoC,OAApC,GAA8C,IAAnE;;EAEA,SAAKge,KAAL,CAAWtC,OAAX,CAAmB,CAACoG,UAAD,EAAaC,YAAb,CAAnB,EAA2D,KAAK5D,aAAhE;EACD,GAVO;;EAYA,+BAAA,GAAR;EAAA,oBAAA;;EACE,SAAKP,iBAAL,GAAyB,IAAIoE,gBAAJ,EAAzB;;EACA,SAAKpE,iBAAL,CAAuB9F,EAAvB,CAA0B,QAA1B,EAAoC,UAAApE,CAAA;EAClChB,MAAAA,KAAI,CAACkG,cAAL,CAAoBlF,CAApB;EACD,KAFD;EAGD,GALO;;EAOA,2BAAA,GAAR,UAA0BuO,WAA1B,EAAiDC,MAAjD,EAAkEC,cAAlE;EACE,QAAMC,KAAK,GAAG,KAAKC,kBAAL,CAAwBF,cAAc,IAAI,KAAK7I,OAAL,CAAaiE,WAA/B,IAA8C,CAAtE,CAAd;;EACA,QAAMlR,GAAG,GAAG6V,MAAM,IAAI,KAAKlE,KAAL,CAAWC,GAAX,GAAiB5R,GAAvC;;EACA,QAAMiW,aAAa,GAAGjW,GAAG,GAAG+V,KAA5B;EACA,QAAMG,OAAO,GAAGN,WAAW,CAAC,CAAD,CAAX,GAAiBA,WAAW,CAAC,CAAD,CAA5B,IAAmCK,aAAnD;;EAEA,QAAIC,OAAJ,EAAa;EACX,aAAON,WAAP;EACD,KAFD,MAEO;EACL,aAAO,KAAK3I,OAAL,CAAa8D,QAAb,IAAyBV,iBAAhC;EACD;EACF,GAXO;;EAaA,6BAAA,GAAR,UAA4B8F,aAA5B,EAAqDN,MAArD;EACE,QAAM7V,GAAG,GAAG6V,MAAM,IAAI,KAAKlE,KAAL,CAAWC,GAAX,GAAiB5R,GAAvC;;EACA,QAAMkW,OAAO,GAAGC,aAAa,CAAC,CAAD,CAAb,GAAmBA,aAAa,CAAC,CAAD,CAAhC,IAAuCnW,GAAvD;;EAEA,QAAIkW,OAAJ,EAAa;EACX,aAAOC,aAAP;EACD,KAFD,MAEO;EACL,aAAO,KAAKlJ,OAAL,CAAa+D,UAAb,IAA2BV,mBAAlC;EACD;EACF,GATO;;EAWA,qBAAA,GAAR,UAAoB0D,KAApB;EACE,WAAOA,KAAK,CAAC,CAAD,CAAL,GAAWA,KAAK,CAAC,CAAD,CAAhB,GAAsB,GAAtB,GAA4B,CAAC,KAAD,EAAQ,KAAR,CAA5B,GAA6C,CAAC,IAAD,EAAO,IAAP,CAApD;EACD,GAFO;EAIR;;;;;;;;;;;;;EAWQ,6BAAA,GAAR,UAA4BoC,SAA5B;EACE,QAAM5F,GAAG,GAAG,KAAKvD,OAAjB;;EACA,QAAMjN,GAAG,GAAG,KAAK2R,KAAL,CAAWC,GAAX,GAAiB5R,GAA7B;;EAEA,QAAM0T,MAAM,GAAG,KAAKC,iBAAL,CAAuBnD,GAAG,CAACQ,UAA3B,EAAuChR,GAAvC,EAA4CwQ,GAAG,CAACE,aAAhD,CAAf;;EACA,QAAM8C,MAAM,GAAG,KAAKC,eAAL,CAAqBjD,GAAG,CAACO,QAAzB,EAAmC/Q,GAAnC,EAAwCwQ,GAAG,CAACU,WAA5C,CAAf;;;EAGA,QAAM0B,GAAG,GAAG,KAAKjB,KAAL,CAAWC,GAAX,EAAZ;;EACA,QAAIliB,CAAC,GAAGkjB,GAAG,CAAC1C,GAAZ;EACA,QAAI2C,CAAC,GAAGD,GAAG,CAACnC,KAAZ;EAEAxe,IAAAA,MAAA,CAAU,KAAK0f,KAAL,CAAWla,IAAX,CAAgByY,GAAhB,CAAoB8D,KAA9B,EAA4CR,MAA5C;EACAvhB,IAAAA,MAAA,CAAU,KAAK0f,KAAL,CAAWla,IAAX,CAAgBgZ,KAAhB,CAAsBuD,KAAhC,EAA8CN,MAA9C;EACA,SAAK/B,KAAL,CAAWla,IAAX,CAAgByY,GAAhB,CAAoB+D,QAApB,GAA+B,KAAKC,WAAL,CAAiBV,MAAjB,CAA/B;EACA,SAAK7B,KAAL,CAAWla,IAAX,CAAgBgZ,KAAhB,CAAsBwD,QAAtB,GAAiC,KAAKC,WAAL,CAAiBR,MAAjB,CAAjC;EAEA;;;;EAGA,QAAIhkB,CAAC,GAAG8jB,MAAM,CAAC,CAAD,CAAd,EAAmB;EACjB9jB,MAAAA,CAAC,GAAG8jB,MAAM,CAAC,CAAD,CAAV;EACD,KAFD,MAEO,IAAI9jB,CAAC,GAAG8jB,MAAM,CAAC,CAAD,CAAd,EAAmB;EACxB9jB,MAAAA,CAAC,GAAG8jB,MAAM,CAAC,CAAD,CAAV;EACD;;EAED,QAAIX,CAAC,GAAGa,MAAM,CAAC,CAAD,CAAd,EAAmB;EACjBb,MAAAA,CAAC,GAAGa,MAAM,CAAC,CAAD,CAAV;EACD,KAFD,MAEO,IAAIb,CAAC,GAAGa,MAAM,CAAC,CAAD,CAAd,EAAmB;EACxBb,MAAAA,CAAC,GAAGa,MAAM,CAAC,CAAD,CAAV;EACD;;EAED,QAAI0C,SAAJ,EAAe;EACbA,MAAAA,SAAS,CAACrhB,GAAV,CAAc;EACZmb,QAAAA,GAAG,EAAExgB,CADO;EAEZ+gB,QAAAA,KAAK,EAAEoC;EAFK,OAAd;EAID;;EAED,SAAKlB,KAAL,CAAWqD,KAAX,CAAiB;EACf9E,MAAAA,GAAG,EAAExgB,CADU;EAEf+gB,MAAAA,KAAK,EAAEoC;EAFQ,KAAjB,EAGG,CAHH;;EAKA,WAAO,IAAP;EACD,GA7CO;;EA+CA,2BAAA,GAAR,UAA0B7B,UAA1B,EAAgDhR,GAAhD,EAA6D0Q,aAA7D;EACE,QAAI,KAAKzD,OAAL,CAAa4D,QAAb,KAA0Bxc,SAAS,CAACG,EAAxC,EAA4C;EAC1C;EACA,aAAO+b,oBAAP;EACD;;EAED,QAAM8F,aAAa,GAAGrF,UAAU,CAAC,CAAD,CAAV,GAAgBA,UAAU,CAAC,CAAD,CAAhD;EACA,QAAMsF,OAAO,GAAGtW,GAAG,GAAG,CAAtB;EACA,QAAMuW,UAAU,GAAGF,aAAa,GAAG,GAAnC;;EAEA,QAAI3F,aAAa,IAAI,CAAC6F,UAAtB,EAAkC;EAChC;EACA,aAAOvF,UAAU,CAACwF,MAAX,EAAP;EACD;;;EAGD,WAAO,CAACxF,UAAU,CAAC,CAAD,CAAV,GAAgBsF,OAAjB,EAA0BtF,UAAU,CAAC,CAAD,CAAV,GAAgBsF,OAA1C,CAAP;EACD,GAjBO;;EAmBA,yBAAA,GAAR,UAAwBvF,QAAxB,EAA4C/Q,GAA5C,EAAyDkR,WAAzD;EACE,QAAI,KAAKjE,OAAL,CAAa4D,QAAb,KAA0Bxc,SAAS,CAACG,EAAxC,EAA4C;EAC1C,aAAO6b,iBAAP;EACD;;EAED,QAAMoG,eAAe,GAAG1F,QAAQ,CAAC,CAAD,CAAR,GAAcA,QAAQ,CAAC,CAAD,CAA9C;EAEA;;;;EAGA,QAAI0F,eAAe,IAAI,GAAvB,EAA4B;EAC1B;EACA,aAAO1F,QAAQ,CAACyF,MAAT,EAAP;EACD;EAED;;;EAGA;;;EACA,QAAME,iBAAiB,GACrBC,IAAQ,CAAC7nB,QAAT,CAAkB3C,IAAI,CAACkD,KAAL,CAAW6hB,WAAX,EAAwB,IAAI/kB,IAAI,CAAC+T,GAAL,CAASqO,QAAA,CAAkBvO,GAAG,GAAG,CAAxB,CAAT,CAA5B,CAAlB,CADF;;EAIA,WAAO,CACL+Q,QAAQ,CAAC,CAAD,CAAR,GAAc2F,iBADT,EAEL3F,QAAQ,CAAC,CAAD,CAAR,GAAc2F,iBAFT,CAAP;EAID,GA3BO;;;EA8BA,wBAAA,GAAR,UAAuBrC,GAAvB;EACE,QAAMzB,GAAG,GAAG,KAAKjB,KAAL,CAAWC,GAAX,EAAZ;;EACA,QAAMpB,GAAG,GAAG,KAAKvD,OAAjB;EACA,QAAMc,KAAK,GAAgF;EACzF6I,MAAAA,aAAa,EAAEpG,GAAG,CAACtV,OADsE;EAEzF+U,MAAAA,SAAS,EAAEoE,GAAG,CAACpE,SAF0E;EAGzFC,MAAAA,GAAG,EAAE0C,GAAG,CAAC1C,GAHgF;EAIzFO,MAAAA,KAAK,EAAEmC,GAAG,CAACnC,KAJ8E;EAKzFzQ,MAAAA,GAAG,EAAE4S,GAAG,CAAC5S,GALgF;EAMzFrR,MAAAA,UAAU,EAAE;EAN6E,KAA3F;;EASA,QAAI6hB,GAAG,CAACK,QAAJ,KAAiBxc,SAAS,CAACG,EAA3B,IAAiC,KAAK+c,iBAA1C,EAA6D;EAC3DxD,MAAAA,KAAK,CAACpf,UAAN,GAAmB,KAAK4iB,iBAAL,CAAuB4B,qBAAvB,CAA6CP,GAAG,CAAC1C,GAAjD,CAAnB;EACD;;EAED,SAAKzI,OAAL,CAAa,IAAIC,gBAAJ,CAAmB,QAAnB,EAA6BqG,KAA7B,CAAb;EACD,GAjBO;;;EAoBA,4BAAA,GAAR,UAA2B8I,KAA3B;EACE,QAAMC,UAAU,GAAG,CACjB,KADiB,EACV,KADU,EACH,KADG,EACI,KADJ,EACW,KADX,EACkB,KADlB,EACyB,KADzB,EACgC,KADhC,EAEjB,KAFiB,EAEV,KAFU,EAEH,KAFG,EAEI,KAFJ,EAEW,KAFX,EAEkB,KAFlB,EAEyB,KAFzB,EAEgC,IAFhC,EAEsC,IAFtC,EAE4C,IAF5C,EAEkD,IAFlD,EAGjB,IAHiB,EAGX,IAHW,EAGL,IAHK,EAGC,IAHD,EAGO,IAHP,EAGa,IAHb,EAGmB,IAHnB,EAGyB,IAHzB,EAG+B,IAH/B,EAGqC,IAHrC,EAG2C,IAH3C,EAGiD,IAHjD,EAIjB,IAJiB,EAIX,IAJW,EAIL,IAJK,EAIC,IAJD,EAIO,IAJP,CAAnB;EAMA,QAAMC,WAAW,GAAG,CAClB,KADkB,EACX,KADW,EACJ,KADI,EACG,KADH,EACU,KADV,EACiB,KADjB,EACwB,KADxB,EAC+B,KAD/B,EAElB,KAFkB,EAEX,KAFW,EAEJ,KAFI,EAEG,KAFH,EAEU,KAFV,EAEiB,KAFjB,EAEwB,KAFxB,EAE+B,IAF/B,EAEqC,IAFrC,EAE2C,IAF3C,EAEiD,IAFjD,EAGlB,IAHkB,EAGZ,IAHY,EAGN,IAHM,EAGA,IAHA,EAGM,IAHN,EAGY,IAHZ,EAGkB,IAHlB,EAGwB,IAHxB,EAG8B,IAH9B,EAGoC,IAHpC,EAG0C,IAH1C,EAGgD,IAHhD,EAIlB,IAJkB,EAIZ,IAJY,EAIN,IAJM,EAIA,IAJA,EAIM,IAJN,CAApB;EAOA,QAAIC,QAAQ,GAAG,CAAC,CAAhB;;EAEA,SAAK,IAAInpB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGipB,UAAU,CAAClsB,MAAX,GAAoB,CAAxC,EAA2CiD,CAAC,EAA5C,EAAgD;EAC9C,UAAIipB,UAAU,CAACjpB,CAAD,CAAV,IAAiBgpB,KAAjB,IAA0BC,UAAU,CAACjpB,CAAC,GAAG,CAAL,CAAV,IAAqBgpB,KAAnD,EAA0D;EACxDG,QAAAA,QAAQ,GAAGnpB,CAAX;EACA;EACD;EACF;;EAED,QAAImpB,QAAQ,KAAK,CAAC,CAAlB,EAAqB;EACnB,UAAIF,UAAU,CAAC,CAAD,CAAV,GAAgBD,KAApB,EAA2B;EACzB,eAAOE,WAAW,CAAC,CAAD,CAAlB;EACD,OAFD,MAEO;EACL;EACA,eAAOA,WAAW,CAAEA,WAAW,CAAC,CAAD,CAAX,CAAuBnsB,MAAvB,GAAgC,CAAlC,CAAlB;EACD;EACF;;EAED,QAAMqsB,MAAM,GAAGH,UAAU,CAACE,QAAD,CAAzB;EACA,QAAME,MAAM,GAAGJ,UAAU,CAACE,QAAQ,GAAG,CAAZ,CAAzB;EACA,QAAMG,OAAO,GAAGJ,WAAW,CAACC,QAAD,CAA3B;EACA,QAAMI,OAAO,GAAGL,WAAW,CAACC,QAAQ,GAAG,CAAZ,CAA3B;EAEA,WAAO,KAAKK,KAAL,CAAWF,OAAX,EAAoBC,OAApB,EAA6B,CAACP,KAAK,GAAGI,MAAT,KAAoBC,MAAM,GAAGD,MAA7B,CAA7B,CAAP;EACD,GAtCO;;EAwCA,eAAA,GAAR,UAAcloB,CAAd,EAAyBmG,CAAzB,EAAoCoiB,QAApC;EACE,WAAOvoB,CAAC,GAAGuoB,QAAQ,IAAIpiB,CAAC,GAAGnG,CAAR,CAAnB;EACD,GAFO;;EAIA,2BAAA,GAAR;EACE,QAAMyhB,GAAG,GAAG,KAAKvD,OAAjB;;EAEA,SAAK0E,KAAL,CAAWqD,KAAX,CAAiB;EACf9E,MAAAA,GAAG,EAAEM,GAAG,CAACN,GADM;EAEfO,MAAAA,KAAK,EAAED,GAAG,CAACC,KAFI;EAGfzQ,MAAAA,GAAG,EAAEwQ,GAAG,CAACxQ;EAHM,KAAjB,EAIG,CAJH;;EAMA,WAAO,IAAP;EACD,GAVO;;EAroBMuX,EAAAA,uBAAA,GAAUluB,OAAV;;EAEAkuB,EAAAA,+BAAA,GAAkBhkB,eAAlB;EACAgkB,EAAAA,qCAAA,GAAwB/jB,qBAAxB;EACA+jB,EAAAA,mCAAA,GAAsB3jB,mBAAtB;EACA2jB,EAAAA,mCAAA,GAAsB7jB,mBAAtB;EACA6jB,EAAAA,qCAAA,GAAwB5jB,qBAAxB;EACA4jB,EAAAA,oCAAA,GAAuB9jB,oBAAvB;EAyoBhB,wBAAA;EAAC,EAjpB6BiV,UAA9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECrCA;;;;;;;;EAOA,IAAM8O,UAAU,GAAG;EACjB;;;;;;;;;EASAC,EAAAA,cAAc,EAAE,EAVC;;EAWjB;;;;;;;;;EASAC,EAAAA,QAAQ,EAAE,EApBO;;EAqBjB;;;;;;;;;EASAC,EAAAA,eAAe,EAAE,EA9BA;;EA+BjB;;;;;;;;;EASAC,EAAAA,iBAAiB,EAAE,EAxCF;;EAyCjB;;;;;;;;;EASAC,EAAAA,gBAAgB,EAAE,EAlDD;;EAmDjB;;;;;;;;;EASAC,EAAAA,sBAAsB,EAAE;EA5DP,CAAnB;EA+DA;;;;;;;;EAOA,IAAMC,iBAAiB,GAKnB;EACF;;;;;;;;;EASAC,EAAAA,KAAK,EAAE,OAVL;;EAWF;;;;;;;;;EASAC,EAAAA,WAAW,EAAE,YApBX;;EAqBF;;;;;;;;;EASAC,EAAAA,aAAa,EAAE,cA9Bb;;EA+BF;;;;;;;;;EASAC,EAAAA,KAAK,EAAE;EAxCL,CALJ;EAgDA;;;;;;;;EAOA,IAAMC,eAAe,GAMjB;EACF;;;;;;;;;EASAC,EAAAA,eAAe,EAAE,iBAVf;;EAWF;;;;;;;;;EASAC,EAAAA,OAAO,EAAE,SApBP;;EAqBF;;;;;;;;;;EAUAC,EAAAA,SAAS,EAAE,WA/BT;;EAgCF;;;;;;;;;;;;EAYAC,EAAAA,QAAQ,EAAE,UA5CR;;EA6CF;;;;;;;;;;;;EAYAC,EAAAA,iBAAiB,EAAE;EAzDjB,CANJ;EAkEA;;;;;;;;EAOA,IAAMC,aAAa,GAIf;EACF;;;;;;;;;EASAC,EAAAA,UAAU,EAAE,KAVV;;EAWF;;;;;;;;;EASAC,EAAAA,UAAU,EAAE,KApBV;;EAqBF;;;;;;;;;EASAtkB,EAAAA,IAAI,EAAE;EA9BJ,CAJJ;;EAsCA,IAAMukB,kBAAkB,GAA+C;EACrE1uB,EAAAA,KAAK,EAAE,IAD8D;EAErEuB,EAAAA,KAAK,EAAE,IAF8D;EAGrEotB,EAAAA,cAAc,EAAE,IAHqD;EAIrEC,EAAAA,aAAa,EAAE,IAJsD;EAKrEC,EAAAA,YAAY,EAAE,IALuD;EAMrEle,EAAAA,KAAK,EAAE,IAN8D;EAOrEC,EAAAA,MAAM,EAAE,IAP6D;EAQrEmV,EAAAA,GAAG,EAAE,IARgE;EASrEO,EAAAA,KAAK,EAAE,IAT8D;EAUrEzQ,EAAAA,GAAG,EAAE,IAVgE;EAWrE0Q,EAAAA,aAAa,EAAE,IAXsD;EAYrEC,EAAAA,OAAO,EAAE,IAZ4D;EAarEC,EAAAA,WAAW,EAAE,IAbwD;EAcrEC,EAAAA,QAAQ,EAAE,IAd2D;EAerEE,EAAAA,QAAQ,EAAE,IAf2D;EAgBrEC,EAAAA,UAAU,EAAE,IAhByD;EAiBrEC,EAAAA,QAAQ,EAAE,IAjB2D;EAkBrEH,EAAAA,cAAc,EAAE,IAlBqD;EAmBrEmI,EAAAA,WAAW,EAAE;EAnBwD,CAAvE;EAsBA,IAAMC,oBAAoB,GAAG,gBAA7B;;;;;;;;;;;;;EC1SA,IAAMC,gBAAgB,GAAG;EACvB,OAAK,UADkB;EAEvB,UAAQ,cAFe;EAGvB,UAAQ,eAHe;EAIvB,UAAQ,mBAJe;EAKvB,UAAQ,eALe;EAMvB,UAAQ,+BANe;EAOvB,WAAS;EAPc,CAAzB;EAUA,IAAIC,iBAAiB,GAAmB,IAAxC;;EAIA;;;EAAA,qBAAA;;EACgBC,EAAAA,uBAAA,GAAd,UAA2Brd,EAA3B,EAAsDlQ,IAAtD,EAAoEnC,MAApE;EACE,QAAM2vB,MAAM,GAAGtd,EAAE,CAACK,YAAH,CAAgBvQ,IAAhB,CAAf;EAEAkQ,IAAAA,EAAE,CAACO,YAAH,CAAgB+c,MAAhB,EAAwB3vB,MAAxB;EACAqS,IAAAA,EAAE,CAACQ,aAAH,CAAiB8c,MAAjB;EACA,QAAMC,OAAO,GAAGvd,EAAE,CAACwd,kBAAH,CAAsBF,MAAtB,EAA8Btd,EAAE,CAACyd,cAAjC,CAAhB;;EAEA,QAAIF,OAAJ,EAAa;EACX,aAAOD,MAAP;EACD;;;EAGDzT,IAAAA,OAAO,CAAC6T,KAAR,CAAc1d,EAAE,CAAC2d,gBAAH,CAAoBL,MAApB,CAAd;EAEA,WAAO,IAAP;EACD,GAfa;;EAiBAD,EAAAA,wBAAA,GAAd,UAA4Brd,EAA5B,EAAuDI,YAAvD,EAAkFK,cAAlF;EACE,QAAME,OAAO,GAAGX,EAAE,CAACY,aAAH,EAAhB;EAEAZ,IAAAA,EAAE,CAACa,YAAH,CAAgBF,OAAhB,EAAyBP,YAAzB;EACAJ,IAAAA,EAAE,CAACa,YAAH,CAAgBF,OAAhB,EAAyBF,cAAzB;EACAT,IAAAA,EAAE,CAACD,WAAH,CAAeY,OAAf;EAEAX,IAAAA,EAAE,CAACgB,YAAH,CAAgBZ,YAAhB;EACAJ,IAAAA,EAAE,CAACgB,YAAH,CAAgBP,cAAhB;EAEA,QAAM8c,OAAO,GAAGvd,EAAE,CAACoB,mBAAH,CAAuBT,OAAvB,EAAgCX,EAAE,CAAC4d,WAAnC,CAAhB;;EAEA,QAAIL,OAAJ,EAAa;EACX,aAAO5c,OAAP;EACD;;EAEDX,IAAAA,EAAE,CAAC6d,aAAH,CAAiBld,OAAjB;EACA,WAAO,IAAP;EACD,GAlBa;;EAoBA0c,EAAAA,qBAAA,GAAd,UAAyBrd,EAAzB,EAAoDzS;EAAe;EAAnE,IAAqFuwB,IAArF,EAAuGC,QAAvG,EAAyHC,IAAzH;EACE,QAAMC,MAAM,GAAGje,EAAE,CAACke,YAAH,EAAf;EAEAle,IAAAA,EAAE,CAACme,UAAH,CAAc5wB,MAAd,EAAsB0wB,MAAtB;EACAje,IAAAA,EAAE,CAACoe,UAAH,CAAc7wB,MAAd,EAAsBuwB,IAAtB,EAA4B9d,EAAE,CAACqe,WAA/B;;EAEA,QAAIJ,MAAJ,EAAY;EACTA,MAAAA,MAAc,CAACF,QAAf,GAA0BA,QAA1B;EACAE,MAAAA,MAAc,CAACK,QAAf,GAA0BR,IAAI,CAAClvB,MAAL,GAAcmvB,QAAxC;EACF;;EAED,QAAIC,IAAI,KAAKnjB,SAAb,EAAwB;EACtBmF,MAAAA,EAAE,CAACue,uBAAH,CAA2BP,IAA3B;EACAhe,MAAAA,EAAE,CAACwe,mBAAH,CAAuBR,IAAvB,EAA8BC,MAAc,CAACF,QAA7C,EAAuD/d,EAAE,CAACye,KAA1D,EAAiE,KAAjE,EAAwE,CAAxE,EAA2E,CAA3E;EACD;;EAED,WAAOR,MAAP;EACD,GAjBa;;EAmBAZ,EAAAA,0BAAA,GAAd,UAA8Bra,MAA9B,EAAyD0b,qBAAzD;;;EACE,QAAMC,gBAAgB,GAAG,CAAC,OAAD,EAAU,oBAAV,EAAgC,WAAhC,EAA6C,WAA7C,CAAzB;EACA,QAAIC,OAAO,GAAiC,IAA5C;;EACA,QAAMC,iBAAiB,YAClB;EACDC,MAAAA,qBAAqB,EAAE,KADtB;EAEDC,MAAAA,SAAS,EAAE;EAFV,OAGGL,sBAJR;;EAOA,QAAMM,2BAA2B,GAAG,UAAA3T,CAAA;EAAK,aAAAA,CAAC,CAAC4T,aAAF;EAAe,KAAxD;;EAEAjc,IAAAA,MAAM,CAACmI,gBAAP,CAAwB,2BAAxB,EAAqD6T,2BAArD;;;EAEA,WAAyB,IAAAE,qBAAAC,SAAAR,iBAAA,kDAAzB,4BAAA,kDAAA,EAA2C;EAAtC,YAAMS,UAAU,6BAAhB;;EACH,YAAI;EACFR,UAAAA,OAAO,GAAG5b,MAAM,CAACqc,UAAP,CAAkBD,UAAlB,EAA8BP,iBAA9B,CAAV;EACD,SAFD,CAEE,OAAOliB,CAAP,EAAU,EAH6B;;;EAIzC,YAAIiiB,OAAJ,EAAa;EACX;EACD;EACF;;;;;;;;;;;;;EAED5b,IAAAA,MAAM,CAACoI,mBAAP,CAA2B,2BAA3B,EAAwD4T,2BAAxD;EAEA,WAAOJ,OAAP;EACD,GA1Ba;;EA4BAvB,EAAAA,wBAAA,GAAd,UAA4Brd,EAA5B,EAAuDsf,aAAvD;EACE,QAAMC,OAAO,GAAGvf,EAAE,CAACwf,aAAH,EAAhB;EAEAxf,IAAAA,EAAE,CAACyf,WAAH,CAAeH,aAAf,EAA8BC,OAA9B;EACAvf,IAAAA,EAAE,CAAC0f,aAAH,CAAiBJ,aAAjB,EAAgCtf,EAAE,CAAC2f,kBAAnC,EAAuD3f,EAAE,CAAC4f,MAA1D;EACA5f,IAAAA,EAAE,CAAC0f,aAAH,CAAiBJ,aAAjB,EAAgCtf,EAAE,CAAC6f,kBAAnC,EAAuD7f,EAAE,CAAC4f,MAA1D;EACA5f,IAAAA,EAAE,CAAC0f,aAAH,CAAiBJ,aAAjB,EAAgCtf,EAAE,CAAC8f,cAAnC,EAAmD9f,EAAE,CAAC+f,aAAtD;EACA/f,IAAAA,EAAE,CAAC0f,aAAH,CAAiBJ,aAAjB,EAAgCtf,EAAE,CAACggB,cAAnC,EAAmDhgB,EAAE,CAAC+f,aAAtD;EACA/f,IAAAA,EAAE,CAACyf,WAAH,CAAeH,aAAf,EAA8B,IAA9B;EAEA,WAAOC,OAAP;EACD,GAXa;EAad;;;;;;;EAKclC,EAAAA,2BAAA,GAAd;EACE,QAAID,iBAAiB,KAAK,IAA1B,EAAgC;EAC9B,UAAMpa,MAAM,GAAG/T,QAAQ,CAACC,aAAT,CAAuB,QAAvB,CAAf;EACA,UAAM+wB,YAAY,GAAG5C,UAAU,CAAC6C,eAAX,CAA2Bld,MAA3B,CAArB;EAEAoa,MAAAA,iBAAiB,GAAG,CAAC,CAAC6C,YAAtB,CAJ8B;;EAO9B,UAAIA,YAAJ,EAAkB;EAChB,YAAME,oBAAoB,GAAGF,YAAY,CAACG,YAAb,CAA0B,oBAA1B,CAA7B;;EAEA,YAAID,oBAAJ,EAA0B;EACxBA,UAAAA,oBAAoB,CAACE,WAArB;EACD;EACF;EACF;;EACD,WAAO,CAAC,CAACjD,iBAAT;EACD,GAjBa;EAmBd;;;;;;;EAKcC,EAAAA,wBAAA,GAAd;EACE,QAAMiD,SAAS,GAAG7vB,KAAK,EAAvB;EACA,QAAI8vB,aAAa,GAAG,IAApB;;EAEA,QAAID,SAAS,CAAC1vB,EAAV,CAAaC,IAAb,KAAsB,SAA1B,EAAqC;EACnC,UAAMgG,OAAO,GAAG2pB,UAAU,CAACF,SAAS,CAAC1vB,EAAV,CAAaiG,OAAd,CAA1B;;EAEA,UAAIA,OAAO,IAAI,GAAX,IAAkBA,OAAO,IAAI,CAAjC,EAAoC;EAClC0pB,QAAAA,aAAa,GAAG,KAAhB;EACD,OAFD,MAEO,IAAI1pB,OAAO,KAAK,GAAhB,EAAqB;EAC1B,YAAIypB,SAAS,CAACvvB,OAAV,CAAkBF,IAAlB,KAA2B,QAA/B,EAAyC;EACvC0vB,UAAAA,aAAa,GAAG,KAAhB;EACD;EACF;EACF;;EACD,WAAOA,aAAP;EACD,GAhBa;;EAkBAlD,EAAAA,yCAAA,GAAd,UAA6CoD,IAA7C;EACE,QAAI,EAAEA,IAAI,IAAItD,gBAAV,CAAJ,EAAiC;EAC/B,aAAO,eAAP;EACD;;EAED,WAAOA,gBAAgB,CAACsD,IAAD,CAAvB;EACD,GANa;EASd;;;;;;EAIcpD,EAAAA,qBAAA,GAAd,UAAyBrd,EAAzB,EAAoDzS,MAApD,EAAoEmzB,MAApE;EACE,QAAI;EACF1gB,MAAAA,EAAE,CAAC2gB,UAAH,CAAcpzB,MAAd,EAAsB,CAAtB,EAAyByS,EAAE,CAAC4gB,IAA5B,EAAkC5gB,EAAE,CAAC4gB,IAArC,EAA2C5gB,EAAE,CAAC6gB,aAA9C,EAA6DH,MAA7D;EACD,KAFD,CAEE,OAAOhD,KAAP,EAAc;EACd;EACA7T,MAAAA,OAAO,CAAC6T,KAAR,CAAc,8BAAd,EAA8CA,KAA9C;EACA;EACD;EACF,GARa;;EAUAL,EAAAA,4BAAA,GAAd,UAAgCrd,EAAhC;EACE;EACA,YAAoCA,EAAE,CAAC8gB,YAAH,CAAgB9gB,EAAE,CAAC+gB,gBAAnB,CAApC;EACD,GAHa;;EAIhB,mBAAA;EAAC,GA5KD;;ECZA,IAAMT,SAAS,GAAG7vB,KAAK,EAAvB;EACA,IAAMuwB,MAAM,GAAGV,SAAS,CAACvvB,OAAV,CAAkBF,IAAlB,KAA2B,IAA3B,IAAmCyvB,SAAS,CAACvvB,OAAV,CAAkBkwB,YAAlB,KAAmC,EAArF;EAEA,IAAMC,MAAM,GAER;EACF/E,EAAAA,KAAK,EAAE;EADL,CAFJ;EAMA;;;;;EAIA;;;EAAgChS,EAAAA,2BAAA;;EAW9B,mBAAA;EAAA,gBACEC,WAAA,KAAA,SADF;;EAGEC,IAAAA,KAAI,CAAC8W,eAAL,GAAuB,IAAvB;EACA9W,IAAAA,KAAI,CAAC+W,YAAL,GAAoB,IAApB;EACA/W,IAAAA,KAAI,CAACgX,aAAL,GAAqB,IAArB;;EACD;;;;EAcM,gBAAA,GAAP,UAAcjR,EAAd;UAAgBpQ,EAAE;UAAEshB,aAAa;UAAEC,WAAW;UAAEC,QAAQ;UAAEC,OAAO;EAO/DzhB,IAAAA,EAAE,CAAC0hB,gBAAH,CAAqBJ,aAAqB,CAACK,cAA3C,EAA2D,KAA3D,EAAkEF,OAAlE;EACAzhB,IAAAA,EAAE,CAAC0hB,gBAAH,CAAqBJ,aAAqB,CAACM,eAA3C,EAA4D,KAA5D,EAAmEJ,QAAnE;;EAEA,QAAID,WAAJ,EAAiB;EACfvhB,MAAAA,EAAE,CAAC6hB,YAAH,CAAgB7hB,EAAE,CAAC8hB,SAAnB,EAA+BP,WAAmB,CAACjD,QAAnD,EAA6Dte,EAAE,CAAC+hB,cAAhE,EAAgF,CAAhF;EACD;EACF,GAbM;;EAgBP;;;;;;;;;;;;;;;;;;;;EAkBO,sBAAA,GAAP,UAAoBC,WAApB;EACE,QAAMljB,KAAK,GAAIkjB,WAAgC,CAACC,YAAjC,IACTD,WAAgC,CAACE,UADvC;EAEA,QAAMnjB,MAAM,GAAIijB,WAAgC,CAACG,aAAjC,IACVH,WAAgC,CAACI,WADvC;EAGA,WAAO;EAAEtjB,MAAAA,KAAK,OAAP;EAASC,MAAAA,MAAM;EAAf,KAAP;EACD,GAPM;EASP;;;;;EAGO,0BAAA,GAAP,UAAwB2W,KAAxB;EACE;;;;;;;;EAQD,GATM;EAWP;;;;;;;EAKU,0BAAA,GAAV,UAA2BvnB,KAA3B,EAAuEk0B,cAAvE;EAAuE,iCAAA,EAAA;EAAAA,MAAAA,qBAAA;;;EACrE,QAAMC,WAAW,GAAGtB,MAAM,IAAK7yB,KAAK,YAAYY,gBAAhD;;EAEA,QAAIuzB,WAAW,IAAID,cAAnB,EAAmC;EAC3B,UAAAjS,KAAkBiS,cAAc,IAAI,KAAKE,YAAL,CAAkBp0B,KAAlB,CAApC;EAAA,UAAC2Q,KAAK,WAAN;EAAA,UAAQC,MAAM,YAAd;;EAEN,WAAKqiB,YAAL,GAAoBnyB,QAAQ,CAACC,aAAT,CAAuB,QAAvB,CAApB;EACA,WAAKkyB,YAAL,CAAkBtiB,KAAlB,GAA0BA,KAA1B;EACA,WAAKsiB,YAAL,CAAkBriB,MAAlB,GAA2BA,MAA3B;EACA,WAAKsiB,aAAL,GAAqB,KAAKD,YAAL,CAAkB/B,UAAlB,CAA6B,IAA7B,CAArB;EACD;;EACD,SAAK8B,eAAL,GAAuBkB,cAAvB;EACD,GAZS;;EAcA,yBAAA,GAAV,UAA0Bl0B,KAA1B;EACE,QAAI,CAAC,KAAKizB,YAAV,EAAwB;EACtB,aAAOjzB,KAAP;EACD;EAED;;;;;;;EAKA,QAAMq0B,gBAAgB,GAAG,KAAKD,YAAL,CAAkBp0B,KAAlB,CAAzB;EACA,QAAMs0B,gBAAgB,GAAG,KAAKtB,eAAL,IAAwBqB,gBAAjD;;EAEA,QAAI,KAAKpB,YAAL,CAAkBtiB,KAAlB,KAA4B2jB,gBAAgB,CAAC3jB,KAAjD,EAAwD;EACtD,WAAKsiB,YAAL,CAAkBtiB,KAAlB,GAA0B2jB,gBAAgB,CAAC3jB,KAA3C;EACD;;EAED,QAAI,KAAKsiB,YAAL,CAAkBriB,MAAlB,KAA6B0jB,gBAAgB,CAAC1jB,MAAlD,EAA0D;EACxD,WAAKqiB,YAAL,CAAkBriB,MAAlB,GAA2B0jB,gBAAgB,CAAC1jB,MAA5C;EACD;;EAED,QAAI,KAAKoiB,eAAT,EAA0B;EACxB,WAAKE,aAAL,CAAoBqB,SAApB,CAA8Bv0B,KAA9B,EACE,CADF,EACK,CADL,EACQq0B,gBAAgB,CAAC1jB,KADzB,EACgC0jB,gBAAgB,CAACzjB,MADjD,EAEE,CAFF,EAEK,CAFL,EAEQ0jB,gBAAgB,CAAC3jB,KAFzB,EAEgC2jB,gBAAgB,CAAC1jB,MAFjD;EAGD,KAJD,MAIO;EACL,WAAKsiB,aAAL,CAAoBqB,SAApB,CAA8Bv0B,KAA9B,EAAqC,CAArC,EAAwC,CAAxC;EACD;;EAED,WAAO,KAAKizB,YAAZ;EACD,GA9BS;;EAgCA,4BAAA,GAAV,UAA6BuB,WAA7B;EACE,QAAIC,UAAU,GACZ50B,KAAK,CAACC,OAAN,CAAc00B,WAAW,CAACC,UAA1B,IACED,WAAW,CAACC,UADd,GAC2B50B,KAAK,MAAL,OAAA,WAASA,KAAK,CAAC,CAAD,EAAd,EAAmBM,GAAnB,CAAuB;EAAM,aAAAq0B,WAAW,CAACC,UAAZ;EAAsB,KAAnD,CAF7B;EAIAA,IAAAA,UAAU,GAAGA,UAAU,CAACt0B,GAAX,CACX,UAAAu0B,MAAA;EAAU,sBACL;EACDC,QAAAA,cAAc,EAAE,KADf;EAEDC,QAAAA,QAAQ,EAAE;EAFT,SAGGF,OAJE;EAKR,KANS,CAAb;EASA,WAAOD,UAAP;EACD,GAfS;;EAiBA,uBAAA,GAAV,UAAwBlF,KAAxB;EACE;EACA7T,IAAAA,OAAO,CAAC6T,KAAR,CAAc,iBAAd,EAAiCA,KAAjC;EACA;;EAEA,SAAKjS,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,MAAM,CAAC/E,KAA1B,EAAiC;EAC5C6G,MAAAA,OAAO,EAAE,OAAOtF,KAAP,KAAiB,QAAjB,GAA4BA,KAA5B,GAAoCA,KAAK,CAACsF;EADP,KAAjC,CAAb;EAGD,GARS;;EAvJIC,EAAAA,eAAA,GAAS/B,MAAT;EAgKhB,iBAAA;EAAC,EArK+BxU,UAAhC;;ECXA;;;EAA2BvC,EAAAA,+BAAA;;EAA3B,uBAAA;;EAkRC;;;;EAjRe+Y,EAAAA,yBAAA,GAAd,UAA2BP,WAA3B;EACE,WAAOA,WAAW,CAACQ,KAAZ,IAAqB,QAA5B;EACD,GAFa;;EAOP,+BAAA,GAAP;EACED,IAAAA,YAAY,CAACE,qBAAb,GACEF,YAAY,CAACE,qBAAb,KAAuC,IAAvC,GAA8CF,YAAY,CAACE,qBAA3D,GAAmF;EAEjF,KAFiF,EAE9E,CAAC,CAF6E,EAE1E,CAF0E,EAGjF,CAAC,CAHgF,EAG7E,CAAC,CAH4E,EAGzE,CAHyE,EAIjF,CAAC,CAJgF,EAI7E,CAJ6E,EAI1E,CAJ0E,EAKjF,CALiF,EAK9E,CAL8E,EAK3E,CAL2E;EAQjF,KAAC,CARgF,EAQ7E,CAAC,CAR4E,EAQzE,CAAC,CARwE,EASjF,CATiF,EAS9E,CAAC,CAT6E,EAS1E,CAAC,CATyE,EAUjF,CAViF,EAU9E,CAV8E,EAU3E,CAAC,CAV0E,EAWjF,CAAC,CAXgF,EAW7E,CAX6E,EAW1E,CAAC,CAXyE;EAcjF,KAAC,CAdgF,EAc7E,CAd6E,EAc1E,CAAC,CAdyE,EAejF,CAfiF,EAe9E,CAf8E,EAe3E,CAAC,CAf0E,EAgBjF,CAhBiF,EAgB9E,CAhB8E,EAgB3E,CAhB2E,EAiBjF,CAAC,CAjBgF,EAiB7E,CAjB6E,EAiB1E,CAjB0E;EAoBjF,KApBiF,EAoB9E,CAAC,CApB6E,EAoB1E,CAAC,CApByE,EAqBjF,CAAC,CArBgF,EAqB7E,CAAC,CArB4E,EAqBzE,CAAC,CArBwE,EAsBjF,CAAC,CAtBgF,EAsB7E,CAAC,CAtB4E,EAsBzE,CAtByE,EAuBjF,CAvBiF,EAuB9E,CAAC,CAvB6E,EAuB1E,CAvB0E;EA0BjF,KA1BiF,EA0B9E,CAAC,CA1B6E,EA0B1E,CAAC,CA1ByE,EA2BjF,CA3BiF,EA2B9E,CAAC,CA3B6E,EA2B1E,CA3B0E,EA4BjF,CA5BiF,EA4B9E,CA5B8E,EA4B3E,CA5B2E,EA6BjF,CA7BiF,EA6B9E,CA7B8E,EA6B3E,CAAC,CA7B0E;EAgCjF,KAAC,CAhCgF,EAgC7E,CAAC,CAhC4E,EAgCzE,CAhCyE,EAiCjF,CAAC,CAjCgF,EAiC7E,CAAC,CAjC4E,EAiCzE,CAAC,CAjCwE,EAkCjF,CAAC,CAlCgF,EAkC7E,CAlC6E,EAkC1E,CAAC,CAlCyE,EAmCjF,CAAC,CAnCgF,EAmC7E,CAnC6E,EAmC1E,CAnC0E,CADrF;EAuCA,WAAOF,YAAY,CAACE,qBAApB;EACD,GAzCM;;EA2CA,sBAAA,GAAP;EACE,QAAIF,YAAY,CAACG,WAAjB,EAA8B;EAC5B,aAAOH,YAAY,CAACG,WAApB;EACD;;EAED,QAAMC,SAAS,GAAa,EAA5B;EACA,QAAMC,kBAAkB,GAAG,KAAKC,qBAAL,EAA3B;;EAEA,SAAK,IAAI3xB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAI0xB,kBAAkB,CAAC30B,MAAnB,GAA4B,CAAjD,EAAqDiD,CAAC,IAAI,CAA1D,EAA6D;EAC3DyxB,MAAAA,SAAS,CAAClN,IAAV,CACEvkB,CADF,EAEEA,CAAC,GAAG,CAFN,EAGEA,CAAC,GAAG,CAHN,EAIEA,CAJF,EAKEA,CAAC,GAAG,CALN,EAMEA,CAAC,GAAG,CANN;EAQD;;EAEDqxB,IAAAA,YAAY,CAACG,WAAb,GAA2BC,SAA3B;EACA,WAAOA,SAAP;EACD,GArBM;;EAuBA,6BAAA,GAAP,UAA2BlT,EAA3B;EAAA,oBAAA;;UAA6BjiB,KAAK;UAAEw0B,WAAW;EAI7C,QAAMc,WAAW,GAAG,QAApB;EACA,QAAMN,KAAK,GAAGD,YAAY,CAACQ,YAAb,CAA0Bf,WAA1B,CAAd;EACA,QAAMgB,IAAI,GAAG,KAAKH,qBAAL,EAAb;;EACA,QAAMZ,UAAU,GAAG,KAAKgB,kBAAL,CAAwBjB,WAAxB,CAAnB;;EACA,QAAMkB,QAAQ,GAAG,CAAjB;EACA,QAAMC,aAAa,GAAG,CAAtB;EACQ,QAAAC,IAAI,GAAKpB,WAAW,KAApB;EAER,QAAMqB,SAAS,GAAGP,WAAW,CAACta,KAAZ,CAAkB,EAAlB,EACf7a,GADe,CACX,UAAA21B,IAAA;EAAQ,aAAArB,UAAU,CAACO,KAAK,CAACjlB,OAAN,CAAc+lB,IAAd,CAAD,CAAV;EAA+B,KAD5B,EAEf31B,GAFe,CAEX,UAACu0B,MAAD,EAAShxB,CAAT;EACH,UAAMkxB,QAAQ,GAAG5yB,IAAI,CAAC+zB,KAAL,CAAWrB,MAAM,CAACE,QAAP,GAAkB,EAA7B,CAAjB;EACA,UAAMoB,QAAQ,GAAGtB,MAAM,CAACC,cAAP,GAAwB,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAU,CAAV,CAAxB,GAAuC,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAU,CAAV,CAAxD;;EAEA,WAAK,IAAI5lB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG/M,IAAI,CAACkF,GAAL,CAAS0tB,QAAT,CAApB,EAAwC7lB,CAAC,EAAzC,EAA6C;EAC3C,YAAK2lB,MAAM,CAACC,cAAP,IAAyBC,QAAQ,GAAG,CAArC,IACD,CAACF,MAAM,CAACC,cAAR,IAA0BC,QAAQ,GAAG,CADxC,EAC4C;EAC1CoB,UAAAA,QAAQ,CAAC/N,IAAT,CAAc+N,QAAQ,CAACC,KAAT,EAAd;EACD,SAHD,MAGO;EACLD,UAAAA,QAAQ,CAACE,OAAT,CAAiBF,QAAQ,CAACG,GAAT,EAAjB;EACD;EACF;;EAED,UAAMC,WAAW,GAAGV,QAAQ,GAAGC,aAA/B;EACA,UAAMU,UAAU,GAAGb,IAAI,CAACc,KAAL,CAAW5yB,CAAC,GAAG0yB,WAAf,EAA4B1yB,CAAC,GAAG0yB,WAAJ,GAAkBA,WAA9C,CAAnB;EACA,UAAMG,QAAQ,GAAe,EAA7B;;EAEA,WAAK,IAAIC,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGb,aAApB,EAAmCa,CAAC,EAApC,EAAwC;EACtCD,QAAAA,QAAQ,CAACP,QAAQ,CAACQ,CAAD,CAAT,CAAR,GAAwBH,UAAU,CAACI,MAAX,CAAkB,CAAlB,EAAqBf,QAArB,CAAxB;EACD;;EACD,aAAOa,QAAP;EACD,KAvBe,EAwBfp2B,GAxBe,CAwBX,UAAAu2B,KAAA;EAAS,aAAAxa,KAAI,CAACya,YAAL,CAAkB;EAAE32B,QAAAA,KAAK,OAAP;EAAS42B,QAAAA,UAAU,EAAEF,KAArB;EAA4Bd,QAAAA,IAAI;EAAhC,OAAlB,CAAA;EAAqD,KAxBnD,EAyBfptB,MAzBe,CAyBR,UAACC,GAAD,EAAgBouB,GAAhB;EAAoC,sBACvCpuB,KACAouB,GAAG,CAACruB,MAAJ,CAAW,UAACsuB,MAAD,EAASJ,KAAT;EAAmB,wBAAII,QAAWJ,MAAf;EAAqB,OAAnD,EAAqD,EAArD,EAFuC;EAG3C,KA5Be,EA4Bb,EA5Ba,CAAlB;EA8BA,WAAOb,SAAP;EACD,GA3CM;;EA6CA,+BAAA,GAAP;EACE,WAAO,oSAAP;EAUD,GAXM;;EAaA,iCAAA,GAAP;EACE,WAAO,4LAAP;EAOD,GARM;;EAUA,uBAAA,GAAP,UAAqBhkB,EAArB,EAAgD7R,KAAhD,EAA4Fw0B,WAA5F;EACE,QAAMuC,SAAS,GAAG,QAAlB;EACA,QAAM/B,KAAK,GAAGD,YAAY,CAACQ,YAAb,CAA0Bf,WAA1B,CAAd;EACA,QAAMwC,QAAQ,GAAG,EAAjB;EAEAhC,IAAAA,KAAK,CAACha,KAAN,CAAY,EAAZ,EAAgBzb,OAAhB,CAAwB,UAAC0B,CAAD,EAAIyC,CAAJ;EACtBszB,MAAAA,QAAQ,CAAC/1B,CAAD,CAAR,GAAcyC,CAAd;EACD,KAFD;;EAIA,QAAI;EACF,UAAI1D,KAAK,YAAYH,KAArB,EAA4B;EAC1B,aAAK,IAAIo3B,UAAU,GAAG,CAAtB,EAAyBA,UAAU,GAAG,CAAtC,EAAyCA,UAAU,EAAnD,EAAuD;EACrD,cAAMC,OAAO,GAAGF,QAAQ,CAACD,SAAS,CAACE,UAAD,CAAV,CAAxB;EAEA/H,UAAAA,UAAU,CAACsD,UAAX,CAAsB3gB,EAAtB,EAA0BA,EAAE,CAACslB,2BAAH,GAAiCF,UAA3D,EAAuEj3B,KAAK,CAACk3B,OAAD,CAA5E;EACD;EACF,OAND,MAMO;EACL,YAAME,qBAAqB,GAAG,KAAKC,wBAAL,CAA8BxlB,EAA9B,EAAkC7R,KAAlC,CAA9B;;EAEA,aAAK,IAAIi3B,UAAU,GAAG,CAAtB,EAAyBA,UAAU,GAAG,CAAtC,EAAyCA,UAAU,EAAnD,EAAuD;EACrD,cAAMC,OAAO,GAAGF,QAAQ,CAACD,SAAS,CAACE,UAAD,CAAV,CAAxB;EACA,cAAMK,IAAI,GAAG,KAAKC,oBAAL,CACXv3B,KADW,EACJk3B,OADI,EACKE,qBADL,CAAb;EAIAlI,UAAAA,UAAU,CAACsD,UAAX,CAAsB3gB,EAAtB,EAA0BA,EAAE,CAACslB,2BAAH,GAAiCF,UAA3D,EAAuEK,IAAvE;EACD;EACF;EACF,KAnBD,CAmBE,OAAOpa,CAAP,EAAU;EACV,WAAKsa,aAAL,CAAmBta,CAAnB;EACD;EACF,GA/BM;;EAiCA,qBAAA,GAAP,UAAmBrL,EAAnB,EAA8Cuf,OAA9C,EAAqEpxB,KAArE,EAAiHw0B,WAAjH;EACE3iB,IAAAA,EAAE,CAACyf,WAAH,CAAezf,EAAE,CAAC4lB,gBAAlB,EAAoCrG,OAApC;EACA,SAAKsG,aAAL,CAAmB7lB,EAAnB,EAAuB7R,KAAvB,EAA8Bw0B,WAA9B;EACD,GAHM;;EAKA,2BAAA,GAAP,UAAyBx0B,KAAzB;EACQ,QAAAiiB,KAAkB,KAAKmS,YAAL,CAAkBp0B,KAAlB,CAAlB;EAAA,QAAC2Q,KAAK,WAAN;EAAA,QAAQC,MAAM,YAAd;;EACN,QAAMmW,WAAW,GAAGpW,KAAK,GAAGC,MAA5B;EACA,QAAI+mB,gBAAJ;;EAEA,QAAI5Q,WAAW,KAAK,IAAI,CAAxB,EAA2B;EACzB4Q,MAAAA,gBAAgB,GAAGhnB,KAAnB;EACD,KAFD,MAEO,IAAIoW,WAAW,KAAK,CAApB,EAAuB;EAC5B4Q,MAAAA,gBAAgB,GAAG/mB,MAAnB;EACD,KAFM,MAEA,IAAImW,WAAW,KAAK,IAAI,CAAxB,EAA2B;EAChC4Q,MAAAA,gBAAgB,GAAGhnB,KAAK,GAAG,CAA3B;EACD,KAFM,MAEA;EACLgnB,MAAAA,gBAAgB,GAAGhnB,KAAK,GAAG,CAA3B;EACD;;EACD,WAAOgnB,gBAAP;EACD,GAfM;;EAiBA,8BAAA,GAAP,UAA4B33B,KAA5B,EAAwEk3B,OAAxE,EAAyFU,iBAAzF;EACS,QAAAjnB,KAAK,GAAI,KAAKyjB,YAAL,CAAkBp0B,KAAlB,OAAT;EACP,QAAM23B,gBAAgB,GAAG,KAAKE,iBAAL,CAAuB73B,KAAvB,CAAzB;EAEA,QAAM6U,MAAM,GAAG/T,QAAQ,CAACC,aAAT,CAAuB,QAAvB,CAAf;EAEA8T,IAAAA,MAAM,CAAClE,KAAP,GAAeinB,iBAAf;EACA/iB,IAAAA,MAAM,CAACjE,MAAP,GAAgBgnB,iBAAhB;EACA,QAAMnH,OAAO,GAAG5b,MAAM,CAACqc,UAAP,CAAkB,IAAlB,CAAhB;EACA,QAAM4G,UAAU,GAAGnnB,KAAK,GAAGgnB,gBAA3B;EAEA,QAAMryB,CAAC,GAAGqyB,gBAAgB,GAAGT,OAAnB,IAA8BS,gBAAgB,GAAGG,UAAjD,CAAV;EACA,QAAMvyB,CAAC,GAAGvD,IAAI,CAAC+zB,KAAL,CAAWmB,OAAO,GAAGY,UAArB,IAAoCH,gBAA9C;EAEAlH,IAAAA,OAAQ,CAAC8D,SAAT,CACEv0B,KADF,EACSsF,CADT,EACYC,CADZ,EAEEoyB,gBAFF,EAEoBA,gBAFpB,EAEsC,CAFtC,EAEyC,CAFzC,EAE4CC,iBAF5C,EAE+DA,iBAF/D;EAIA,WAAO/iB,MAAP;EACD,GAnBM;;EAqBA,kCAAA,GAAP,UAAgChD,EAAhC,EAA2D7R,KAA3D;EACE,QAAMmyB,SAAS,GAAG7vB,KAAK,EAAvB;EACA,QAAM80B,qBAAqB,GAAGvlB,EAAE,CAAC8gB,YAAH,CAAgB9gB,EAAE,CAACkmB,yBAAnB,CAA9B;EACA,QAAIC,UAAU,GAAG,KAAKH,iBAAL,CAAuB73B,KAAvB,CAAjB;;EAEA,QAAImyB,SAAS,CAACvvB,OAAV,CAAkBF,IAAlB,KAA2B,IAA3B,IAAmCyvB,SAAS,CAACvvB,OAAV,CAAkBkwB,YAAlB,KAAmC,EAA1E,EAA8E;EAC5E,UAAI,CAACtG,IAAQ,CAACznB,YAAT,CAAsBizB,UAAtB,CAAL,EAAwC;EACtC,aAAK,IAAIt0B,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAG0zB,qBAApB,EAA2C1zB,CAAC,IAAI,CAAhD,EAAmD;EACjD,cAAIA,CAAC,GAAGs0B,UAAR,EAAoB;EAClB;EACD,WAFD,MAEO;EACLA,YAAAA,UAAU,GAAGt0B,CAAb;EACA;EACD;EACF;EACF;EACF;;EACD,QAAIyuB,SAAS,CAAC1vB,EAAV,CAAaC,IAAb,KAAsB,KAA1B,EAAiC;EAC/B,UAAMowB,YAAY,GAAGX,SAAS,CAAC1vB,EAAV,CAAaqwB,YAAlC,CAD+B;;EAI/B,UAAIA,YAAY,KAAK,CAArB,EAAwB;EACtBkF,QAAAA,UAAU,GAAG,IAAb;EACD,OAN8B;;;EAQ/B,UAAIlF,YAAY,KAAK,CAArB,EAAwB;EACtBkF,QAAAA,UAAU,GAAG,GAAb;EACD;EACF;;;EAED,WAAOh2B,IAAI,CAACyN,GAAL,CAAS2nB,qBAAT,EAAgCY,UAAhC,CAAP;EACD,GA/BM;;EAiCC,sBAAA,GAAR,UAAqBC,SAArB;EAKU,QAAAj4B,KAAK,GAAuBi4B,SAAS,MAArC;EAAA,QAAOrB,UAAU,GAAWqB,SAAS,WAArC;EAAA,QAAmBrC,IAAI,GAAKqC,SAAS,KAArC;EAER,QAAMN,gBAAgB,GAAG93B,KAAK,CAACC,OAAN,CAAcE,KAAd,IACrB,KAAKo0B,YAAL,CAAkBp0B,KAAK,CAAC,CAAD,CAAvB,EAA4B2Q,KADP,GAErB,KAAKknB,iBAAL,CAAuB73B,KAAvB,CAFJ;;EAKA,QAAMk4B,iBAAiB,GAAG,IAAItC,IAAI,IAAI,IAAI+B,gBAAR,CAAlC;EAEA,QAAMQ,eAAe,GAAG,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAUh4B,GAAV,CAAc,UAAAi4B,SAAA;EACpC,UAAMC,OAAO,GAAG7L,IAAQ,CAACpkB,IAAT,CAAcwuB,UAAU,CAAC,CAAD,CAAV,CAAcwB,SAAd,CAAd,CAAhB;EACA,UAAME,UAAU,GAAG1B,UAAU,CAAChM,IAAX,CAAgB,UAAA8L,KAAA;EAAS,eAAAlK,IAAQ,CAACpkB,IAAT,CAAcsuB,KAAK,CAAC0B,SAAD,CAAnB,MAAoCC,OAApC;EAA2C,OAApE,CAAnB;EAEA,aAAOC,UAAP;EACD,KALuB,EAKrBn4B,GALqB,CAKjB,UAAAm4B,UAAA;EAAc,aAAAA,UAAU,GAAGJ,iBAAH,GAAuB,CAAjC;EAAkC,KAL/B,CAAxB;EAOA,WAAOtB,UAAU,CAACz2B,GAAX,CAAe,UAAA22B,MAAA;EAAU,aAAAA,MAAM,CAAC32B,GAAP,CAAW,UAACu2B,KAAD,EAAQ0B,SAAR;EAAsB,eAAA1B,KAAK,GAAGyB,eAAe,CAACC,SAAD,CAAvB;EAAkC,OAAnE,CAAA;EAAoE,KAA7F,CAAP;EACD,GAtBO;;EAtPOrD,EAAAA,kCAAA,GAAyC,IAAzC;EACAA,EAAAA,wBAAA,GAA+B,IAA/B;EA4QjB,qBAAA;EAAC,EAlR0BD,SAA3B;;ECFA;;;EAA+C9Y,EAAAA,oCAAA;;EAA/C,4BAAA;;EA4QC;;;;EAzQQ,+BAAA,GAAP;EACE,WAAO,kRAAP;EAUD,GAXM;;EAaA,iCAAA,GAAP;EACE,WAAO,8qEAAP;EAyDD,GA1DM;;EA4DA,+BAAA,GAAP;EACE,QAAI,CAAC,KAAKuc,SAAV,EAAqB;EACnB,WAAKA,SAAL,GAAiB;EAEf,OAFe,EAEZ,CAAC,CAFW,EAER,CAFQ,EAGf,CAAC,CAHc,EAGX,CAAC,CAHU,EAGP,CAHO,EAIf,CAAC,CAJc,EAIX,CAJW,EAIR,CAJQ,EAKf,CALe,EAKZ,CALY,EAKT,CALS;EAQf,OAAC,CARc,EAQX,CAAC,CARU,EAQP,CAAC,CARM,EASf,CATe,EASZ,CAAC,CATW,EASR,CAAC,CATO,EAUf,CAVe,EAUZ,CAVY,EAUT,CAAC,CAVQ,EAWf,CAAC,CAXc,EAWX,CAXW,EAWR,CAAC,CAXO;EAcf,OAAC,CAdc,EAcX,CAdW,EAcR,CAAC,CAdO,EAef,CAfe,EAeZ,CAfY,EAeT,CAAC,CAfQ,EAgBf,CAhBe,EAgBZ,CAhBY,EAgBT,CAhBS,EAiBf,CAAC,CAjBc,EAiBX,CAjBW,EAiBR,CAjBQ;EAoBf,OAAC,CApBc,EAoBX,CAAC,CApBU,EAoBP,CApBO,EAqBf,CArBe,EAqBZ,CAAC,CArBW,EAqBR,CArBQ,EAsBf,CAtBe,EAsBZ,CAAC,CAtBW,EAsBR,CAAC,CAtBO,EAuBf,CAAC,CAvBc,EAuBX,CAAC,CAvBU,EAuBP,CAAC,CAvBM;EA0Bf,OA1Be,EA0BZ,CAAC,CA1BW,EA0BR,CAAC,CA1BO,EA2Bf,CA3Be,EA2BZ,CAAC,CA3BW,EA2BR,CA3BQ,EA4Bf,CA5Be,EA4BZ,CA5BY,EA4BT,CA5BS,EA6Bf,CA7Be,EA6BZ,CA7BY,EA6BT,CAAC,CA7BQ;EAgCf,OAAC,CAhCc,EAgCX,CAAC,CAhCU,EAgCP,CAhCO,EAiCf,CAAC,CAjCc,EAiCX,CAAC,CAjCU,EAiCP,CAAC,CAjCM,EAkCf,CAAC,CAlCc,EAkCX,CAlCW,EAkCR,CAAC,CAlCO,EAmCf,CAAC,CAnCc,EAmCX,CAnCW,EAmCR,CAnCQ,CAAjB;EAqCD;;EAED,WAAO,KAAKA,SAAZ;EACD,GA1CM;;EA4CA,sBAAA,GAAP;EAAA,oBAAA;;;EAEE,QAAMC,OAAO,GAAI;EACf,UAAMrD,SAAS,GAAa,EAA5B;;EAEA,WAAK,IAAIzxB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAIwY,KAAI,CAACqc,SAAL,CAAe93B,MAAf,GAAwB,CAA7C,EAAiDiD,CAAC,IAAI,CAAtD,EAAyD;EACvDyxB,QAAAA,SAAS,CAAClN,IAAV,CACEvkB,CADF,EAEEA,CAAC,GAAG,CAFN,EAGEA,CAAC,GAAG,CAHN,EAIEA,CAJF,EAKEA,CAAC,GAAG,CALN,EAMEA,CAAC,GAAG,CANN;EAQD;;EACD,aAAOyxB,SAAP;EACD,KAde,EAAhB;;EAgBA,WAAOqD,OAAP;EACD,GAnBM;;EAqBA,6BAAA,GAAP,UAA2BvW,EAA3B;EAAA,oBAAA;;UAA6BjiB,KAAK;UAAEw0B,WAAW;;EAK7C,QAAMiE,IAAI,GAAG,CAAb;EACA,QAAMC,IAAI,GAAG,CAAb;EAEA,QAAMC,WAAW,GAAG,KAAKvE,YAAL,CAAkBp0B,KAAlB,CAApB;EACQ,QAAA41B,IAAI,GAAKpB,WAAW,KAApB;EAER,QAAMQ,KAAK,GAAGR,WAAW,CAACQ,KAAZ,IAAqB,QAAnC;EACA,QAAI8B,MAAM,GAAe,EAAzB;;EAGA,SAAK,IAAI/nB,CAAC,GAAG2pB,IAAI,GAAG,CAApB,EAAuB3pB,CAAC,IAAI,CAA5B,EAA+BA,CAAC,EAAhC,EAAoC;EAClC,WAAK,IAAI6pB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGH,IAApB,EAA0BG,CAAC,EAA3B,EAA+B;EAC7B,YAAMlC,KAAK,GAAG,CACZkC,CAAC,GAAGH,IADQ,EACF1pB,CAAC,GAAG2pB,IADF,EAEZ,CAACE,CAAC,GAAG,CAAL,IAAUH,IAFE,EAEI1pB,CAAC,GAAG2pB,IAFR,EAGZ,CAACE,CAAC,GAAG,CAAL,IAAUH,IAHE,EAGI,CAAC1pB,CAAC,GAAG,CAAL,IAAU2pB,IAHd,EAIZE,CAAC,GAAGH,IAJQ,EAIF,CAAC1pB,CAAC,GAAG,CAAL,IAAU2pB,IAJR,CAAd;EAOA5B,QAAAA,MAAM,CAAC7O,IAAP,CAAYyO,KAAZ;EACD;EACF;;EAED,QAAMmC,WAAW,GAAG,KAAKpD,kBAAL,CAAwBjB,WAAxB,CAApB;;;EAGAsC,IAAAA,MAAM,GAAGA,MAAM;EAAA,KAEZ32B,GAFM,CAEF,UAAAu2B,KAAA;EAAS,aAAAxa,KAAI,CAACya,YAAL,CAAkBD,KAAlB,EAAyBiC,WAAzB,EAAsC/C,IAAtC,CAAA;EAA2C,KAFlD,EAGNz1B,GAHM,CAGF,UAACu2B,KAAD,EAAQhzB,CAAR;EAAc,aAAAwY,KAAI,CAAC4c,eAAL,CAAqBpC,KAArB,EAA4BmC,WAAW,CAACn1B,CAAD,CAAvC,CAAA;EAA2C,KAHvD,CAAT;;EAMA,WAAO,SAASsX,KAAT,CAAe,EAAf,EACJ7a,GADI,CACA,UAAA21B,IAAA;EAAQ,aAAAd,KAAK,CAACjlB,OAAN,CAAc+lB,IAAd,CAAA;EAAmB,KAD3B,EAEJ31B,GAFI,CAEA,UAAA44B,KAAA;EAAS,aAAAjC,MAAM,CAACiC,KAAD,CAAN;EAAa,KAFtB,EAGJvwB,MAHI,CAGG,UAACC,GAAD,EAAMouB,GAAN;EAAc,aAAApuB,GAAG,CAAC4jB,MAAJ,CAAWwK,GAAX,CAAA;EAAe,KAHhC,EAGkC,EAHlC,CAAP;EAID,GAzCM;;EA2CA,uBAAA,GAAP,UAAqBhlB,EAArB,EAAgD7R,KAAhD;EACEkvB,IAAAA,UAAU,CAACsD,UAAX,CAAsB3gB,EAAtB,EAA0BA,EAAE,CAACmnB,UAA7B,EAAyC,KAAKC,eAAL,CAAqBj5B,KAArB,CAAzC;EACD,GAFM;;EAIA,qBAAA,GAAP,UAAmB6R,EAAnB,EAA8Cuf,OAA9C,EAAqEpxB,KAArE;EACE;EACM,QAAAiiB,KAAkB,KAAKmS,YAAL,CAAkBp0B,KAAlB,CAAlB;EAAA,QAAC2Q,KAAK,WAAN;EAAA,QAAQC,MAAM,YAAd;;EACN,QAAMsoB,IAAI,GAAGl3B,IAAI,CAAC0N,GAAL,CAASiB,KAAT,EAAgBC,MAAhB,CAAb;EACA,QAAMuoB,OAAO,GAAGjK,UAAU,CAACkK,iBAAX,CAA6BvnB,EAA7B,CAAhB;;EAEA,QAAIqnB,IAAI,GAAGC,OAAX,EAAoB;EAClB,WAAK3B,aAAL,CAAmB,iBAAe7mB,KAAf,4BAAA,GAA8CwoB,OAA9C,OAAnB;;EACA;EACD;;;EAGD,SAAKE,gBAAL,CAAsBr5B,KAAtB;;EAEA6R,IAAAA,EAAE,CAACynB,aAAH,CAAiBznB,EAAE,CAAC0nB,QAApB;EACA1nB,IAAAA,EAAE,CAAC2nB,WAAH,CAAe3nB,EAAE,CAAC4nB,mBAAlB,EAAuC,IAAvC;EACA5nB,IAAAA,EAAE,CAACyf,WAAH,CAAezf,EAAE,CAACmnB,UAAlB,EAA8B5H,OAA9B;EAEA,SAAKsG,aAAL,CAAmB7lB,EAAnB,EAAuB7R,KAAvB;EACD,GAnBM;;EAqBC,yBAAA,GAAR,UAAwB02B,KAAxB,EAAyCjC,UAAzC;EACE,QAAIiF,QAAQ,GAAGhD,KAAK,CAACJ,KAAN,EAAf;;EAEA,QAAI7B,UAAU,CAACE,cAAf,EAA+B;EAC7B+E,MAAAA,QAAQ,GAAG,KAAKC,oBAAL,CAA0BD,QAA1B,CAAX;EACD;;EAED,QAAIjF,UAAU,CAACG,QAAf,EAAyB;EACvB8E,MAAAA,QAAQ,GAAG,KAAKE,YAAL,CAAkBF,QAAlB,EAA4BjF,UAAU,CAACG,QAAvC,CAAX;EACD;;EAED,WAAO8E,QAAP;EACD,GAZO;;EAcA,sBAAA,GAAR,UAAqBhD,KAArB,EAAsCiC,WAAtC,EAAsF/C,IAAtF;EACU,QAAAjlB,KAAK,GAAagoB,WAAW,MAA7B;EAAA,QAAO/nB,MAAM,GAAK+nB,WAAW,OAA7B;;EAGR,QAAMkB,QAAQ,GAAGjE,IAAI,IAAI,IAAIhlB,MAAR,CAArB;EACA,QAAMkpB,QAAQ,GAAGlE,IAAI,IAAI,IAAIjlB,KAAR,CAArB;EAEA,WAAO,CACL+lB,KAAK,CAAC,CAAD,CAAL,GAAWoD,QADN,EACgBpD,KAAK,CAAC,CAAD,CAAL,GAAWmD,QAD3B,EAELnD,KAAK,CAAC,CAAD,CAAL,GAAWoD,QAFN,EAEgBpD,KAAK,CAAC,CAAD,CAAL,GAAWmD,QAF3B,EAGLnD,KAAK,CAAC,CAAD,CAAL,GAAWoD,QAHN,EAGgBpD,KAAK,CAAC,CAAD,CAAL,GAAWmD,QAH3B,EAILnD,KAAK,CAAC,CAAD,CAAL,GAAWoD,QAJN,EAIgBpD,KAAK,CAAC,CAAD,CAAL,GAAWmD,QAJ3B,CAAP;EAMD,GAbO;;EAeA,sBAAA,GAAR,UAAqBnD,KAArB,EAAsCqD,aAAtC;EACE,QAAMC,IAAI,GAAG,CAAb;;EACA,QAAMC,UAAU,GAAGj4B,IAAI,CAAC+zB,KAAL,CAAWgE,aAAa,GAAG,EAA3B,IAAiC,CAApD;;EAEA,QAAIE,UAAU,KAAK,CAAnB,EAAsB;EACpB,aAAOvD,KAAP;EACD;;EAED,QAAIwD,KAAJ;EACA,QAAIC,YAAY,GAAa,EAA7B;;EAEA,QAAIF,UAAU,GAAG,CAAjB,EAAoB;EAClBC,MAAAA,KAAK,GAAGxD,KAAK,CAACD,MAAN,CAAa,CAAb,EAAgBwD,UAAU,GAAGD,IAA7B,CAAR;EACAG,MAAAA,YAAY,GAAGzD,KAAK,CAACrK,MAAN,CAAa6N,KAAb,CAAf;EACD,KAHD,MAGO;EACLA,MAAAA,KAAK,GAAGxD,KAAK,CAACD,MAAN,CAAa,CAAC,IAAIwD,UAAL,IAAmBD,IAAhC,EAAsC,CAACC,UAAD,GAAcD,IAApD,CAAR;EACAG,MAAAA,YAAY,GAAGD,KAAK,CAAC7N,MAAN,CAAaqK,KAAb,CAAf;EACD;;EAED,WAAOyD,YAAP;EACD,GApBO;;EAsBA,8BAAA,GAAR,UAA6BzD,KAA7B;EACE,WAAO,CACLA,KAAK,CAAC,CAAD,CADA,EACKA,KAAK,CAAC,CAAD,CADV,EAELA,KAAK,CAAC,CAAD,CAFA,EAEKA,KAAK,CAAC,CAAD,CAFV,EAGLA,KAAK,CAAC,CAAD,CAHA,EAGKA,KAAK,CAAC,CAAD,CAHV,EAILA,KAAK,CAAC,CAAD,CAJA,EAIKA,KAAK,CAAC,CAAD,CAJV,CAAP;EAMD,GAPO;;EAQV,0BAAA;EA5QA,EAA+C5B,SAA/C;;ECAA,IAAMsF,aAAa,GAAG,EAAtB;EACA,IAAMC,cAAc,GAAG,EAAvB;EACA,IAAMC,MAAM,GAAG,CAAf;EACA,IAAMC,iCAAiC,GAAG,CAAC,GAAD,GAAOv4B,IAAI,CAAC6C,EAAtD;EAEA,IAAM21B,gBAAgB,GAAa,EAAnC;EACA,IAAMpF,kBAAkB,GAAa,EAArC;EACA,IAAMD,SAAS,GAAa,EAA5B;EACA,IAAIsF,MAAJ;EACA,IAAIC,MAAJ;;EAEA,KAAKD,MAAM,GAAG,CAAd,EAAiBA,MAAM,IAAIL,aAA3B,EAA0CK,MAAM,EAAhD,EAAoD;EAClD,MAAMpzB,KAAK,GAAG,CAACozB,MAAM,GAAGL,aAAT,GAAyB,GAA1B,IAAiCp4B,IAAI,CAAC6C,EAApD;EACA,MAAM4gB,QAAQ,GAAGzjB,IAAI,CAACiL,GAAL,CAAS5F,KAAT,CAAjB;EACA,MAAMme,QAAQ,GAAGxjB,IAAI,CAAC6K,GAAL,CAASxF,KAAT,CAAjB;;EAEA,OAAKqzB,MAAM,GAAG,CAAd,EAAiBA,MAAM,IAAIL,cAA3B,EAA2CK,MAAM,EAAjD,EAAqD;EACnD,QAAMC,GAAG,GAAG,CAACD,MAAM,GAAGL,cAAT,GAA0B,GAA3B,IAAkC,CAAlC,GAAsCr4B,IAAI,CAAC6C,EAA3C,GAAgD01B,iCAA5D;EACA,QAAMK,MAAM,GAAG54B,IAAI,CAACiL,GAAL,CAAS0tB,GAAT,CAAf;EACA,QAAME,MAAM,GAAG74B,IAAI,CAAC6K,GAAL,CAAS8tB,GAAT,CAAf;EACA,QAAMr1B,CAAC,GAAGu1B,MAAM,GAAGrV,QAAnB;EACA,QAAMjgB,CAAC,GAAGkgB,QAAV;EACA,QAAMxa,CAAC,GAAG2vB,MAAM,GAAGpV,QAAnB;EACA,QAAMsV,CAAC,GAAGJ,MAAM,GAAGL,cAAnB;EACA,QAAMp5B,CAAC,GAAGw5B,MAAM,GAAGL,aAAnB;EAEAI,IAAAA,gBAAgB,CAACvS,IAAjB,CAAsB6S,CAAtB,EAAyB75B,CAAzB;EACAm0B,IAAAA,kBAAkB,CAACnN,IAAnB,CAAwBqS,MAAM,GAAGh1B,CAAjC,EAAoCg1B,MAAM,GAAG/0B,CAA7C,EAAgD+0B,MAAM,GAAGrvB,CAAzD;;EAEA,QAAIyvB,MAAM,KAAKL,cAAX,IAA6BI,MAAM,KAAKL,aAA5C,EAA2D;EACzD,UAAMx1B,CAAC,GAAG61B,MAAM,IAAIJ,cAAc,GAAG,CAArB,CAAN,GAAgCK,MAA1C;EACA,UAAM3vB,CAAC,GAAGnG,CAAC,GAAGy1B,cAAJ,GAAqB,CAA/B;EAEAlF,MAAAA,SAAS,CAAClN,IAAV,CAAerjB,CAAf,EAAkBmG,CAAlB,EAAqBnG,CAAC,GAAG,CAAzB,EAA4BmG,CAA5B,EAA+BA,CAAC,GAAG,CAAnC,EAAsCnG,CAAC,GAAG,CAA1C;EACD;EACF;EACF;;EAED;;;EAA6BoX,EAAAA,iCAAA;;EAO3B,yBAAA,CAAmB+e,MAAnB;EAAA,gBACE9e,WAAA,KAAA,SADF;;EAGEC,IAAAA,KAAI,CAAC8e,aAAL,GAAqBD,MAArB;;EACD;;;;EAEM,gBAAA,GAAP,UAAcE,GAAd;EACS,QAAAppB,EAAE,GAAmBopB,GAAG,GAAxB;EAAA,QAAI9H,aAAa,GAAI8H,GAAG,cAAxB;EAEP,QAAIC,kBAAJ;EACA,QAAIC,mBAAJ;;EAEA,YAAQ,KAAKH,aAAb;EACE,WAAKzM,aAAa,CAACC,UAAnB;EACE0M,QAAAA,kBAAkB,GAAG,CAAC,CAAD,EAAI,GAAJ,EAAS,CAAT,EAAY,CAAZ,CAArB;EACAC,QAAAA,mBAAmB,GAAG,CAAC,CAAD,EAAI,GAAJ,EAAS,CAAT,EAAY,GAAZ,CAAtB;EACA;;EACF,WAAK5M,aAAa,CAACE,UAAnB;EACEyM,QAAAA,kBAAkB,GAAG,CAAC,GAAD,EAAM,CAAN,EAAS,CAAT,EAAY,CAAZ,CAArB;EACAC,QAAAA,mBAAmB,GAAG,CAAC,GAAD,EAAM,CAAN,EAAS,GAAT,EAAc,CAAd,CAAtB;EACA;;EACF;EACED,QAAAA,kBAAkB,GAAG,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAU,CAAV,CAArB;EACAC,QAAAA,mBAAmB,GAAG,CAAC,CAAD,EAAI,CAAJ,EAAO,CAAP,EAAU,CAAV,CAAtB;EAXJ;;EAcA,QAAMC,eAAe,GAAGvpB,EAAE,CAAC0B,kBAAH,CAAsB4f,aAAtB,EAAqC,iBAArC,CAAxB;EAEAthB,IAAAA,EAAE,CAACwpB,UAAH,CAAcD,eAAd,WAAmCF,oBAAuBC,oBAA1D;;EAEAlf,IAAAA,gBAAA,CAAMqf,MAAN,KAAA,KAAA,EAAaL,GAAb;EACD,GAzBM;;EA2BA,+BAAA,GAAP;EACE,WAAOM,cAAc,CAACtG,qBAAtB;EACD,GAFM;;EAIA,sBAAA,GAAP;EACE,WAAOsG,cAAc,CAACrG,WAAtB;EACD,GAFM;;EAIA,6BAAA,GAAP;EACE,WAAOqG,cAAc,CAACC,mBAAtB;EACD,GAFM;;EAIA,+BAAA,GAAP;EACE,WAAO,gaAAP;EAaD,GAdM;;EAgBA,iCAAA,GAAP;EACE,WAAO,yKAAP;EAOD,GARM;;EAUA,uBAAA,GAAP,UAAqB3pB,EAArB,EAAgD7R,KAAhD;EACEkvB,IAAAA,UAAU,CAACsD,UAAX,CAAsB3gB,EAAtB,EAA0BA,EAAE,CAACmnB,UAA7B,EAAyC,KAAKC,eAAL,CAAqBj5B,KAArB,CAAzC;EACD,GAFM;;EAIA,qBAAA,GAAP,UAAmB6R,EAAnB,EAA8Cuf,OAA9C,EAAqEpxB,KAArE;EACE;EACM,QAAAiiB,KAAoB,KAAKmS,YAAL,CAAkBp0B,KAAlB,CAApB;EAAA,QAAE2Q,KAAK,WAAP;EAAA,QAASC,MAAM,YAAf;;EACN,QAAMsoB,IAAI,GAAGl3B,IAAI,CAAC0N,GAAL,CAASiB,KAAT,EAAgBC,MAAhB,CAAb;EACA,QAAMuoB,OAAO,GAAGjK,UAAU,CAACkK,iBAAX,CAA6BvnB,EAA7B,CAAhB;;EAEA,QAAIqnB,IAAI,GAAGC,OAAX,EAAoB;EAClB,WAAK3B,aAAL,CAAmB,iBAAe7mB,KAAf,4BAAA,GAA8CwoB,OAA9C,OAAnB;;EACA;EACD;;;EAGD,SAAKE,gBAAL,CAAsBr5B,KAAtB;;EAEA6R,IAAAA,EAAE,CAACynB,aAAH,CAAiBznB,EAAE,CAAC0nB,QAApB;EACA1nB,IAAAA,EAAE,CAAC2nB,WAAH,CAAe3nB,EAAE,CAAC4nB,mBAAlB,EAAuC,IAAvC;EACA5nB,IAAAA,EAAE,CAACyf,WAAH,CAAezf,EAAE,CAACmnB,UAAlB,EAA8B5H,OAA9B;EAEA,SAAKsG,aAAL,CAAmB7lB,EAAnB,EAAuB7R,KAAvB;EACD,GAnBM;;EAjFQu7B,EAAAA,oCAAA,GAAwBnG,kBAAxB;EACAmG,EAAAA,kCAAA,GAAsBf,gBAAtB;EACAe,EAAAA,0BAAA,GAAcpG,SAAd;EAmGjB,uBAAA;EAAC,EAtG4BL,SAA7B;;ECrCA,IAAM2G,kCAAkC,GAAG,CAA3C;EACA,IAAMpB,gBAAc,GAAG,EAAvB;EAEA,IAAMG,kBAAgB,GAAa,EAAnC;EACA,IAAMpF,oBAAkB,GAAa,EAArC;EACA,IAAMD,WAAS,GAAa,EAA5B;;EAEA;;;EAA+BnZ,EAAAA,mCAAA;;EAA/B,2BAAA;;EA+IC;;;;EA1IQ,+BAAA,GAAP;EACE,WAAO0f,gBAAgB,CAACzG,qBAAxB;EACD,GAFM;;EAIA,sBAAA,GAAP;EACE,WAAOyG,gBAAgB,CAACxG,WAAxB;EACD,GAFM;;EAIA,6BAAA,GAAP;EACE,WAAOwG,gBAAgB,CAACF,mBAAxB;EACD,GAFM;;EAIA,+BAAA,GAAP;EACE,WAAO,kRAAP;EAUD,GAXM;;EAaA,iCAAA,GAAP;EACE,WAAO,+LAAP;EAOD,GARM;;EAUA,uBAAA,GAAP,UAAqB3pB,EAArB,EAAgD7R,KAAhD;EACEkvB,IAAAA,UAAU,CAACsD,UAAX,CAAsB3gB,EAAtB,EAA0BA,EAAE,CAACmnB,UAA7B,EAAyC,KAAKC,eAAL,CAAqBj5B,KAArB,CAAzC;EACD,GAFM;;EAIA,qBAAA,GAAP,UAAmB6R,EAAnB,EAA8Cuf,OAA9C,EAAqEpxB,KAArE;EACE;EACM,QAAAiiB,KAAkB,KAAKmS,YAAL,CAAkBp0B,KAAlB,CAAlB;EAAA,QAAC2Q,KAAK,WAAN;EAAA,QAAQC,MAAM,YAAd;;EACN,QAAMsoB,IAAI,GAAGl3B,IAAI,CAAC0N,GAAL,CAASiB,KAAT,EAAgBC,MAAhB,CAAb;EACA,QAAMuoB,OAAO,GAAGjK,UAAU,CAACkK,iBAAX,CAA6BvnB,EAA7B,CAAhB;EACA,QAAI8pB,eAAJ;;EAEA,QAAIzC,IAAI,GAAGC,OAAX,EAAoB;EAClB,WAAK3B,aAAL,CAAmB,iBAAe7mB,KAAf,oCAAA,GAAsDwoB,OAAtD,OAAnB,EADkB;;EAIlB;;;;;EAGAwC,MAAAA,eAAe,GAAGhrB,KAAK,GAAGC,MAAR,GAChB;EAACD,QAAAA,KAAK,EAAEwoB,OAAR;EAAiBvoB,QAAAA,MAAM,EAAEuoB,OAAO,GAAGvoB,MAAV,GAAmBD;EAA5C,OADgB,GAEhB;EAACA,QAAAA,KAAK,EAAEwoB,OAAO,GAAGxoB,KAAV,GAAkBC,MAA1B;EAAkCA,QAAAA,MAAM,EAAEuoB;EAA1C,OAFF;EAGD;;;EAGD,SAAKE,gBAAL,CAAsBr5B,KAAtB,EAA6B27B,eAA7B;;EAEA9pB,IAAAA,EAAE,CAACynB,aAAH,CAAiBznB,EAAE,CAAC0nB,QAApB;EACA1nB,IAAAA,EAAE,CAAC2nB,WAAH,CAAe3nB,EAAE,CAAC4nB,mBAAlB,EAAuC,IAAvC;EACA5nB,IAAAA,EAAE,CAACyf,WAAH,CAAezf,EAAE,CAACmnB,UAAlB,EAA8B5H,OAA9B;EAEA,SAAKsG,aAAL,CAAmB7lB,EAAnB,EAAuB7R,KAAvB;EACD,GA3BM;;EA6BA,0BAAA,GAAP,UAAwBiiB,EAAxB;UAA0B2Z;UAAAC,gBAAgB,mBAAGJ;EAC3C,QAAIf,MAAJ;EACA,QAAIoB,iBAAJ;EACA,QAAIC,aAAJ;EACA,QAAIC,OAAJ;EACA,QAAIjV,WAAJ;;EAGA,QAAI8U,gBAAgB,GAAG,CAAvB,EAA0B;EACxB;;;;EAIAG,MAAAA,OAAO,GAAG,IAAV;EACAjV,MAAAA,WAAW,GAAG,IAAI8U,gBAAlB;EACD,KAPD,MAOO;EACLG,MAAAA,OAAO,GAAG,KAAV;EACAjV,MAAAA,WAAW,GAAG8U,gBAAd;EACD;;EAED,QAAI9U,WAAW,IAAI0U,kCAAnB,EAAuD;EACrD,UAAM5lB,GAAG,GAAG,MAAMkR,WAAlB;EAEA+U,MAAAA,iBAAiB,GAAG,IAAI95B,IAAI,CAAC6C,EAA7B,CAHqD;;EAIrDk3B,MAAAA,aAAa,GAAG/5B,IAAI,CAAC+T,GAAL,CAASqO,QAAA,CAAkBvO,GAAG,GAAG,CAAxB,CAAT,CAAhB;EACD,KALD,MAKO;EACLimB,MAAAA,iBAAiB,GAAG/U,WAApB;EACAgV,MAAAA,aAAa,GAAG,GAAhB,CAFK;EAGN;;;EAGDvB,IAAAA,kBAAgB,CAAC/5B,MAAjB,GAA0B,CAA1B;EACA20B,IAAAA,oBAAkB,CAAC30B,MAAnB,GAA4B,CAA5B;EACA00B,IAAAA,WAAS,CAAC10B,MAAV,GAAmB,CAAnB;EAEA,QAAMw7B,SAAS,GAAG,CAAC,CAACF,aAAF,EAAiBA,aAAjB,CAAlB;EACA,QAAMG,wBAAwB,GAAGl6B,IAAI,CAAC6C,EAAL,GAAU,CAAV,GAAc,CAAC,IAAI7C,IAAI,CAAC6C,EAAT,GAAci3B,iBAAf,IAAoC,CAAnF;EAEA;;EACA,SAAK,IAAIK,IAAI,GAAG,CAAX,EAAcC,OAAO,GAAGH,SAAS,CAACx7B,MAAvC,EAA+C07B,IAAI,GAAGC;EAAO;EAA7D,MAAiFD,IAAI,EAArF,EAAyF;EACvF,WAAKzB,MAAM,GAAG,CAAd,EAAiBA,MAAM,IAAIL,gBAA3B,EAA2CK,MAAM,EAAjD,EAAqD;EACnD,YAAMntB,KAAK,GAAG2uB,wBAAwB,GAAIxB,MAAM,GAAGL,gBAAT,GAA0ByB,iBAApE;EACA,YAAMx2B,CAAC,GAAGtD,IAAI,CAAC6K,GAAL,CAASU,KAAT,CAAV;EACA,YAAMhI,CAAC,GAAG02B,SAAS,CAACE,IAAD,CAAnB;EACA,YAAMlxB,CAAC,GAAGjJ,IAAI,CAACiL,GAAL,CAASM,KAAT,CAAV;EACA,YAAIutB,CAAC,SAAL;EACA,YAAI75B,CAAC,SAAL;;EAEA,YAAI+6B,OAAJ,EAAa;EACX;EACAlB,UAAAA,CAAC,GAAG,IAAIqB,IAAR,CAFW;;EAGXl7B,UAAAA,CAAC,GAAGy5B,MAAM,GAAGL,gBAAb;EACD,SAJD,MAIO;EACP;EACES,UAAAA,CAAC,GAAGJ,MAAM,GAAGL,gBAAb;EACAp5B,UAAAA,CAAC,GAAGk7B,IAAJ;EACD;;EAED3B,QAAAA,kBAAgB,CAACvS,IAAjB,CAAsB6S,CAAtB,EAAyB75B,CAAzB;EACAm0B,QAAAA,oBAAkB,CAACnN,IAAnB,CAAwB3iB,CAAxB,EAA2BC,CAA3B,EAA8B0F,CAA9B;;EAEA,YAAIkxB,IAAI,KAAK,CAAT,IAAczB,MAAM,GAAGL,gBAA3B,EAA2C;EACzC,cAAMz1B,CAAC,GAAG81B,MAAV;EACA,cAAM3vB,CAAC,GAAGnG,CAAC,GAAGy1B,gBAAJ,GAAqB,CAA/B;EAEAlF,UAAAA,WAAS,CAAClN,IAAV,CAAerjB,CAAf,EAAkBmG,CAAlB,EAAqBnG,CAAC,GAAG,CAAzB,EAA4BmG,CAA5B,EAA+BA,CAAC,GAAG,CAAnC,EAAsCnG,CAAC,GAAG,CAA1C;EACD;EACF;EACF;EACF,GArEM;;EAxEQ82B,EAAAA,sCAAA,GAAwBtG,oBAAxB;EACAsG,EAAAA,oCAAA,GAAsBlB,kBAAtB;EACAkB,EAAAA,4BAAA,GAAcvG,WAAd;EA4IjB,yBAAA;EAAC,EA/I8BL,SAA/B;;ECXA,IAAMuH,yBAAyB,GAAG,wBAAlC;EACA,IAAMC,mBAAmB,GAAG,CAAC,CAAD,EAAI,CAAJ,EAAO,GAAP,EAAY,CAAZ,CAA5B;EACA,IAAMC,oBAAoB,GAAG,CAAC,GAAD,EAAM,CAAN,EAAS,GAAT,EAAc,CAAd,CAA7B;EACA,IAAMC,IAAI,GAAG;EACXC,EAAAA,IAAI,EAAE,MADK;EAEXC,EAAAA,KAAK,EAAE;EAFI,CAAb;;EAKA;;;EAOE,oBAAA;EAAA,oBAAA;;EAOO,gBAAA,GAAU;EACf,UAAM/iB,SAAS,GAAGuC,KAAI,CAACygB,UAAvB;;EAEAzgB,MAAAA,KAAI,CAAC0gB,iBAAL,CAAuB1gB,KAAI,CAACwH,OAA5B;;EAEA,UAAI/J,SAAS,IAAIA,SAAS,CAACkjB,YAA3B,EAAyC;EACvC,aAAKljB,SAAS,CAACmjB,WAAV,EAAL;EACD;;EAED5gB,MAAAA,KAAI,CAAC6gB,MAAL;EACD,KAVM;;EANL,SAAKC,UAAL,GAAkB,IAAIj7B,MAAM,CAACk7B,WAAX,EAAlB;;EACA,SAAKF,MAAL;EACD;;;EAEDt9B,EAAAA,qBAAA,mBAAA;WAAA;EAAuB,aAAO,KAAKk9B,UAAZ;EAAyB;;;KAAhD;;EAcO,mBAAA,GAAP;EACE,WAAOO,OAAO,CAAC,KAAKP,UAAN,CAAd;EACD,GAFM;;EAIA,sBAAA,GAAP,UAAoB9qB,EAApB;EACE;EACAA,IAAAA,EAAE,CAACsrB,eAAH,CAAmBtrB,EAAE,CAACurB,WAAtB,EAAmC,IAAnC;EACD,GAHM;;EAKA,qBAAA,GAAP;EACE,SAAKT,UAAL,CAAiBU,WAAjB;EACD,GAFM;;EAIA,sBAAA,GAAP,UAAoBxrB,EAApB;EACE,QAAMyrB,OAAO,GAAG,KAAKX,UAArB;EACA,QAAMY,SAAS,GAAG1rB,EAAE,CAAC2rB,kBAAH,GAAwB,GAA1C;EACA,QAAM5sB,MAAM,GAAGiB,EAAE,CAAC4rB,mBAAlB;EACA,QAAMzjB,SAAS,GAAG,KAAKgjB,UAAvB;EAEAM,IAAAA,OAAO,CAACI,YAAR,CAAqB1jB,SAArB;EAEA,QAAM2jB,YAAY,GAAG3jB,SAAS,CAACG,cAA/B;EACA,QAAMyjB,aAAa,GAAG5jB,SAAS,CAACM,eAAhC;EAEAujB,IAAAA,OAAA,CAAaF,YAAb,EAA2BA,YAA3B,EAAyC,KAAKG,UAA9C;EACAD,IAAAA,OAAA,CAAaD,aAAb,EAA4BA,aAA5B,EAA2C,KAAKE,UAAhD;EAEA,WAAO,CACL;EACEC,MAAAA,QAAQ,EAAE,CAAC,CAAD,EAAI,CAAJ,EAAOR,SAAP,EAAkB3sB,MAAlB,CADZ;EAEEyiB,MAAAA,QAAQ,EAAEsK,YAFZ;EAGErK,MAAAA,OAAO,EAAEtZ,SAAS,CAACE;EAHrB,KADK,EAML;EACE6jB,MAAAA,QAAQ,EAAE,CAACR,SAAD,EAAY,CAAZ,EAAeA,SAAf,EAA0B3sB,MAA1B,CADZ;EAEEyiB,MAAAA,QAAQ,EAAEuK,aAFZ;EAGEtK,MAAAA,OAAO,EAAEtZ,SAAS,CAACK;EAHrB,KANK,CAAP;EAYD,GA1BM;;EA4BA,sBAAA,GAAP;EACE,WAAO6iB,OAAO,CAAC,KAAKP,UAAL,IAAmB,KAAKA,UAAL,CAAgBE,YAApC,CAAd;EACD,GAFM;;EAIA,wBAAA,GAAP,UAAsBmB,QAAtB;EACEj8B,IAAAA,MAAM,CAACib,gBAAP,CAAwBqf,yBAAxB,EAAmD2B,QAAnD;EACD,GAFM;;EAIA,2BAAA,GAAP,UAAyBA,QAAzB;EACEj8B,IAAAA,MAAM,CAACkb,mBAAP,CAA2Bof,yBAA3B,EAAsD2B,QAAtD;EACD,GAFM;;EAIA,wBAAA,GAAP,UAAsBnpB,MAAtB;EAAA,oBAAA;;EACE,WAAOxS,SAAS,CAAC47B,aAAV,GAA0B95B,IAA1B,CAA+B,UAAA+5B,QAAA;EACpC,UAAMvkB,SAAS,GAAGukB,QAAQ,CAACz9B,MAAT,IAAmBy9B,QAAQ,CAAC,CAAD,CAA7C;;EAEA,UAAI,CAACvkB,SAAL,EAAgB;EACd,eAAOwkB,SAAO,CAACC,MAAR,CAAe,IAAIC,KAAJ,CAAU,wBAAV,CAAf,CAAP;EACD;;EACD,UAAI,CAAC1kB,SAAS,CAAC2kB,YAAV,CAAuBC,UAA5B,EAAwC;EACtC,eAAOJ,SAAO,CAACC,MAAR,CAAe,IAAIC,KAAJ,CAAU,wCAAV,CAAf,CAAP;EACD;;EAED,aAAO1kB,SAAS,CAAC6kB,cAAV,CAAyB,CAAC;EAACh/B,QAAAA,MAAM,EAAEqV;EAAT,OAAD,CAAzB,EAA6C1Q,IAA7C,CAAkD;EACvD,YAAMs6B,OAAO,GAAG9kB,SAAS,CAACS,gBAAV,CAA2BoiB,IAAI,CAACC,IAAhC,CAAhB;EACA,YAAMiC,QAAQ,GAAG/kB,SAAS,CAACS,gBAAV,CAA2BoiB,IAAI,CAACE,KAAhC,CAAjB;EAEA7nB,QAAAA,MAAM,CAAClE,KAAP,GAAe3O,IAAI,CAAC0N,GAAL,CAAS+uB,OAAO,CAACE,WAAjB,EAA8BD,QAAQ,CAACC,WAAvC,IAAsD,CAArE;EACA9pB,QAAAA,MAAM,CAACjE,MAAP,GAAgB5O,IAAI,CAAC0N,GAAL,CAAS+uB,OAAO,CAACG,YAAjB,EAA+BF,QAAQ,CAACE,YAAxC,CAAhB;;EAEA1iB,QAAAA,KAAI,CAAC2iB,WAAL,CAAiBllB,SAAjB;EACD,OARM,CAAP;EASD,KAnBM,CAAP;EAoBD,GArBM;;EAuBA,sBAAA,GAAP,UAAoBpR,MAApB;EACE,SAAKu1B,UAAL,GAAkBv1B,MAAlB;EACD,GAFM;;EAIC,qBAAA,GAAR,UAAoBoR,SAApB;EACE,SAAKgjB,UAAL,GAAkBhjB,SAAlB;EAEA,QAAMmlB,MAAM,GAAGnlB,SAAS,CAAColB,SAAV,EAAf;;EAEA,QAAID,MAAM,CAACr+B,MAAX,EAAmB;EACjB,UAAMu+B,KAAK,GAAGF,MAAM,CAAC,CAAD,CAApB;EAEA,WAAKG,WAAL,GAAmBD,KAAK,CAACE,UAAzB;EACA,WAAKC,YAAL,GAAoBH,KAAK,CAACI,WAA1B;EACD;;EAED,SAAKC,cAAL,CAAoB,KAAK3b,OAAzB;EACD,GAbO;;EAeA,gBAAA,GAAR;EACE,SAAKiZ,UAAL,GAAkB,IAAlB;EACA,SAAKsC,WAAL,GAAmB3C,mBAAnB;EACA,SAAK6C,YAAL,GAAoB5C,oBAApB;EACA,SAAKuB,UAAL,GAAkB,CAAlB;EACD,GALO;;EAMV,kBAAA;EAAC,GA/HD;;ECLA,IAAMwB,kBAAkB,GAAG,OAA3B;;EAMA;;;EAQE,oBAAA,CAAmBxc,OAAnB;EAAA,oBAAA;;EAAmB,0BAAA,EAAA;EAAAA,MAAAA,YAAA;;;EAOZ,gBAAA,GAAU;EACf,UAAMyc,SAAS,GAAGrjB,KAAI,CAACsjB,UAAvB;;EAEAtjB,MAAAA,KAAI,CAAC0gB,iBAAL,CAAuB1gB,KAAI,CAACwH,OAA5B;;EAEA,UAAI6b,SAAJ,EAAe;EACb;EACAA,QAAAA,SAAS,CAACE,GAAV,GAAgBt7B,IAAhB,CAAqB;EAAM,iBAAA,KAAK,CAAL;EAAM,SAAjC,EAAmC;EAAM,iBAAA,KAAK,CAAL;EAAM,SAA/C;EACD;;EACD+X,MAAAA,KAAI,CAAC6gB,MAAL;EACD,KAVM;;EANL,SAAKA,MAAL;;EACA,SAAK2C,QAAL,GAAgB5c,OAAhB;EACD;;;EAEDrjB,EAAAA,qBAAA,mBAAA;WAAA;EAAuB,aAAO,KAAK+/B,UAAZ;EAAyB;;;KAAhD;;EAcO,mBAAA,GAAP,UAAiBG,KAAjB;EACE,QAAMlmB,IAAI,GAAGkmB,KAAK,CAACC,aAAN,CAAoB,KAAKC,WAAzB,CAAb;EAEA,WAAO3C,OAAO,CAACzjB,IAAD,CAAd;EACD,GAJM;;EAMA,sBAAA,GAAP,UAAoB5H,EAApB,EAA+C8tB,KAA/C;EACE,QAAMG,OAAO,GAAGH,KAAK,CAACG,OAAtB;EACA,QAAMC,SAAS,GAAGD,OAAO,CAACE,WAAR,CAAoBD,SAAtC;EAEAluB,IAAAA,EAAE,CAACsrB,eAAH,CAAmBtrB,EAAE,CAACurB,WAAtB,EAAmC2C,SAAU,CAACE,WAA9C;EACD,GALM;;;EAQA,qBAAA,GAAP,cAAO;;EAEA,sBAAA,GAAP,UAAoBpuB,EAApB,EAA+C8tB,KAA/C;EAAA,oBAAA;;EACE,QAAMG,OAAO,GAAGH,KAAK,CAACG,OAAtB;EACA,QAAMrmB,IAAI,GAAGkmB,KAAK,CAACC,aAAN,CAAoB,KAAKC,WAAzB,CAAb;;EAEA,QAAI,CAACpmB,IAAL,EAAW;EACT;EACA,aAAO,IAAP;EACD;;EAED,QAAMymB,OAAO,GAAGJ,OAAO,CAACE,WAAR,CAAoBD,SAApC;EAEA,WAAOtmB,IAAI,CAAC0mB,KAAL,CAAWhgC,GAAX,CAAe,UAAAqZ,IAAA;EACpB,UAAMukB,QAAQ,GAAGmC,OAAQ,CAACE,WAAT,CAAqB5mB,IAArB,CAAjB;EACA,UAAM6Z,QAAQ,GAAG7Z,IAAI,CAAC6mB,SAAL,CAAejyB,OAAf,CAAuBkyB,MAAxC;;EAEA,UAAIx9B,oBAAJ,EAA0B;EACxB+6B,QAAAA,OAAA,CAAaxK,QAAb,EAAuBA,QAAvB,EAAiCjP,QAAA,CAAkB,GAAlB,CAAjC;EACD;;EAEDyZ,MAAAA,OAAA,CAAaxK,QAAb,EAAuBA,QAAvB,EAAiCnX,KAAI,CAAC4hB,UAAtC;EAEA,aAAO;EACLC,QAAAA,QAAQ,EAAE,CAACA,QAAQ,CAACz4B,CAAV,EAAay4B,QAAQ,CAACx4B,CAAtB,EAAyBw4B,QAAQ,CAACptB,KAAlC,EAAyCotB,QAAQ,CAACntB,MAAlD,CADL;EAELyiB,QAAAA,QAAQ,UAFH;EAGLC,QAAAA,OAAO,EAAE9Z,IAAI,CAAC+mB;EAHT,OAAP;EAKD,KAfM,CAAP;EAgBD,GA3BM;;EA6BA,sBAAA,GAAP;EACE,WAAO,KAAKC,WAAZ;EACD,GAFM;;EAIA,wBAAA,GAAP,UAAsBxC,QAAtB;;;EACE,UAAA,KAAKwB,UAAL,UAAA,iBAAA,SAAA,MAAiBxiB,iBAAiB,OAAOghB,SAAzC;EACD,GAFM;;EAIA,2BAAA,GAAP,UAAyBA,QAAzB;;;EACE,UAAA,KAAKwB,UAAL,UAAA,iBAAA,SAAA,MAAiBviB,oBAAoB,OAAO+gB,SAA5C;EACD,GAFM;;EAIM,wBAAA,GAAb,UAA4BnpB,MAA5B,EAAuDhD,EAAvD;;;;;;;;;EACQiR,YAAAA,OAAO,GAAG3jB,KAAK,CAAC;EACpBshC,cAAAA,gBAAgB,EAAE,CAACnB,kBAAD;EADE,aAAD,EAElB,KAAKI,QAFa,CAAf;EAIAgB,YAAAA,UAAU,GAAG7uB,EAAE,CAAC8uB,oBAAH,EAAb;oBACFD,UAAU,IAAKA,UAAkB,CAACE,YAAnB,KAAoC,OAAnD;;kBAAA;EACF;;gBAAO/uB,EAAU,CAACgvB,gBAAX,GAAP;;;EAAA5e,YAAAA,OAAA;;;;;EAGF;;gBAAQ5f,SAAiB,CAAC4B,EAAlB,CAAqB68B,cAArB,CAAoC,cAApC,EAAoDhe,OAApD,EAA6D3e,IAA7D,CAAkE,UAAA27B,OAAA;EACxE,kBAAMiB,OAAO,GAAG,IAAKh/B,MAAc,CAACi/B,YAApB,CAAiClB,OAAjC,EAA0CjuB,EAA1C,CAAhB;EAEAiuB,cAAAA,OAAO,CAACmB,iBAAR,CAA0B;EAAClB,gBAAAA,SAAS,EAAEgB;EAAZ,eAA1B;EACA,qBAAOjB,OAAO,CAACoB,qBAAR,CAA8B5B,kBAA9B,EACJn7B,IADI,CACC,UAAAg9B,QAAA;EACJjlB,gBAAAA,KAAI,CAACklB,WAAL,CAAiBtB,OAAjB,EAA0BiB,OAA1B,EAAmCI,QAAnC;EACD,eAHI,CAAP;EAID,aARO,EAAR;;;;EASD,GAnBY;;EAqBN,sBAAA,GAAP,UAAoB54B,MAApB;EACE,SAAKu1B,UAAL,GAAkBv1B,MAAlB;EACD,GAFM;;EAIC,qBAAA,GAAR,UAAoBu3B,OAApB,EAAwCiB,OAAxC,EAA0DI,QAA1D;EACE,SAAK3B,UAAL,GAAkBM,OAAlB;EACA,SAAKuB,QAAL,GAAgBN,OAAhB;EACA,SAAKlB,WAAL,GAAmBsB,QAAnB;EACA,SAAKX,WAAL,GAAmB,IAAnB;EACA,SAAKnB,cAAL,CAAoB,KAAK3b,OAAzB;EACD,GANO;;EAQA,gBAAA,GAAR;EACE,SAAK8b,UAAL,GAAkB,IAAlB;EACA,SAAK6B,QAAL,GAAgB,IAAhB;EACA,SAAKxB,WAAL,GAAmB,IAAnB;EACA,SAAKW,WAAL,GAAmB,KAAnB;EACA,SAAK1C,UAAL,GAAkB,CAAlB;EACA,SAAK4B,QAAL,GAAgB,EAAhB;EACD,GAPO;;EAQV,kBAAA;EAAC,GA7HD;;ECVA;;;EAME,wBAAA;EAAA,oBAAA;EA4CA;;;;;EAGQ,gBAAA,GAAU;EAAC,mBAAA;;aAAA,YAAArgC,uBAAAA;EAAAiiC,QAAAA,QAAA,gBAAA;;;EACjBplB,MAAAA,KAAI,CAACqlB,SAAL,MAAA,CAAArlB,KAAA,WAAmBolB,KAAnB;;EACAplB,MAAAA,KAAI,CAACslB,MAAL,GAActlB,KAAI,CAACulB,QAAL,CAAcC,qBAAd,CAAoCxlB,KAAI,CAACylB,OAAzC,CAAd;EACD,KAHO;EAKR;;;;;;;;;;;EASQ,wBAAA,GAAkB;EAAC,mBAAA;;aAAA,YAAAtiC,uBAAAA;EAAAiiC,QAAAA,QAAA,gBAAA;;;EACzB,UAAMM,MAAM,GAAGC,WAAW,CAACC,GAAZ,EAAf;;EAEA5lB,MAAAA,KAAI,CAACqlB,SAAL,MAAA,CAAArlB,KAAA,WAAmBolB,KAAnB;;EAEA,UAAMS,IAAI,GAAGF,WAAW,CAACC,GAAZ,KAAoBF,MAAjC;;EAEA,UAAI1lB,KAAI,CAAC8lB,SAAL,IAAkB,CAAtB,EAAyB;EACvBtkB,QAAAA,YAAY,CAACxB,KAAI,CAAC8lB,SAAN,CAAZ;EACA9lB,QAAAA,KAAI,CAAC8lB,SAAL,GAAiB,CAAC,CAAlB;EACD;EAED;;;EACA,UAAID,IAAI,GAAG,EAAX,EAAe;EACb7lB,QAAAA,KAAI,CAACslB,MAAL,GAActlB,KAAI,CAACulB,QAAL,CAAcC,qBAAd,CAAoCxlB,KAAI,CAACylB,OAAzC,CAAd;EACD,OAFD,MAEO;EACL;EACAzlB,QAAAA,KAAI,CAAC8lB,SAAL,GAAiBjgC,MAAM,CAACiT,UAAP,CAAkBkH,KAAI,CAACylB,OAAvB,EAAgC,CAAhC,CAAjB;EACD;EACF,KAnBO;;EA5DN,SAAKJ,SAAL,GAAiB,IAAjB;EACA,SAAKE,QAAL,GAAgB1/B,MAAhB;EACA,SAAKy/B,MAAL,GAAc,CAAC,CAAf;EACA,SAAKQ,SAAL,GAAiB,CAAC,CAAlB;EACD;;;;EAEM,qBAAA,GAAP,UAAmBhE,QAAnB;EACE,SAAKuD,SAAL,GAAiBvD,QAAjB;EACD,GAFM;;EAIA,oBAAA,GAAP,UAAkBvN,OAAlB;EACE,SAAKgR,QAAL,GAAgBhR,OAAhB;EACD,GAFM;;EAIA,eAAA,GAAP;EACE,QAAMA,OAAO,GAAG,KAAKgR,QAArB;EACA,QAAMzD,QAAQ,GAAG,KAAKuD,SAAtB;;EAGA,QAAI,CAAC9Q,OAAD,IAAY,CAACuN,QAAjB,EAA2B;;EAE3B,QAAI,KAAKwD,MAAL,IAAe,CAAf,IAAoB,KAAKQ,SAAL,IAAkB,CAA1C,EAA6C;;EAE7C,QAAIl/B,oBAAJ,EAA0B;EACxB,WAAK0+B,MAAL,GAAc/Q,OAAO,CAACiR,qBAAR,CAA8B,KAAKO,eAAnC,CAAd;EACD,KAFD,MAEO;EACL,WAAKT,MAAL,GAAc/Q,OAAO,CAACiR,qBAAR,CAA8B,KAAKC,OAAnC,CAAd;EACD;EACF,GAdM;;EAgBA,cAAA,GAAP;EACE,QAAI,KAAKH,MAAL,IAAe,CAAnB,EAAsB;EACpB,WAAKC,QAAL,CAAcS,oBAAd,CAAmC,KAAKV,MAAxC;EACD;;EAED,QAAI,KAAKQ,SAAL,IAAkB,CAAtB,EAAyB;EACvBtkB,MAAAA,YAAY,CAAC,KAAKskB,SAAN,CAAZ;EACD;;EAED,SAAKR,MAAL,GAAc,CAAC,CAAf;EACA,SAAKQ,SAAL,GAAiB,CAAC,CAAlB;EACD,GAXM;;EAkDT,sBAAA;EAAC,GAvFD;;ECuBA,IAAMG,SAAS,GAAGlU,eAAlB;;EAGA,IAAImU,kBAAkB,GAAG/+B,gBAAgB,IAAI,CAA7C;;EAGA,IAAI++B,kBAAkB,GAAG,CAAzB,EAA4B;EAC1BA,EAAAA,kBAAkB,GAAG,CAArB;EACD;;EAGD;;;;;;;EAKA,IAAMrP,QAAM,GAMR;EACFsP,EAAAA,YAAY,EAAE,aADZ;EAEFC,EAAAA,YAAY,EAAE,aAFZ;EAGFtU,EAAAA,KAAK,EAAE,OAHL;EAIFL,EAAAA,sBAAsB,EAAE,sBAJtB;EAKF4U,EAAAA,yBAAyB,EAAE;EALzB,CANJ;EAcA,IAAMlV,YAAU,GAAG;EACjBC,EAAAA,cAAc,EAAE,EADC;EAEjBC,EAAAA,QAAQ,EAAE,EAFO;EAGjBC,EAAAA,eAAe,EAAE,EAHA;EAIjBgV,EAAAA,cAAc,EAAE;EAJC,CAAnB;;EAOA;;;EAAgCxmB,EAAAA,oCAAA;;EAkE9B,4BAAA,CACEhc,KADF,EAEE2Q,KAFF,EAGEC,MAHF,EAIE6xB,OAJF,EAKEC,SALF,EAME5T,WANF,EAOE6T,eAPF,EAQEC,0BARF;EAAA;EAWE3mB,IAAAA,WAAA,KAAA,SAXF;;EA5BOC,IAAAA,wBAAA,GAAyC,IAAzC;EACAA,IAAAA,kBAAA,GAAmC,IAAnC;EACAA,IAAAA,iBAAA,GAAkC,IAAlC;;EA2WAA,IAAAA,YAAA,GAAS;EACd,UAAM2mB,EAAE,GAAG3mB,KAAI,CAAC4mB,GAAhB;EACA,UAAMjxB,EAAE,GAAGqK,KAAI,CAACuU,OAAhB;EACA,UAAMsS,QAAQ,GAAG7mB,KAAI,CAAC8mB,SAAtB;EAEA,UAAI,CAACH,EAAL,EAAS;EAETA,MAAAA,EAAE,CAACjG,iBAAH,CAAqB1gB,KAAI,CAAC+mB,MAA1B;EACAJ,MAAAA,EAAE,CAACnf,OAAH;EACAxH,MAAAA,KAAI,CAAC4mB,GAAL,GAAW,IAAX;;EAGA,UAAIjgC,MAAJ,EAAY;EACVqZ,QAAAA,KAAI,CAACgnB,aAAL;EACD;;EACDhnB,MAAAA,KAAI,CAACinB,wBAAL,CAA8BjnB,KAAI,CAACvL,KAAnC,EAA0CuL,KAAI,CAACtL,MAA/C;;EACAsL,MAAAA,KAAI,CAACknB,eAAL;;EACAvxB,MAAAA,EAAE,CAACsrB,eAAH,CAAmBtrB,EAAE,CAACurB,WAAtB,EAAmC,IAAnC;;EACAlhB,MAAAA,KAAI,CAACmnB,YAAL;;EACAnnB,MAAAA,KAAI,CAAConB,gBAAL,GAAwB,IAAxB;EAEAP,MAAAA,QAAQ,CAACQ,IAAT;EACAR,MAAAA,QAAQ,CAACS,UAAT,CAAoBzhC,MAApB;EACAghC,MAAAA,QAAQ,CAACU,WAAT,CAAqBvnB,KAAI,CAACwnB,OAAL,CAAatnB,IAAb,CAAkBF,KAAlB,CAArB;EACA6mB,MAAAA,QAAQ,CAACY,KAAT;EACD,KAzBM;;EAsUCznB,IAAAA,mBAAA,GAAgB,UAAC0nB,IAAD,EAAejE,KAAf;;;EACtB,UAAMkD,EAAE,GAAG3mB,KAAI,CAAC4mB,GAAhB;EACA,UAAMjxB,EAAE,GAAGqK,KAAI,CAACuU,OAAhB;EAEA,UAAMoT,SAAS,GAAGhB,EAAG,CAACiB,YAAJ,CAAiBjyB,EAAjB,EAAqB8tB,KAArB,CAAlB;EAEA,UAAI,CAACkE,SAAL,EAAgB;EAEhBhB,MAAAA,EAAG,CAACkB,YAAJ,CAAiBlyB,EAAjB,EAAqB8tB,KAArB;;;EAEA;EACA,aAAuB,IAAA/D,KAAA5K,SAAA,CAAC,CAAD,EAAI,CAAJ,EAAA,gBAAvB,UAAA,gBAAA,EAA+B;EAA1B,cAAMgT,QAAQ,WAAd;EACH,cAAMC,QAAQ,GAAGJ,SAAS,CAACG,QAAD,CAA1B;EAEA9nB,UAAAA,KAAI,CAACmX,QAAL,GAAgB4Q,QAAQ,CAAC5Q,QAAzB;EACAnX,UAAAA,KAAI,CAACoX,OAAL,GAAe2Q,QAAQ,CAAC3Q,OAAxB;EAEAzhB,UAAAA,EAAE,CAACksB,QAAH,MAAA,CAAAlsB,EAAA,WAAeoyB,QAAQ,CAAClG,SAAxB;EACAlsB,UAAAA,EAAE,CAACqyB,SAAH,CAAchoB,KAAI,CAACiX,aAAL,CAA2BgR,IAAzC,EAA+CH,QAA/C;;EAEA9nB,UAAAA,KAAI,CAACmnB,YAAL;;EACAnnB,UAAAA,KAAI,CAACkoB,KAAL;EACD;;;;;;;;;;;;;EAEDvB,MAAAA,EAAG,CAACwB,WAAJ;EACD,KAzBO;;EAoGAnoB,IAAAA,qBAAA,GAAkB,UAAC0nB,IAAD,EAAOjE,KAAP;EACxB,UAAMkD,EAAE,GAAG3mB,KAAI,CAAC4mB,GAAhB;EACA,UAAMjxB,EAAE,GAAGqK,KAAI,CAACuU,OAAhB;EACA,UAAMsS,QAAQ,GAAG7mB,KAAI,CAAC8mB,SAAtB;;EAGA,UAAI,CAACH,EAAE,CAACyB,SAAH,CAAa3E,KAAb,CAAL,EAA0B;EAE1B,UAAM4E,SAAS,GAAG7/B,UAAA,CAAgB,CAAhB,EAAmB,CAAnB,EAAsB,CAAC,CAAvB,CAAlB;EACA,UAAMu/B,QAAQ,GAAGpB,EAAE,CAACiB,YAAH,CAAgBjyB,EAAhB,EAAoB8tB,KAApB,EAA4B,CAA5B,CAAjB;;EAEA,UAAMtM,QAAQ,GAAGmR,QAAA,CAAcA,MAAA,EAAd,EAA6BP,QAAQ,CAAC5Q,QAAtC,CAAjB;EACA,UAAMC,OAAO,GAAGkR,QAAA,CAAcA,MAAA,EAAd,EAA6BP,QAAQ,CAAC3Q,OAAtC,CAAhB;EAEA,UAAMmR,KAAK,GAAGD,MAAA,CAAYA,MAAA,EAAZ,EAA2BnR,QAA3B,CAAd;EACA,UAAMqR,IAAI,GAAGF,MAAA,CAAYA,MAAA,EAAZ,EAA2BlR,OAA3B,CAAb;EACA,UAAMtrB,OAAO,GAAGtD,aAAA,CAAmBA,QAAA,EAAnB,EAAkC6/B,SAAlC,EAA6CG,IAA7C,CAAhB;EAEAhgC,MAAAA,aAAA,CAAmBsD,OAAnB,EAA4BA,OAA5B,EAAqCy8B,KAArC;EAEA,UAAME,SAAS,GAAGnY,IAAQ,CAACzkB,gBAAT,CAA0BC,OAA1B,EAAmCtD,UAAA,CAAgB,CAAhB,EAAmB,CAAnB,EAAsB,CAAtB,CAAnC,CAAlB;;EAEA,UAAIigC,SAAS,KAAK,CAAlB,EAAqB;EACnB;EACA;EACA;EACD;;EAED9B,MAAAA,EAAE,CAAC+B,YAAH,CAAgBD,SAAhB;EACA5B,MAAAA,QAAQ,CAACU,WAAT,CAAqBvnB,KAAI,CAAC2oB,aAA1B;EACD,KA9BO;;EA9uBN3oB,IAAAA,KAAI,CAACymB,eAAL,GAAuBA,eAAvB;EACAzmB,IAAAA,KAAI,CAACtC,WAAL,GAAmB+oB,eAAe,CAAC/oB,WAAnC;EAEAsC,IAAAA,KAAI,CAACvL,KAAL,GAAaA,KAAb;EACAuL,IAAAA,KAAI,CAACtL,MAAL,GAAcA,MAAd;EAEAsL,IAAAA,KAAI,CAAC4oB,eAAL,GAAuB,IAAvB;EACA5oB,IAAAA,KAAI,CAAC6oB,QAAL,GAAgB,IAAhB;EACA7oB,IAAAA,KAAI,CAAC8oB,UAAL,GAAkB,IAAlB;EACA9oB,IAAAA,KAAI,CAAC+oB,gBAAL,GAAwB,IAAxB;EAEA/oB,IAAAA,KAAI,CAACoX,OAAL,GAAeuK,QAAA,EAAf;EACA3hB,IAAAA,KAAI,CAACmX,QAAL,GAAgBwK,QAAA,EAAhB;;EAGAA,IAAAA,WAAA,CAAiB3hB,KAAI,CAACoX,OAAtB,EAA+BlP,QAAA,CAAkBlI,KAAI,CAACtC,WAAvB,CAA/B,EAAoEjJ,KAAK,GAAGC,MAA5E,EAAoF,GAApF,EAAyF,GAAzF;EAEAsL,IAAAA,KAAI,CAACgpB,kBAAL,GAA0B,IAA1B;EACAhpB,IAAAA,KAAI,CAACipB,YAAL,GAAoB,IAApB;EACAjpB,IAAAA,KAAI,CAACkX,WAAL,GAAmB,IAAnB;EAEAlX,IAAAA,KAAI,CAACrH,MAAL,GAAcqH,KAAI,CAACkpB,WAAL,CAAiB1C,SAAjB,EAA4B5T,WAA5B,EAAyCne,KAAzC,EAAgDC,MAAhD,CAAd;;EAEAsL,IAAAA,KAAI,CAACmpB,sBAAL;;EACAnpB,IAAAA,KAAI,CAACopB,QAAL,GAAgB,IAAhB;;EACAppB,IAAAA,KAAI,CAACqpB,iBAAL,GAAyB,IAAzB;EAEArpB,IAAAA,KAAI,CAACspB,2BAAL,GAAmC5C,0BAAnC;EACA1mB,IAAAA,KAAI,CAACupB,MAAL,GAAc,IAAd;EACAvpB,IAAAA,KAAI,CAACwpB,YAAL,GAAoB,IAApB;EACAxpB,IAAAA,KAAI,CAACypB,aAAL,GAAqB,KAArB;EACAzpB,IAAAA,KAAI,CAAConB,gBAAL,GAAwB,KAAxB;EACApnB,IAAAA,KAAI,CAAC0pB,WAAL,GAAmB,KAAnB;;EAEA1pB,IAAAA,KAAI,CAAC2pB,cAAL,GAAsB3pB,KAAI,CAAC2pB,cAAL,CAAoBzpB,IAApB,CAAyBF,KAAzB,CAAtB;EACAA,IAAAA,KAAI,CAAC4pB,eAAL,GAAwB5pB,KAAI,CAAC4pB,eAAL,CAAqB1pB,IAArB,CAA0BF,KAA1B,CAAxB;EAEAA,IAAAA,KAAI,CAAC8mB,SAAL,GAAiB,IAAI+C,aAAJ,EAAjB;;EAGA7pB,IAAAA,KAAI,CAAC4mB,GAAL,GAAW,IAAX;;EAEA,QAAI9iC,KAAJ,EAAW;EACTkc,MAAAA,KAAI,CAAC8pB,QAAL,CAAc;EACZhmC,QAAAA,KAAK,OADO;EAEZimC,QAAAA,SAAS,EAAEtD,eAAe,CAACsD,SAFf;EAGZxD,QAAAA,OAAO,SAHK;EAIZ7T,QAAAA,aAAa,EAAE+T,eAAe,CAAC/T;EAJnB,OAAd;EAMD;;;EACF;;;;;EAGM,4BAAA,GAAP,UAA0BsX,eAA1B;EACE,SAAKC,gBAAL,GAAwBD,eAAxB;EACD,GAFM;;EAIA,oBAAA,GAAP;EACE,WAAO,KAAKT,MAAZ;EACD,GAFM;;EAIA,kBAAA,GAAP,UAAgBxjB,EAAhB;UACEjiB,KAAK;UACLimC,SAAS;UACTrK;UAAA6G,OAAO,mBAAG;UACV7T,aAAa;EAOb,SAAK+W,aAAL,GAAqB,KAArB;EACA,SAAKS,QAAL,GAAgB3D,OAAhB;EACA,SAAKiD,YAAL,YACK;EACD;EACA1Q,MAAAA,KAAK,EAAGiR,SAAS,KAAK9D,SAAS,CAAChU,OAAzB,GAAoC,QAApC,GAA+C,QAFrD;EAGDsG,MAAAA,UAAU,EAAE;EACVE,QAAAA,cAAc,EAAE,KADN;EAEVC,QAAAA,QAAQ,EAAE;EAFA,OAHX;EAODgB,MAAAA,IAAI,EAAE;EAPL,OASAhH,cAVL;;EAYA,SAAKyX,aAAL,CAAmBJ,SAAnB;;EAEA,QAAI,KAAKK,cAAT,EAAyB;EACvB,WAAKA,cAAL,CAAoB5iB,OAApB;EACD;;EAED,SAAK4iB,cAAL,GAAsB,IAAIC,OAAJ,GACnBjlB,EADmB,CAChB,OADgB,EACP,KAAKukB,cADE,EAEnBvkB,EAFmB,CAEhB,OAFgB,EAEP,KAAKwkB,eAFE,CAAtB;;EAIA,QAAIrD,OAAJ,EAAa;EACX,WAAKgD,MAAL,GAAc/kC,cAAc,CAACV,KAAD,CAA5B;;EACA,WAAKsmC,cAAL,CAAoBhyB,KAApB,CAA0B,CAAC,KAAKmxB,MAAN,CAA1B;;EACA,WAAKG,WAAL,GAAmB,IAAnB;EACD,KAJD,MAIO;EACL,WAAKH,MAAL,GAAc1lC,cAAc,CAACC,KAAD,CAA5B;;EACA,WAAKsmC,cAAL,CAAoBhyB,KAApB,CAA0BzU,KAAK,CAACC,OAAN,CAAc,KAAK2lC,MAAnB,IAA6B,KAAKA,MAAlC,GAA2C,CAAC,KAAKA,MAAN,CAArE;;EACA,WAAKG,WAAL,GAAmB,KAAnB;EACD;EACF,GA5CM;;EA8CA,uBAAA,GAAP;EACE,WAAO,CAAC,CAAC,KAAKH,MAAP,IAAiB,KAAKE,aAAtB,KACJ,CAAC,KAAKS,QAAN,IAAmB,KAAKX,MAAL,CAAiCpkC,UAAjC,IAA+C;EAAE;EADhE,KAAP;EAED,GAHM;;EAKA,qBAAA,GAAP;EAAA,oBAAA;;EACE,WAAO,IAAI88B,SAAJ,CAAY,UAAC/5B,GAAD,EAAMoiC,GAAN;EACjB,UAAMC,aAAa,GAAGvqB,KAAI,CAACoqB,cAA3B;;EAEA,UAAI,CAACpqB,KAAI,CAACupB,MAAV,EAAkB;EAChB,eAAOe,GAAG,CAAC,sBAAD,CAAV;EACD;;EAED,UAAI,CAACC,aAAL,EAAoB;EAClB,eAAOD,GAAG,CAAC,gCAAD,CAAV;EACD;;EAED,UAAIC,aAAa,CAACC,OAAd,EAAJ,EAA6B;EAC3BxqB,QAAAA,KAAI,CAACyqB,YAAL;;EACAviC,QAAAA,GAAG;EACJ,OAHD,MAGO;EACLqiC,QAAAA,aAAa,CAACnyB,KAAd,CAAoBzU,KAAK,CAACC,OAAN,CAAcoc,KAAI,CAACupB,MAAnB,IAA6BvpB,KAAI,CAACupB,MAAlC,GAA2C,CAACvpB,KAAI,CAACupB,MAAN,CAA/D;EACAgB,QAAAA,aAAa,CAACG,IAAd,CAAmB,OAAnB,EAA4B,UAAA1pB,CAAA;EAC1B,cAAIA,CAAC,CAAC2pB,UAAF,GAAe,CAAnB,EAAsB;EACpBL,YAAAA,GAAG,CAAC,wBAAD,CAAH;EACD,WAFD,MAEO;EACLtqB,YAAAA,KAAI,CAACyqB,YAAL;;EACAviC,YAAAA,GAAG;EACJ;EACF,SAPD;EAQD;EACF,KAzBM,CAAP;EA0BD,GA3BM;;;EA8BA,kBAAA,GAAP,UAAgB0iC,aAAhB;EACE,QAAI,CAAC,KAAKC,kBAAV,EAA8B;EAC5B,WAAKC,MAAL;EACAF,MAAAA,aAAa,CAACjlC,WAAd,CAA0B,KAAKgT,MAA/B;EACD;;EACD,SAAKywB,QAAL,GAAgBwB,aAAhB;EACD,GANM;;EAQA,0BAAA,GAAP;EACE,QAAI,KAAKG,mBAAL,EAAJ,EAAgC;EAC9B,UAAMjV,oBAAoB,GAAG,KAAKvB,OAAL,CAAawB,YAAb,CAA0B,oBAA1B,CAA7B;;EAEA,UAAID,oBAAJ,EAA0B;EACxBA,QAAAA,oBAAoB,CAACE,WAArB;EACD;EACF;EACF,GARM;;;EAWA,gBAAA,GAAP;EACE,QAAI,CAAC,KAAK6U,kBAAN,IAA4B,KAAKlyB,MAAL,CAAYiyB,aAA5C,EAA2D;EACzD,WAAKjyB,MAAL,CAAYiyB,aAAZ,CAA0BI,WAA1B,CAAsC,KAAKryB,MAA3C;EACD;EACF,GAJM;;EAMA,iBAAA,GAAP;EACE,QAAI,KAAKyxB,cAAT,EAAyB;EACvB,WAAKA,cAAL,CAAoB5iB,OAApB;EACD;;EAED,SAAKsf,SAAL,CAAeO,IAAf;;EACA,SAAKyD,MAAL;EACA,SAAKG,gBAAL;EAEA,SAAKrjB,GAAL;EAEA,SAAKjP,MAAL,CAAYoI,mBAAZ,CAAgC,kBAAhC,EAAoD,KAAKmqB,mBAAzD;EACA,SAAKvyB,MAAL,CAAYoI,mBAAZ,CAAgC,sBAAhC,EAAwD,KAAKoqB,uBAA7D;EACD,GAbM;;EAeA,6BAAA,GAAP;EACE,QAAMpM,GAAG,GAAG,KAAKxK,OAAjB;;EACA,QACE,CAACwK,GAAD,IACGA,GAAG,CAACqM,aAAJ,EADH,IAEG,CAACrM,GAAG,CAAChoB,mBAAJ,CAAwB,KAAKkgB,aAA7B,EAA6C8H,GAAG,CAACxL,WAAjD,CAHN,EAGqE;EACnE,aAAO,KAAP;EACD;;EACD,WAAO,IAAP;EACD,GATM;;EAWA,2BAAA,GAAP,UAAyB7V,WAAzB;EACE,SAAKA,WAAL,GAAmBA,WAAnB;;EACA,SAAKwpB,eAAL;EACD,GAHM;;EAKA,kCAAA,GAAP,UAAgCzyB,KAAhC,EAAuCC,MAAvC;EACE,QAAI22B,eAAe,GAAG,KAAtB;EAEA,SAAK52B,KAAL,GAAaA,KAAb;EACA,SAAKC,MAAL,GAAcA,MAAd;EAEA,QAAMhF,CAAC,GAAG+E,KAAK,GAAGyxB,kBAAlB;EACA,QAAMoF,CAAC,GAAG52B,MAAM,GAAGwxB,kBAAnB;;EAEA,QAAIx2B,CAAC,KAAK,KAAKiJ,MAAL,CAAYlE,KAAtB,EAA6B;EAC3B,WAAKkE,MAAL,CAAYlE,KAAZ,GAAoB/E,CAApB;EACA27B,MAAAA,eAAe,GAAG,IAAlB;EACD;;EAED,QAAIC,CAAC,KAAK,KAAK3yB,MAAL,CAAYjE,MAAtB,EAA8B;EAC5B,WAAKiE,MAAL,CAAYjE,MAAZ,GAAqB42B,CAArB;EACAD,MAAAA,eAAe,GAAG,IAAlB;EACD;;EAED,QAAI,CAACA,eAAL,EAAsB;EACpB;EACD;;EAED,SAAKnE,eAAL;;EACA,SAAKE,gBAAL,GAAwB,IAAxB;EACD,GAzBM;;EA2BA,oBAAA,GAAP,UAAkBmE,QAAlB;EACE,QAAIA,QAAQ,IAAI,KAAKC,aAAL,OAAyB,KAAzC,EAAgD;EAC9C;EACA,WAAKpE,gBAAL,GAAwB,IAAxB;EACD;;EAED,SAAKsC,WAAL,GAAmB6B,QAAnB;EACD,GAPM;;EASA,qBAAA,GAAP;EACE,SAAKzE,SAAL,CAAeS,WAAf,CAA2B,KAAKC,OAAL,CAAatnB,IAAb,CAAkB,IAAlB,CAA3B;;EACA,SAAK4mB,SAAL,CAAeW,KAAf;EACD,GAHM;;EAKA,oBAAA,GAAP;EACE,SAAKX,SAAL,CAAeO,IAAf;EACD,GAFM;;EAIA,8BAAA,GAAP,UAA4B/+B,UAA5B,EAAwCoV,WAAxC;EACE,QAAI,CAAC,KAAK8tB,aAAL,EAAL,EAA2B;EACzB;EACD;;EAED,QAAI,KAAK9B,WAAL,KAAqB,KAArB,IACF,KAAKd,eADH,IACsB3+B,aAAA,CAAiB,KAAK2+B,eAAtB,EAAuCtgC,UAAvC,CADtB,IAEF,KAAKoV,WAFH,IAEkB,KAAKA,WAAL,KAAqBA,WAFvC,IAGF,KAAK0pB,gBAAL,KAA0B,KAH5B,EAGmC;EACjC;EACD;;;EAGD,QAAI1pB,WAAW,KAAKlN,SAAhB,IAA6BkN,WAAW,KAAK,KAAKA,WAAtD,EAAmE;EACjE,WAAK+tB,iBAAL,CAAuB/tB,WAAvB;EACD;;EAED,SAAKyZ,QAAL,GAAgBwK,QAAA,CAAcA,QAAA,EAAd,EAA6Br5B,UAA7B,CAAhB;;EAEA,SAAK4/B,KAAL;;EAEA,SAAKU,eAAL,GAAuB3+B,OAAA,CAAW3B,UAAX,CAAvB;;EACA,QAAI,KAAK8+B,gBAAT,EAA2B;EACzB,WAAKA,gBAAL,GAAwB,KAAxB;EACD;EACF,GAzBM;;EA2BA,4BAAA,GAAP,UAA0Bvd,GAA1B,EAA+BO,KAA/B,EAAsC1M,WAAtC;EACE,QAAI,CAAC,KAAK8tB,aAAL,EAAL,EAA2B;EACzB;EACD;;EAED,QAAI,KAAK9B,WAAL,KAAqB,KAArB,IACA,KAAKb,QAAL,KAAkB,IADlB,IAC0B,KAAKA,QAAL,KAAkBhf,GAD5C,IAEA,KAAKif,UAAL,KAAoB,IAFpB,IAE4B,KAAKA,UAAL,KAAoB1e,KAFhD,IAGA,KAAK1M,WAHL,IAGoB,KAAKA,WAAL,KAAqBA,WAHzC,IAIA,KAAK0pB,gBAAL,KAA0B,KAJ9B,EAIqC;EACnC;EACD;;;EAGD,QAAI1pB,WAAW,KAAKlN,SAAhB,IAA6BkN,WAAW,KAAK,KAAKA,WAAtD,EAAmE;EACjE,WAAK+tB,iBAAL,CAAuB/tB,WAAvB;EACD;;EAEDikB,IAAAA,QAAA,CAAc,KAAKxK,QAAnB;EACAwK,IAAAA,OAAA,CAAa,KAAKxK,QAAlB,EAA4B,KAAKA,QAAjC,EAA2C,CAACjP,QAAA,CAAkBkC,KAAlB,CAA5C;EACAuX,IAAAA,OAAA,CAAa,KAAKxK,QAAlB,EAA4B,KAAKA,QAAjC,EAA2C,CAACjP,QAAA,CAAkB2B,GAAlB,CAA5C;;EAEA,SAAKqe,KAAL;;EAEA,SAAKW,QAAL,GAAgBhf,GAAhB;EACA,SAAKif,UAAL,GAAkB1e,KAAlB;;EACA,QAAI,KAAKgd,gBAAT,EAA2B;EACzB,WAAKA,gBAAL,GAAwB,KAAxB;EACD;EACF,GA7BM;EA+BP;;;;;EAGO,+BAAA,GAAP;EACE,WAAO,KAAKsE,SAAZ;EACD,GAFM;EAIP;;;;;EAGO,iBAAA,GAAP,UAAe9kB,OAAf;EACE,QAAM+f,EAAE,GAAG,KAAKC,GAAhB;;EAEA,QAAI,CAAC/+B,eAAD,IAAoB,CAAE1B,SAAiB,CAAC47B,aAA5C,EAA2D;EACzD,aAAOE,SAAO,CAACC,MAAR,CAAe,sCAAf,CAAP;EACD;;EACD,QAAIyE,EAAE,IAAIA,EAAE,CAAChG,YAAH,EAAV,EAA6B;EAC3B,aAAOsB,SAAO,CAAC0J,OAAR,CAAgB,qBAAhB,CAAP;EACD;;EAED,WAAO,KAAKC,eAAL,CAAqBhlB,OAArB,CAAP;EACD,GAXM;;EAwCC,uBAAA,GAAR,UAAsBmjB,SAAtB;EAAA,oBAAA;;EACE,QAAI,CAACA,SAAD,IAAc,KAAK8B,UAAL,KAAoB9B,SAAtC,EAAiD;EAC/C;EACD;;EAED,SAAK8B,UAAL,GAAkB9B,SAAlB;EACA,SAAK+B,UAAL,GAAkB/B,SAAS,KAAK9D,SAAS,CAAChU,OAA1C;;EAEA,QAAI,KAAKyZ,SAAT,EAAoB;EAClB,WAAKA,SAAL,CAAe9jB,GAAf;EACD;;EAED,YAAQmiB,SAAR;EACE,WAAK9D,SAAS,CAAChU,OAAf;EACE,aAAKyZ,SAAL,GAAiB,IAAI7S,YAAJ,EAAjB;EACA;;EACF,WAAKoN,SAAS,CAAC/T,SAAf;EACE,aAAKwZ,SAAL,GAAiB,IAAIK,iBAAJ,EAAjB;EACA;;EACF,WAAK9F,SAAS,CAAC9T,QAAf;EACE,aAAKuZ,SAAL,GAAiB,IAAIlM,gBAAJ,EAAjB;EACA;;EACF,WAAKyG,SAAS,CAAC7T,iBAAf;EACE,aAAKsZ,SAAL,GAAiB,IAAIrM,cAAJ,CAAmB,KAAKoH,eAAL,CAAqB9T,YAAxC,CAAjB;EACA;;EACF;EACE,aAAK+Y,SAAL,GAAiB,IAAIrM,cAAJ,CAAmBhN,aAAa,CAACpkB,IAAjC,CAAjB;EACA;EAfJ;;EAkBA,SAAKy9B,SAAL,CAAetmB,EAAf,CAAkBwT,QAAQ,CAAC/B,MAAT,CAAgB/E,KAAlC,EAAyC,UAAA9Q,CAAA;EACvChB,MAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,QAAM,CAAC/E,KAA1B,EAAiC;EAC5CrsB,QAAAA,IAAI,EAAE0rB,YAAU,CAACmV,cAD2B;EAE5C3N,QAAAA,OAAO,EAAE3X,CAAC,CAAC2X;EAFiC,OAAjC,CAAb;EAID,KALD;;EAOA,SAAKqT,UAAL;EACD,GAtCO;;EAwCA,qBAAA,GAAR,UAAoBxF,SAApB,EAA4C5T,WAA5C,EAAiEne,KAAjE,EAAgFC,MAAhF;EACE,QAAMu3B,iBAAiB,GAAGzF,SAAS,CAAC0F,aAAV,CAA2C,MAAItZ,WAA/C,CAA1B;;EACA,QAAMja,MAAM,GAAGszB,iBAAiB,IAAI,KAAKE,aAAL,CAAmBvZ,WAAnB,CAApC;;EAEA,SAAKiY,kBAAL,GAA0B,CAAC,CAACoB,iBAA5B;EAEAtzB,IAAAA,MAAM,CAAClE,KAAP,GAAeA,KAAf;EACAkE,IAAAA,MAAM,CAACjE,MAAP,GAAgBA,MAAhB;EAEA,SAAKw2B,mBAAL,GAA2B,KAAKA,mBAAL,CAAyBhrB,IAAzB,CAA8B,IAA9B,CAA3B;EACA,SAAKirB,uBAAL,GAA+B,KAAKA,uBAAL,CAA6BjrB,IAA7B,CAAkC,IAAlC,CAA/B;EAEAvH,IAAAA,MAAM,CAACmI,gBAAP,CAAwB,kBAAxB,EAA4C,KAAKoqB,mBAAjD;EACAvyB,IAAAA,MAAM,CAACmI,gBAAP,CAAwB,sBAAxB,EAAgD,KAAKqqB,uBAArD;EAEA,WAAOxyB,MAAP;EACD,GAhBO;;EAkBA,uBAAA,GAAR,UAAsByzB,SAAtB;EACE,QAAMzzB,MAAM,GAAG/T,QAAQ,CAACC,aAAT,CAAuB,QAAvB,CAAf;EAEA8T,IAAAA,MAAM,CAACyzB,SAAP,GAAmBA,SAAnB;EAEA,WAAOzzB,MAAP;EACD,GANO;;EAQA,gCAAA,GAAR;EACE,QAAMA,MAAM,GAAG,KAAKA,MAApB;EAEAA,IAAAA,MAAM,CAACpR,KAAP,CAAamQ,MAAb,GAAsB,GAAtB;EACAiB,IAAAA,MAAM,CAACpR,KAAP,CAAaiQ,IAAb,GAAoB,GAApB;EACAmB,IAAAA,MAAM,CAACpR,KAAP,CAAakQ,KAAb,GAAqB,GAArB;EACAkB,IAAAA,MAAM,CAACpR,KAAP,CAAaoQ,GAAb,GAAmB,GAAnB;EACAgB,IAAAA,MAAM,CAACpR,KAAP,CAAa8kC,MAAb,GAAsB,MAAtB;EACA1zB,IAAAA,MAAM,CAACpR,KAAP,CAAa+kC,SAAb,GAAyB,MAAzB;EACA3zB,IAAAA,MAAM,CAACpR,KAAP,CAAaglC,QAAb,GAAwB,MAAxB;EACA5zB,IAAAA,MAAM,CAACpR,KAAP,CAAailC,OAAb,GAAuB,MAAvB;EACA7zB,IAAAA,MAAM,CAACpR,KAAP,CAAasW,QAAb,GAAwB,UAAxB;EACD,GAZO;;EAcA,yBAAA,GAAR;EACE,SAAK4rB,aAAL,GAAqB,KAArB;EACA,SAAKF,MAAL,GAAc,IAAd;EACA,SAAKnoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,QAAM,CAAC/E,KAA1B,EAAiC;EAC5CrsB,MAAAA,IAAI,EAAE0rB,YAAU,CAACG,eAD2B;EAE5CqH,MAAAA,OAAO,EAAE;EAFmC,KAAjC,CAAb;EAKA,WAAO,KAAP;EACD,GATO;;EAWA,6BAAA,GAAR;EACE,SAAKvX,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,QAAM,CAACuP,YAA1B,EAAwC;EACnDqG,MAAAA,OAAO,EAAE,KAAKlD,MADqC;EAEnDhD,MAAAA,OAAO,EAAE,KAAK2D,QAFqC;EAGnDzX,MAAAA,cAAc,EAAE,KAAKoZ;EAH8B,KAAxC,CAAb;EAKD,GANO;;EAQA,wBAAA,GAAR,UAAuB7qB,CAAvB;EACE,QAAIA,CAAC,CAAC2pB,UAAF,GAAe,CAAnB,EAAsB;EAEtB,SAAKlB,aAAL,GAAqB,IAArB;;EAEA,SAAKiD,mBAAL;EACD,GANO;;EAQA,4BAAA,GAAR;EACE,QAAM/2B,EAAE,GAAG,KAAK4e,OAAhB;;EAEA,QAAI,KAAK0C,aAAT,EAAwB;EACtBthB,MAAAA,EAAE,CAAC6d,aAAH,CAAiB,KAAKyD,aAAtB;EACA,WAAKA,aAAL,GAAqB,IAArB;EACD;;EAED,QAAM0V,QAAQ,GAAG,KAAKjB,SAAtB;EAEA,QAAMkB,QAAQ,GAAGD,QAAQ,CAACE,qBAAT,EAAjB;EACA,QAAMC,QAAQ,GAAGH,QAAQ,CAACI,uBAAT,EAAjB;EAEA,QAAMh3B,YAAY,GAAGid,UAAU,CAAChd,YAAX,CAAwBL,EAAxB,EAA4BA,EAAE,CAACM,aAA/B,EAA8C22B,QAA9C,CAArB;EACA,QAAMx2B,cAAc,GAAG4c,UAAU,CAAChd,YAAX,CAAwBL,EAAxB,EAA4BA,EAAE,CAACU,eAA/B,EAAgDy2B,QAAhD,CAAvB;EAEA,QAAM7V,aAAa,GAAGjE,UAAU,CAACzc,aAAX,CAAyBZ,EAAzB,EAA6BI,YAA7B,EAA2CK,cAA3C,CAAtB;;EAEA,QAAI,CAAC6gB,aAAL,EAAoB;EAClB,YAAM,IAAIkL,KAAJ,CAAU,mCAAiCnP,UAAU,CAACga,8BAAX,CAA0Cr3B,EAAE,CAACs3B,QAAH,EAA1C,CAA3C,CAAN;EACD;;EAEDt3B,IAAAA,EAAE,CAACu3B,UAAH,CAAcjW,aAAd;EACCA,IAAAA,aAAqB,CAACkW,uBAAtB,GAAgDx3B,EAAE,CAACy3B,iBAAH,CAAqBnW,aAArB,EAAoC,iBAApC,CAAhD;EACAA,IAAAA,aAAqB,CAACK,cAAtB,GAAuC3hB,EAAE,CAAC0B,kBAAH,CAAsB4f,aAAtB,EAAqC,UAArC,CAAvC;EACAA,IAAAA,aAAqB,CAACM,eAAtB,GAAwC5hB,EAAE,CAAC0B,kBAAH,CAAsB4f,aAAtB,EAAqC,WAArC,CAAxC;EACAA,IAAAA,aAAqB,CAACoW,cAAtB,GAAuC13B,EAAE,CAAC0B,kBAAH,CAAsB4f,aAAtB,EAAqC,UAArC,CAAvC;EACAA,IAAAA,aAAqB,CAACqW,qBAAtB,GAA8C33B,EAAE,CAACy3B,iBAAH,CAAqBnW,aAArB,EAAoC,eAApC,CAA9C;EACAA,IAAAA,aAAqB,CAACgR,IAAtB,GAA6BtyB,EAAE,CAAC0B,kBAAH,CAAsB4f,aAAtB,EAAqC,MAArC,CAA7B;EAEDthB,IAAAA,EAAE,CAACue,uBAAH,CAA4B+C,aAAqB,CAACkW,uBAAlD;EACAx3B,IAAAA,EAAE,CAACue,uBAAH,CAA4B+C,aAAqB,CAACqW,qBAAlD;;EAGA33B,IAAAA,EAAE,CAAC43B,KAAH,CAAS53B,EAAE,CAAC63B,gBAAH,GAAsB73B,EAAE,CAAC83B,gBAAzB,GAA4C93B,EAAE,CAAC+3B,kBAAxD;;EAEA/3B,IAAAA,EAAE,CAACg4B,SAAH,CAAc1W,aAAqB,CAACoW,cAApC,EAAoD,CAApD;EAEA,SAAKpW,aAAL,GAAqBA,aAArB;EACD,GAvCO;;EAyCA,6BAAA,GAAR,UAA4BjW,CAA5B;EACEA,IAAAA,CAAC,CAAC4sB,cAAF;EACA,SAAKxsB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,QAAM,CAACpF,sBAA1B,CAAb;EACD,GAHO;;EAKA,iCAAA,GAAR;EACE,SAAKua,UAAL;;EACA,SAAK5qB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,QAAM,CAACwP,yBAA1B,CAAb;EACD,GAHO;;EAKA,yBAAA,GAAR;EACE1E,IAAAA,WAAA,CACE,KAAKvK,OADP,EAEElP,QAAA,CAAkB,KAAKxK,WAAvB,CAFF,EAGE,KAAK/E,MAAL,CAAYlE,KAAZ,GAAoB,KAAKkE,MAAL,CAAYjE,MAHlC,EAIE,GAJF,EAKE,GALF;EAOA,SAAK6f,OAAL,CAAasN,QAAb,CAAsB,CAAtB,EAAyB,CAAzB,EAA4B,KAAKtN,OAAL,CAAa+M,kBAAzC,EAA6D,KAAK/M,OAAL,CAAagN,mBAA1E;EACD,GATO;;EAWA,oBAAA,GAAR;EACE,QAAI5rB,EAAJ;;EAGA,QAAI;EACF,WAAKk4B,qBAAL;;EACAl4B,MAAAA,EAAE,GAAG,KAAK4e,OAAV;EAEA,WAAK0S,wBAAL,CAA8B,KAAKxyB,KAAnC,EAA0C,KAAKC,MAA/C;;EACA,WAAKo5B,kBAAL;EACD,KAND,CAME,OAAO9sB,CAAP,EAAU;EACV,WAAKI,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,QAAM,CAAC/E,KAA1B,EAAiC;EAC5CrsB,QAAAA,IAAI,EAAE0rB,YAAU,CAACE,QAD2B;EAE5CsH,QAAAA,OAAO,EAAE;EAFmC,OAAjC,CAAb;EAIA,WAAKnR,OAAL;EACAhI,MAAAA,OAAO,CAAC6T,KAAR,CAAcrS,CAAd,EANU;;EAOV;EACD;;;EAEDrL,IAAAA,EAAE,CAACo4B,UAAH,CAAc,CAAd,EAAiB,CAAjB,EAAoB,CAApB,EAAuB,CAAvB;EACA,QAAM9Y,aAAa,GAAG,KAAK6W,UAAL,GAAkBn2B,EAAE,CAAC4lB,gBAArB,GAAwC5lB,EAAE,CAACmnB,UAAjE;;EAEA,QAAI,KAAK5H,OAAT,EAAkB;EAChBvf,MAAAA,EAAE,CAACq4B,aAAH,CAAiB,KAAK9Y,OAAtB;EACD;;EAED,SAAKA,OAAL,GAAelC,UAAU,CAACmC,aAAX,CAAyBxf,EAAzB,EAA6Bsf,aAA7B,CAAf;;EAEA,QAAI,KAAK4W,UAAL,KAAoB5F,SAAS,CAAC/T,SAAlC,EAA6C;EAC3C;EACAvc,MAAAA,EAAE,CAACkL,MAAH,CAAUlL,EAAE,CAACs4B,SAAb,EAF2C;EAI5C;EACF,GAlCO;;EAoCA,+BAAA,GAAR;EACE,QAAI,KAAKlD,mBAAL,EAAJ,EAAgC;EAC9B;EACD;;EAED,QAAI,CAACllC,MAAM,CAACqoC,qBAAZ,EAAmC;EACjC,YAAM,IAAI/L,KAAJ,CAAU,sCAAV,CAAN;EACD;;EAED,SAAK5N,OAAL,GAAevB,UAAU,CAAC6C,eAAX,CAA2B,KAAKld,MAAhC,EAAwC,KAAK2wB,2BAA7C,CAAf;;EAEA,QAAI,CAAC,KAAK/U,OAAV,EAAmB;EACjB,YAAM,IAAI4N,KAAJ,CAAU,wCAAV,CAAN;EACD;EACF,GAdO;;EAgBA,sBAAA,GAAR;EACE,QAAMr+B,KAAK,GAAG,KAAKylC,MAAnB;;EAEA,QAAMrQ,kBAAkB,GAAG,KAAKwS,SAAL,CAAevS,qBAAf,EAA3B;;EACA,QAAMF,SAAS,GAAG,KAAKyS,SAAL,CAAeyC,YAAf,EAAlB;;EACA,QAAM7P,gBAAgB,GAAG,KAAKoN,SAAL,CAAe0C,mBAAf,CAAmC;EAC1DtqC,MAAAA,KAAK,OADqD;EAE1Dw0B,MAAAA,WAAW,EAAE,KAAKkR;EAFwC,KAAnC,CAAzB;;EAIA,QAAM7zB,EAAE,GAAG,KAAK4e,OAAhB;EAEA,SAAK0U,YAAL,GAAoBjW,UAAU,CAACqb,UAAX,CAClB14B,EADkB,EACdA,EAAE,CAAC24B,YADW,EACG,IAAIznC,YAAJ,CAAiBqyB,kBAAjB,CADH,EACyC,CADzC,EAEjB,KAAKjC,aAAL,CAA2BkW,uBAFV,CAApB;EAIA,SAAKjW,WAAL,GAAmBlE,UAAU,CAACqb,UAAX,CACjB14B,EADiB,EACbA,EAAE,CAAC44B,oBADU,EACY,IAAIC,WAAJ,CAAgBvV,SAAhB,CADZ,EACwC,CADxC,CAAnB;EAGA,SAAK+P,kBAAL,GAA0BhW,UAAU,CAACqb,UAAX,CACxB14B,EADwB,EACpBA,EAAE,CAAC24B,YADiB,EACH,IAAIznC,YAAJ,CAAiBy3B,gBAAjB,CADG,EACiC,KAAKwN,UAAL,GAAkB,CAAlB,GAAsB,CADvD,EAEvB,KAAK7U,aAAL,CAA2BqW,qBAFJ,CAA1B;;EAIA,SAAKnG,YAAL;EACD,GAvBO;;EAyBA,sBAAA,GAAR;EACE;EACA;EACA,QAAI,KAAK0E,UAAL,KAAoB5F,SAAS,CAAC/T,SAAlC,EAA6C;EACrC,UAAAnM,KAAoB,KAAK2lB,SAAL,CAAexT,YAAf,CAA4B,KAAKqR,MAAjC,CAApB;EAAA,UAAE90B,KAAK,WAAP;EAAA,UAASC,MAAM,YAAf;;EACN,UAAM+5B,KAAK,GAAGh6B,KAAK,IAAIC,MAAT,IAAmBD,KAAK,GAAGC,MAAR,KAAmB,GAAtC,GAA4C,CAA5C,GAAgD,CAA9D;EAEA,WAAK6f,OAAL,CAAayT,SAAb,CAAuB,KAAKzT,OAAL,CAAald,kBAAb,CAAgC,KAAK4f,aAArC,EAAqD,QAArD,CAAvB,EAAuFwX,KAAvF;EACD,KALD,MAKO,IAAI,KAAK5C,UAAL,KAAoB5F,SAAS,CAAC9T,QAAlC,EAA4C;EAC3C,UAAAuN,KAAoB,KAAKgM,SAAL,CAAexT,YAAf,CAA4B,KAAKqR,MAAjC,CAApB;EAAA,UAAE90B,KAAK,WAAP;EAAA,UAASC,MAAM,YAAf;;EACN,UAAMirB,gBAAgB,GAAGlrB,KAAK,IAAIC,MAAT,IAAmBD,KAAK,GAAGC,MAApD;;EAEA,WAAKg3B,SAAL,CAAegD,gBAAf,CAAgC;EAAC/O,QAAAA,gBAAgB;EAAjB,OAAhC;EACD;EAGD;;;EACA,SAAKgP,YAAL;;EAEA,SAAKjD,SAAL,CAAetW,WAAf,CACE,KAAKb,OADP,EAEE,KAAKW,OAFP,EAGE,KAAKqU,MAHP,EAIE,KAAKC,YAJP;;EAMA,SAAKpC,gBAAL,GAAwB,IAAxB;EAEA,SAAKhmB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,QAAM,CAACsP,YAA1B,CAAb;EACD,GA5BO;;EA8BA,wBAAA,GAAR;EACE,SAAKuF,SAAL,CAAelQ,aAAf,CACE,KAAKjH,OADP,EAEE,KAAKgV,MAFP,EAGE,KAAKC,YAHP;EAKD,GANO;;EAQA,iBAAA,GAAR;EACE,QAAMQ,eAAe,GAAG,KAAKC,gBAA7B;EACA,QAAMtwB,GAAG,GAAGqwB,eAAe,CAAC4E,MAAhB,EAAZ;;EAEA,QAAI5E,eAAe,CAAC6E,0BAAhB,EAAJ,EAAkD;EAChD,UAAMvmC,UAAU,GAAG0hC,eAAe,CAAC8E,aAAhB,EAAnB;EAEA,WAAKC,oBAAL,CAA0BzmC,UAA1B,EAAsCqR,GAAtC;EACD,KAJD,MAIO;EACL,UAAMkT,QAAQ,GAAGmd,eAAe,CAACgF,WAAhB,EAAjB;EAEA,WAAKC,kBAAL,CAAwBpiB,QAAQ,CAAChD,GAAjC,EAAsCgD,QAAQ,CAACzC,KAA/C,EAAsDzQ,GAAtD;EACD;EACF,GAbO;;EA0CA,sBAAA,GAAR;EACE,QAAMhE,EAAE,GAAG,KAAK4e,OAAhB;EACA,QAAMje,OAAO,GAAG,KAAK2gB,aAArB;EAEA,QAAMgS,YAAY,GAAG,KAAKA,YAA1B;EACA,QAAMD,kBAAkB,GAAG,KAAKA,kBAAhC;EAEArzB,IAAAA,EAAE,CAACme,UAAH,CAAcne,EAAE,CAAC24B,YAAjB,EAA+BrF,YAA/B;EACAtzB,IAAAA,EAAE,CAACue,uBAAH,CAA4B5d,OAAe,CAAC62B,uBAA5C;EACAx3B,IAAAA,EAAE,CAACwe,mBAAH,CACG7d,OAAe,CAAC62B,uBADnB,EAC6ClE,YAAoB,CAACvV,QADlE,EAC4E/d,EAAE,CAACye,KAD/E,EACsF,KADtF,EAC6F,CAD7F,EACgG,CADhG;EAIAze,IAAAA,EAAE,CAACme,UAAH,CAAcne,EAAE,CAAC44B,oBAAjB,EAAuC,KAAKrX,WAA5C;EACAvhB,IAAAA,EAAE,CAACme,UAAH,CAAcne,EAAE,CAAC24B,YAAjB,EAA+BtF,kBAA/B;EACArzB,IAAAA,EAAE,CAACue,uBAAH,CAA4B5d,OAAe,CAACg3B,qBAA5C;EACA33B,IAAAA,EAAE,CAACwe,mBAAH,CACG7d,OAAe,CAACg3B,qBADnB,EAC2CtE,kBAA0B,CAACtV,QADtE,EACgF/d,EAAE,CAACye,KADnF,EAC0F,KAD1F,EACiG,CADjG,EACoG,CADpG;EAGD,GAnBO;;EAqBA,eAAA,GAAR;EACE,QAAI,KAAK8V,QAAL,IAAiB,KAAKR,WAA1B,EAAuC;EACrC,WAAKwF,cAAL;EACD;;EAED,SAAKxD,SAAL,CAAetM,MAAf,CAAsB;EACpBzpB,MAAAA,EAAE,EAAE,KAAK4e,OADW;EAEpB0C,MAAAA,aAAa,EAAE,KAAKA,aAFA;EAGpBC,MAAAA,WAAW,EAAE,KAAKA,WAHE;EAIpBC,MAAAA,QAAQ,EAAE,KAAKA,QAJK;EAKpBC,MAAAA,OAAO,EAAE,KAAKA;EALM,KAAtB;EAOD,GAZO;;EAcA,yBAAA,GAAR,UAAwBxQ,OAAxB;EAAA,oBAAA;;EACE,QAAMjR,EAAE,GAAG,KAAK4e,OAAhB;EACA,QAAM5b,MAAM,GAAG,KAAKA,MAApB;EACA,QAAMkuB,QAAQ,GAAG,KAAKC,SAAtB;EAEA,SAAKF,GAAL,GAAW/+B,eAAe,GACxB,IAAIsnC,SAAJ,CAAcvoB,OAAd,CADwB,GAExB,IAAIwoB,SAAJ,EAFF;EAIA,QAAMzI,EAAE,GAAG,KAAKC,GAAhB;EAEAC,IAAAA,QAAQ,CAACQ,IAAT;EACA,WAAO,IAAIpF,SAAJ,CAAY,UAAC0J,OAAD,EAAUzJ,MAAV;EACjByE,MAAAA,EAAE,CAACrE,cAAH,CAAkB3pB,MAAlB,EAA0BhD,EAA1B,EACG1N,IADH,CACQ;EACJ0+B,QAAAA,EAAE,CAACxD,cAAH,CAAkBnjB,KAAI,CAAC+mB,MAAvB;EACAF,QAAAA,QAAQ,CAACS,UAAT,CAAoBX,EAAE,CAACpS,OAAvB;EACAsS,QAAAA,QAAQ,CAACU,WAAT,CAAqBvnB,KAAI,CAACqvB,eAA1B;;EAEA,YAAI1oC,MAAJ,EAAY;EACVqZ,UAAAA,KAAI,CAACsvB,qBAAL;EACD;;EAEDtvB,QAAAA,KAAI,CAAConB,gBAAL,GAAwB,IAAxB;EACAP,QAAAA,QAAQ,CAACY,KAAT;EAEAkE,QAAAA,OAAO,CAAC,SAAD,CAAP;EACD,OAdH,EAeGxjC,KAfH,CAeS,UAAA6Y,CAAA;EACL2lB,QAAAA,EAAE,CAACnf,OAAH;EACAxH,QAAAA,KAAI,CAAC4mB,GAAL,GAAW,IAAX;EACAC,QAAAA,QAAQ,CAACY,KAAT;EAEAvF,QAAAA,MAAM,CAAClhB,CAAD,CAAN;EACD,OArBH;EAsBD,KAvBM,CAAP;EAwBD,GApCO;;EAsEA,+BAAA,GAAR;EACE,QAAMuuB,OAAO,GAAG,KAAKnG,QAArB;EAEA,QAAI,CAACmG,OAAL,EAAc;EAEd,SAAKlG,iBAAL,GAAyBkG,OAAO,CAACC,YAAR,CAAqB,OAArB,CAAzB;EACA,QAAMC,YAAY,GAAGF,OAAO,CAAChoC,KAA7B;EAEAkoC,IAAAA,YAAY,CAACh7B,KAAb,GAAqB,OAArB;EACAg7B,IAAAA,YAAY,CAAC/6B,MAAb,GAAsB,OAAtB;EACA+6B,IAAAA,YAAY,CAAC5xB,QAAb,GAAwB,OAAxB;EACA4xB,IAAAA,YAAY,CAACj4B,IAAb,GAAoB,GAApB;EACAi4B,IAAAA,YAAY,CAAC93B,GAAb,GAAmB,GAAnB;EACA83B,IAAAA,YAAY,CAACC,MAAb,GAAsB,MAAtB;EACD,GAdO;;EAgBA,uBAAA,GAAR;EACE,QAAMH,OAAO,GAAG,KAAKnG,QAArB;EACA,QAAMzwB,MAAM,GAAG,KAAKA,MAApB;EAEA,QAAI,CAAC42B,OAAL,EAAc;;EAEd,QAAI,KAAKlG,iBAAT,EAA4B;EAC1BkG,MAAAA,OAAO,CAACzqC,YAAR,CAAqB,OAArB,EAA8B,KAAKukC,iBAAnC;EACD,KAFD,MAEO;EACLkG,MAAAA,OAAO,CAACI,eAAR,CAAwB,OAAxB;EACD;;EAED,SAAKtG,iBAAL,GAAyB,IAAzB;;EAGA1wB,IAAAA,MAAM,CAACg3B,eAAP,CAAuB,OAAvB;;EACA,SAAKxG,sBAAL;EACD,GAjBO;;EA/1BMyG,EAAAA,wBAAA,GAAS/Y,QAAT;EACA+Y,EAAAA,4BAAA,GAAaze,YAAb;EAg3BhB,0BAAA;EAAC,EA/3B+B9O,UAAhC;;EClBA;;;;;;EAKA;;;EAAyBvC,EAAAA,6BAAA;EAgKvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuDA,qBAAA,CAAmB0mB,SAAnB,EAA2C5f,OAA3C;EAA2C,0BAAA,EAAA;EAAAA,MAAAA,YAAA;;;EAA3C,gBACE7G,WAAA,KAAA,SADF;;;EAIE,QAAI,CAACiT,UAAU,CAAC6c,gBAAX,EAAL,EAAoC;EAClC/2B,MAAAA,UAAU,CAAC;EACTkH,QAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAAC/E,KAA1B,EAAiC;EAC5CrsB,UAAAA,IAAI,EAAE0rB,UAAU,CAACE,QAD2B;EAE5CsH,UAAAA,OAAO,EAAE;EAFmC,SAAjC,CAAb;EAID,OALS,EAKP,CALO,CAAV;EAMA,aAAO3Y,KAAP;EACD;;EAED,QAAI,CAACgT,UAAU,CAAC8c,aAAX,EAAL,EAAiC;EAC/Bh3B,MAAAA,UAAU,CAAC;EACTkH,QAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAAC/E,KAA1B,EAAiC;EAC5CrsB,UAAAA,IAAI,EAAE0rB,UAAU,CAACC,cAD2B;EAE5CuH,UAAAA,OAAO,EAAE;EAFmC,SAAjC,CAAb;EAID,OALS,EAKP,CALO,CAAV;EAOA,aAAO3Y,KAAP;EACD;;EAED,QAAI,CAAC,CAAC4G,OAAO,CAAC9iB,KAAV,IAAmB,CAAC,CAAC8iB,OAAO,CAACvhB,KAAjC,EAAwC;EACtCyT,MAAAA,UAAU,CAAC;EACTkH,QAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAAC/E,KAA1B,EAAiC;EAC5CrsB,UAAAA,IAAI,EAAE0rB,UAAU,CAACK,gBAD2B;EAE5CmH,UAAAA,OAAO,EAAE;EAFmC,SAAjC,CAAb;EAID,OALS,EAKP,CALO,CAAV;EAMA,aAAO3Y,KAAP;EACD;EAGD;;;EACAlY,IAAAA,cAAc;EAEdkY,IAAAA,KAAI,CAAC+vB,UAAL,GAAkBvJ,SAAlB;EACAxmB,IAAAA,KAAI,CAACupB,MAAL,GAAc3iB,OAAO,CAAC9iB,KAAR,IAAsC8iB,OAAO,CAACvhB,KAA5D;EACA2a,IAAAA,KAAI,CAACkqB,QAAL,GAAgB,CAAC,CAACtjB,OAAO,CAACvhB,KAA1B;EACA2a,IAAAA,KAAI,CAACgwB,eAAL,GAAuBppB,OAAO,CAAC6L,cAAR,IAA0BV,eAAe,CAACC,eAAjE;EACAhS,IAAAA,KAAI,CAACiwB,cAAL,YACK;EACD;EACAnX,MAAAA,KAAK,EAAE9Y,KAAI,CAACgwB,eAAL,KAAyBje,eAAe,CAACE,OAAzC,GAAmD,QAAnD,GAA8D,QAFpE;EAGDsG,MAAAA,UAAU,EAAE;EACVE,QAAAA,cAAc,EAAE,KADN;EAEVC,QAAAA,QAAQ,EAAE;EAFA,OAHX;EAODgB,MAAAA,IAAI,EAAE;EAPL,OAQG9S,OAAO,CAAC8L,cAThB;EAWA1S,IAAAA,KAAI,CAAC8e,aAAL,GAAqBlY,OAAO,CAAC+L,YAAR,IAAwBN,aAAa,CAACC,UAA3D;;EAGAtS,IAAAA,KAAI,CAACkwB,MAAL,GAActpB,OAAO,CAACnS,KAAR,IAAiB5H,QAAQ,CAAChH,MAAM,CAACiB,gBAAP,CAAwB0/B,SAAxB,EAAmC/xB,KAApC,EAA2C,EAA3C,CAAvC;EACAuL,IAAAA,KAAI,CAACmwB,OAAL,GAAevpB,OAAO,CAAClS,MAAR,IAAkB7H,QAAQ,CAAChH,MAAM,CAACiB,gBAAP,CAAwB0/B,SAAxB,EAAmC9xB,MAApC,EAA4C,EAA5C,CAAzC;EAEA;;;;;;EAKAsL,IAAAA,KAAI,CAACowB,IAAL,GAAYxpB,OAAO,CAACiD,GAAR,IAAe,CAA3B;EACA7J,IAAAA,KAAI,CAACqwB,MAAL,GAAczpB,OAAO,CAACwD,KAAR,IAAiB,CAA/B;EACApK,IAAAA,KAAI,CAACswB,IAAL,GAAY1pB,OAAO,CAACjN,GAAR,IAAe,EAA3B;EAEAqG,IAAAA,KAAI,CAACuwB,SAAL,GAAiB3pB,OAAO,CAAC4D,QAAR,IAAoBxc,SAAS,CAACE,QAA/C;EACA8R,IAAAA,KAAI,CAAC8G,WAAL,GAAmB,IAAnB;EAEA9G,IAAAA,KAAI,CAACwwB,YAAL,GAAoBxwB,KAAI,CAACmwB,OAAL,KAAiB,CAAjB,GAAqBnwB,KAAI,CAACkwB,MAAL,GAAclwB,KAAI,CAACmwB,OAAxC,GAAkD,CAAtE;EAEAnwB,IAAAA,KAAI,CAACywB,YAAL,GAAoB7pB,OAAO,CAACgM,WAAR,IAAuBC,oBAA3C;EAEA,QAAMjI,QAAQ,GAAGhE,OAAO,CAACgE,QAAR,IAAoB,CAAC,EAAD,EAAK,GAAL,CAArC;EACA,QAAMH,cAAc,GAAGimB,UAAU,CAACC,sBAAX,CAAkC/pB,OAAO,CAAC6D,cAA1C,IACrB7D,OAAO,CAAC6D,cADa,GACIyG,eAAe,CAAC3jB,mBAD3C;;EAEA,QAAMqjC,cAAc,yBACfhqB,UACA;EACD/R,MAAAA,OAAO,EAAE2xB,SADR;EAED3c,MAAAA,GAAG,EAAE7J,KAAI,CAACowB,IAFT;EAGDhmB,MAAAA,KAAK,EAAEpK,KAAI,CAACqwB,MAHX;EAID12B,MAAAA,GAAG,EAAEqG,KAAI,CAACswB,IAJT;EAKD9lB,MAAAA,QAAQ,EAAExK,KAAI,CAACuwB,SALd;EAMD3lB,MAAAA,QAAQ,UANP;EAODC,MAAAA,WAAW,EAAE7K,KAAI,CAACwwB,YAPjB;EAQD/lB,MAAAA,cAAc;EARb,MAFL;;EAcAzK,IAAAA,KAAI,CAAC6wB,QAAL,GAAgB,KAAhB;;EAEA7wB,IAAAA,KAAI,CAAC8wB,oBAAL,CAA0BF,cAA1B;;EACA5wB,IAAAA,KAAI,CAAC+wB,aAAL,CAAmB/wB,KAAI,CAACowB,IAAxB,EAA8BpwB,KAAI,CAACqwB,MAAnC,EAA2CrwB,KAAI,CAACswB,IAAhD,EAAsDtwB,KAAI,CAACgwB,eAA3D,EAA4EhwB,KAAI,CAACiwB,cAAjF;;;EACD;EAvTD;;;;;;;;;EAKcS,EAAAA,sBAAA,GAAd;EACE,WAAO1d,UAAU,CAAC6c,gBAAX,MAAiC7c,UAAU,CAAC8c,aAAX,EAAxC;EACD,GAFa;EAId;;;;;;;EAKcY,EAAAA,2BAAA,GAAd;EACE,WAAO1d,UAAU,CAAC6c,gBAAX,EAAP;EACD,GAFa;EAId;;;;;;;EAKca,EAAAA,gCAAA,GAAd,UAAoC5O,QAApC;EACE,QAAI,CAAC56B,iBAAD,IAAsB46B,QAA1B,EAAoC;EAClCA,MAAAA,QAAQ,CAAC,KAAD,CAAR;EACA;EACD;;EAED,QAAIkP,oBAAJ;;EAEA,QAAMC,SAAS,GAAG;EAAM,aAAA,IAAIhP,SAAJ,CAAY,UAAA/5B,GAAA;EAClC8oC,QAAAA,oBAAoB,GAAG,UAAA5sB,YAAA;EACrB,cAAMzC,qBAAqB,GAAG,EAAEyC,YAAY,CAACxC,YAAb,CAA0BX,KAA1B,IAAmC,IAArC,CAA9B;EAEA/Y,UAAAA,GAAG,CAACyZ,qBAAD,CAAH;EACD,SAJD;;EAMA9b,QAAAA,MAAM,CAACib,gBAAP,CAAwB,cAAxB,EAAwCkwB,oBAAxC;EACD,OARuB,CAAA;EAQtB,KARF;;EAUA,QAAME,OAAO,GAAG;EAAM,aAAA,IAAIjP,SAAJ,CAAY,UAAA/5B,GAAA;EAChC4Q,QAAAA,UAAU,CAAC;EAAM,iBAAA5Q,GAAG,CAAC,KAAD,CAAH;EAAU,SAAjB,EAAmB,IAAnB,CAAV;EACD,OAFqB,CAAA;EAEpB,KAFF;;EAIA+5B,IAAAA,SAAO,CAACkP,IAAR,CAAa,CAACF,SAAS,EAAV,EAAcC,OAAO,EAArB,CAAb,EAAuCjpC,IAAvC,CAA4C,UAAC0Z,qBAAD;EAC1C9b,MAAAA,MAAM,CAACkb,mBAAP,CAA2B,cAA3B,EAA2CiwB,oBAA3C;;EAEA,UAAIlP,QAAJ,EAAc;EACZA,QAAAA,QAAQ,CAACngB,qBAAD,CAAR;EACD;;EAED+uB,MAAAA,UAAU,CAAC/uB,qBAAX,GAAmC,UAAAyvB,EAAA;EACjC,YAAIA,EAAJ,EAAQ;EACNA,UAAAA,EAAE,CAACzvB,qBAAD,CAAF;EACD;;EACD,eAAOA,qBAAP;EACD,OALD;EAMD,KAbD;EAcD,GApCa;;EAsCC+uB,EAAAA,iCAAA,GAAf,UAAsCvhB,SAAtC;EACE,WAAOA,SAAS,KAAKuhB,UAAU,CAACW,eAAX,CAA2BpjC,IAAzC,IACLkhB,SAAS,KAAKuhB,UAAU,CAACW,eAAX,CAA2BC,GADpC,IAELniB,SAAS,KAAKuhB,UAAU,CAACW,eAAX,CAA2BE,KAFpC,IAGLpiB,SAAS,KAAKuhB,UAAU,CAACW,eAAX,CAA2BG,GAH3C;EAID,GALc;EA4Pf;;;;;;;;;;;;EAUO,kBAAA,GAAP;EACE,QAAI,CAAC,KAAKtH,QAAV,EAAoB;EAClB,aAAO,IAAP;EACD;;EAED,WAAO,KAAKuH,oBAAL,CAA2BC,UAA3B,EAAP;EACD,GANM;EAQP;;;;;;;;;;;;;;;;;;;EAiBO,kBAAA,GAAP,UAAgBrsC,KAAhB,EAA6EgmB,KAA7E;EAA6E,wBAAA,EAAA;EAAAA,MAAAA,UAAA;;;EAK3E,QAAIhmB,KAAJ,EAAW;EACT,WAAKykC,QAAL,CAAczkC,KAAd,EAAqB;EACnBotB,QAAAA,cAAc,EAAEpH,KAAK,CAACoH,cADH;EAEnB8T,QAAAA,OAAO,EAAE,IAFU;EAGnB7T,QAAAA,aAAa,EAAErH,KAAK,CAACqH,aAHF;EAInBC,QAAAA,YAAY,EAAEtH,KAAK,CAACsH;EAJD,OAArB;EAMD;;EAED,WAAO,IAAP;EACD,GAfM;EAiBP;;;;;;;;;EAOO,kBAAA,GAAP;EACE,QAAI,KAAKuX,QAAT,EAAmB;EACjB,aAAO,IAAP;EACD;;EAED,WAAO,KAAKuH,oBAAL,CAA2BC,UAA3B,EAAP;EACD,GANM;EAQP;;;;;;;;;;;;;;;;;;;;EAkBO,kBAAA,GAAP,UAAgB5tC,KAAhB,EAA6EunB,KAA7E;EAA6E,wBAAA,EAAA;EAAAA,MAAAA,UAAA;;;EAM3E,QAAMqH,aAAa,YACd;EACDoG,MAAAA,KAAK,EAAE,QADN;EAEDP,MAAAA,UAAU,EAAE;EACVE,QAAAA,cAAc,EAAE,KADN;EAEVC,QAAAA,QAAQ,EAAE;EAFA,OAFX;EAMDgB,MAAAA,IAAI,EAAE;EANL,OAOGrO,KAAK,CAACqH,cARd;;EAUA,QAAMC,YAAY,GAAGtH,KAAK,CAACsH,YAAN,IAAsBN,aAAa,CAACC,UAAzD;EACA,QAAMiU,OAAO,GAAG,CAAC,CAAElb,KAAK,CAACkb,OAAzB;;EAEA,QAAI,KAAKgD,MAAL,IAAe,KAAKW,QAAL,KAAkB3D,OAArC,EAA8C;EAC5C;EACA/mB,MAAAA,OAAO,CAACmyB,IAAR,CAAa,iFAAb;EACA;;EACA,aAAO,IAAP;EACD;;EAED,QAAI7tC,KAAJ,EAAW;EACT,WAAK8tC,WAAL;;EAEA,WAAKrI,MAAL,GAAczlC,KAAd;EACA,WAAKomC,QAAL,GAAgB3D,OAAhB;EACA,WAAKyJ,eAAL,GAAuB3kB,KAAK,CAACoH,cAAN,IAAwBV,eAAe,CAACC,eAA/D;EACA,WAAKie,cAAL,GAAsBvd,aAAtB;EACA,WAAKoM,aAAL,GAAqBnM,YAArB;;EAEA,WAAKoe,aAAL,CAAmB,KAAKX,IAAxB,EAA8B,KAAKC,MAAnC,EAA2C,KAAKC,IAAhD,EAAsD,KAAKN,eAA3D,EAA4E,KAAKC,cAAjF;EACD;;EAED,WAAO,IAAP;EACD,GAvCM;EAyCP;;;;;;;;EAMO,oBAAA,GAAP,UAAkB1E,QAAlB;EACE,SAAKkG,oBAAL,CAA2BI,UAA3B,CAAsCtG,QAAtC;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;EAKO,2BAAA,GAAP;EACE,WAAO,KAAKyE,eAAZ;EACD,GAFM;EAIP;;;;;;;;;EAOO,sBAAA,GAAP;EACE,WAAO,IAAI/N,SAAJ,CAAY,UAAC0J,OAAD,EAAUzJ,MAAV;EACjB,UAAIh7B,iBAAiB,IAAI,OAAOA,iBAAiB,CAAC4qC,iBAAzB,KAA+C,UAAxE,EAAoF;EAClF5qC,QAAAA,iBAAiB,CAAC4qC,iBAAlB,GAAsC7pC,IAAtC,CAA2C,UAAA8pC,eAAA;EACzC,cAAIA,eAAe,KAAK,SAAxB,EAAmC;EACjCpG,YAAAA,OAAO;EACR,WAFD,MAEO;EACLzJ,YAAAA,MAAM,CAAC,IAAIC,KAAJ,CAAU,mBAAV,CAAD,CAAN;EACD;EACF,SAND,EAMGh6B,KANH,CAMS,UAAA6Y,CAAA;EACP;EACAkhB,UAAAA,MAAM,CAAClhB,CAAD,CAAN;EACD,SATD;EAUD,OAXD,MAWO;EACL2qB,QAAAA,OAAO;EACR;EACF,KAfM,CAAP;EAgBD,GAjBM;EAmBP;;;;;;;;EAMO,uBAAA,GAAP;EACE,WAAO,IAAP;EACD,GAFM;EAIP;;;;;;;;;;;;EAUO,iBAAA,GAAP,UAAe/kB,OAAf;EAAA,oBAAA;;EAAe,0BAAA,EAAA;EAAAA,MAAAA,YAAA;;;EAKb,QAAI,CAAC,KAAKiqB,QAAV,EAAoB;EAClB,aAAO5O,SAAO,CAACC,MAAR,CAAe,IAAIC,KAAJ,CAAU,wCAAV,CAAf,CAAP;EACD;;EAED,WAAO,IAAIF,SAAJ,CAAY,UAAC0J,OAAD,EAAUzJ,MAAV;EACjBliB,MAAAA,KAAI,CAACgyB,YAAL,GACG/pC,IADH,CACQ;EAAM,eAAA+X,KAAI,CAACyxB,oBAAL,CAA2BQ,OAA3B,CAAmCrrB,OAAnC,CAAA;EAA2C,OADzD,EAEG3e,IAFH,CAEQ,UAACC,GAAD;EAAiB,eAAAyjC,OAAO,CAACzjC,GAAD,CAAP;EAAY,OAFrC,EAGGC,KAHH,CAGS,UAAA6Y,CAAA;EAAK,eAAAkhB,MAAM,CAAClhB,CAAD,CAAN;EAAS,OAHvB;EAID,KALM,CAAP;EAMD,GAfM;EAiBP;;;;;;;EAKO,gBAAA,GAAP;EACE,SAAKywB,oBAAL,CAA2B1K,MAA3B;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;EAMO,oBAAA,GAAP,UAAkBzc,OAAlB;EACE,QAAI,OAAOA,OAAP,KAAmB,SAAvB,EAAkC;EAChC,WAAK2f,gBAAL,CAAuB7e,MAAvB,CAA8B,SAA9B,EAAyCd,OAAzC;EACD;;EAED,WAAO,IAAP;EACD,GANM;EAQP;;;;;;;;EAMO,wBAAA,GAAP,UAAsBC,WAAtB;EACE,SAAK0f,gBAAL,CAAuB7e,MAAvB,CAA8B,aAA9B,EAA6Cb,WAA7C;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;;;;;;;EAYO,qBAAA,GAAP,UAAmBC,QAAnB;EACE,SAAKyf,gBAAL,CAAuB7e,MAAvB,CAA8B,UAA9B,EAA0CZ,QAA1C;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;;;EAQO,qBAAA,GAAP,UAAmBmD,KAAnB;EACE,SAAKsc,gBAAL,CAAuB7e,MAAvB,CAA8B,UAA9B,EAA0CuC,KAA1C;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;;EAOO,qBAAA,GAAP;EACE,WAAO,KAAKsc,gBAAL,CAAuB7e,MAAvB,CAA8B,UAA9B,CAAP;EACD,GAFM;EAIP;;;;;;;;;;EAQO,kCAAA,GAAP,UAAgC4R,IAAhC;EAAgC,uBAAA,EAAA;EAAAA,MAAAA,SAAA;;;EAI9B,QAAI,CAAC,KAAK6T,QAAV,EAAoB;EAClB,aAAO,IAAP;EACD;;EAED,QAAIqB,aAAJ;;EAEA,QAAIlV,IAAI,CAACvoB,KAAL,KAAejE,SAAf,IAA4BwsB,IAAI,CAACtoB,MAAL,KAAgBlE,SAAhD,EAA2D;EACzD0hC,MAAAA,aAAa,GAAGrsC,MAAM,CAACiB,gBAAP,CAAwB,KAAKipC,UAA7B,CAAhB;EACD;;EAED,QAAMt7B,KAAK,GAAGuoB,IAAI,CAACvoB,KAAL,IAAc5H,QAAQ,CAACqlC,aAAa,CAACz9B,KAAf,EAAsB,EAAtB,CAApC;EACA,QAAMC,MAAM,GAAGsoB,IAAI,CAACtoB,MAAL,IAAe7H,QAAQ,CAACqlC,aAAa,CAACx9B,MAAf,EAAuB,EAAvB,CAAtC;;EAGA,QAAID,KAAK,KAAK,KAAKy7B,MAAf,IAAyBx7B,MAAM,KAAK,KAAKy7B,OAA7C,EAAsD;EACpD,aAAO,IAAP;EACD;;EAED,SAAKD,MAAL,GAAcz7B,KAAd;EACA,SAAK07B,OAAL,GAAez7B,MAAf;EAEA,SAAK87B,YAAL,GAAoB/7B,KAAK,GAAGC,MAA5B;;EACA,SAAK+8B,oBAAL,CAA2BxK,wBAA3B,CAAoDxyB,KAApD,EAA2DC,MAA3D;;EACA,SAAKu1B,gBAAL,CAAuB7e,MAAvB,CAA8B,aAA9B,EAA6C,KAAKolB,YAAlD;;EACA,SAAKvG,gBAAL,CAAuB9d,cAAvB,CAAsC;EAACzX,MAAAA,MAAM;EAAP,KAAtC;;EAEA,SAAKy9B,MAAL,CAAY,EAAZ,EAAgB,CAAhB;EACA,WAAO,IAAP;EACD,GAhCM;EAkCP;;;;;;EAIO,gBAAA,GAAP;EACE,WAAO,KAAK7B,IAAZ;EACD,GAFM;EAIP;;;;;;EAIO,gBAAA,GAAP;EACE,WAAO,KAAKF,IAAZ;EACD,GAFM;EAIP;;;;;;EAIO,kBAAA,GAAP;EACE,WAAO,KAAKC,MAAZ;EACD,GAFM;EAIP;;;;;;EAIO,qBAAA,GAAP;EACE,WAAO,KAAKpG,gBAAL,CAAuB7e,MAAvB,CAA8B,UAA9B,CAAP;EACD,GAFM;EAIP;;;;;;EAIO,uBAAA,GAAP;EACE,WAAO,KAAK6e,gBAAL,CAAuB7e,MAAvB,CAA8B,YAA9B,CAAP;EACD,GAFM;EAIP;;;;;;;;;;EAQO,qBAAA,GAAP,UAAmBV,QAAnB;EACE,SAAKuf,gBAAL,CAAuB7e,MAAvB,CAA8B,UAA9B,EAA0CV,QAA1C;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;;;EAQO,uBAAA,GAAP,UAAqBC,UAArB;EACE,SAAKsf,gBAAL,CAAuB7e,MAAvB,CAA8B,YAA9B,EAA4CT,UAA5C;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;EAMO,0BAAA,GAAP,UAAwBN,aAAxB;EACE,SAAK4f,gBAAL,CAAuB7e,MAAvB,CAA8B,eAA9B,EAA+Cf,aAA/C;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;;;;;;;;;;EAeO,gBAAA,GAAP,UAAclW,WAAd,EAIImY,QAJJ;EAII,2BAAA,EAAA;EAAAA,MAAAA,YAAA;;;EACF,QAAI,CAAC,KAAKukB,QAAV,EAAoB;EAClB,aAAO,IAAP;EACD;;EAED,QAAMhnB,GAAG,GAAG1V,WAAW,CAAC0V,GAAZ,KAAoBrZ,SAApB,GAAgC2D,WAAW,CAAC0V,GAA5C,GAAkD,KAAKumB,IAAnE;EACA,QAAMhmB,KAAK,GAAGjW,WAAW,CAACiW,KAAZ,KAAsB5Z,SAAtB,GAAkC2D,WAAW,CAACiW,KAA9C,GAAsD,KAAKimB,MAAzE;;EACA,QAAM1lB,UAAU,GAAG,KAAKsf,gBAAL,CAAuB7e,MAAvB,CAA8B,YAA9B,CAAnB;;EACA,QAAMgnB,oBAAoB,GAAGznB,UAAU,CAAC,CAAD,CAAV,GAAgBA,UAAU,CAAC,CAAD,CAAvD;EACA,QAAIhR,GAAG,GAAGxF,WAAW,CAACwF,GAAZ,KAAoBnJ,SAApB,GAAgC2D,WAAW,CAACwF,GAA5C,GAAkD,KAAK22B,IAAjE;;EAEA,QAAI8B,oBAAoB,GAAGz4B,GAA3B,EAAgC;EAC9BA,MAAAA,GAAG,GAAGy4B,oBAAN;EACD;;EAED,SAAKnI,gBAAL,CAAuBkI,MAAvB,CAA8B;EAACtoB,MAAAA,GAAG,KAAJ;EAAMO,MAAAA,KAAK,OAAX;EAAazQ,MAAAA,GAAG;EAAhB,KAA9B,EAAiD2S,QAAjD;;EAEA,QAAIA,QAAQ,KAAK,CAAjB,EAAoB;EAClB,WAAKmlB,oBAAL,CAA2BxC,kBAA3B,CAA8CplB,GAA9C,EAAmDO,KAAnD,EAA0DzQ,GAA1D;EACD;;EACD,WAAO,IAAP;EACD,GAzBM;EA2BP;;;;;;;;;;;;;;EAYO,2BAAA,GAAP,UAAyBwV,SAAzB;EACE,QAAIuhB,UAAU,CAACC,sBAAX,CAAkCxhB,SAAlC,CAAJ,EAAkD;EAChD,WAAK8a,gBAAL,CAAuB7e,MAAvB,CAA8B,gBAA9B,EAAgD+D,SAAhD;EACD;;EAED,WAAO,IAAP;EACD,GANM;EAQP;;;;;;;;;;;;;EAWO,2BAAA,GAAP;EACE,WAAO,KAAK8a,gBAAL,CAAuB7e,MAAvB,CAA8B,gBAA9B,CAAP;EACD,GAFM;EAIP;;;;;;;EAKO,iBAAA,GAAP;EACE,SAAKwmB,WAAL;;EAEA,QAAI,KAAK3H,gBAAT,EAA2B;EACzB,WAAKA,gBAAL,CAAsBziB,OAAtB;;EACA,WAAKyiB,gBAAL,GAAwB,IAAxB;EACD;;EAED,WAAO,IAAP;EACD,GATM;;;EAYC,uBAAA,GAAR,UACEpgB,GADF,EAEEO,KAFF,EAGEzQ,GAHF,EAIE8Y,cAJF,EAKEC,aALF;EAAA,oBAAA;;EAOE,SAAK+e,oBAAL,GAA4B,IAAI7B,iBAAJ,CAC1B,KAAKrG,MADqB,EAE1B,KAAK2G,MAFqB,EAG1B,KAAKC,OAHqB,EAI1B,KAAKjG,QAJqB,EAK1B,KAAK6F,UALqB,EAM1B,KAAKU,YANqB,EAO1B;EACE4B,MAAAA,UAAU,EAAExoB,GADd;EAEEyoB,MAAAA,YAAY,EAAEloB,KAFhB;EAGE1M,MAAAA,WAAW,EAAE/D,GAHf;EAIEowB,MAAAA,SAAS,EAAEtX,cAJb;EAKEC,MAAAA,aAAa,eALf;EAMEC,MAAAA,YAAY,EAAE,KAAKmM;EANrB,KAP0B,CAA5B;;EAgBA,SAAK2S,oBAAL,CAA0Bc,kBAA1B,CAA6C,KAAKtI,gBAAlD;;EAEA,SAAKuI,oBAAL;;EAEA,SAAKf,oBAAL,CACGrc,WADH,GAEGntB,IAFH,CAEQ;EAAM,aAAA+X,KAAI,CAACyyB,SAAL,EAAA;EAAgB,KAF9B,EAGGtqC,KAHH,CAGS;EACL6X,MAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAAC/E,KAA1B,EAAiC;EAC5CrsB,QAAAA,IAAI,EAAE0rB,UAAU,CAACI,iBAD2B;EAE5CoH,QAAAA,OAAO,EAAE;EAFmC,OAAjC,CAAb;EAID,KARH;EASD,GApCO;EAsCR;;;;;;;;;EAOQ,iCAAA,GAAR;EACE,QAAI,KAAKqX,eAAL,KAAyBU,UAAU,CAACgC,cAAX,CAA0BvgB,QAAvD,EAAiE;EAC/D;EACA,UAAMruB,KAAK,GAAG,KAAK2tC,oBAAL,CAA2BC,UAA3B,EAAd;;EACA,UAAI/R,gBAAgB,GAAG77B,KAAK,CAAC8zB,YAAN,GAAqB9zB,KAAK,CAACg0B,aAAlD;EACA,UAAI6a,OAAO,SAAX;EACA,UAAIC,MAAM,SAAV,CAL+D;;EAQ/D,UAAIjT,gBAAgB,GAAG,CAAvB,EAA0B;EACxB;EACAA,QAAAA,gBAAgB,GAAG,IAAIA,gBAAvB;EACD;;EAED,UAAIA,gBAAgB,GAAG,CAAvB,EAA0B;EACxBgT,QAAAA,OAAO,GAAGriB,IAAQ,CAAC7nB,QAAT,CAAkBk3B,gBAAlB,CAAV,CADwB;;EAGxBiT,QAAAA,MAAM,GAAGtiB,IAAQ,CAAC7nB,QAAT,CAAkB3C,IAAI,CAAC+sC,IAAL,CAAU,GAAV,CAAlB,IAAoC,CAA7C;EACD,OAJD,MAIO;EACLF,QAAAA,OAAO,GAAG,GAAV;EACAC,QAAAA,MAAM,GAAI,MAAMjT,gBAAhB,CAFK;EAGN,OApB8D;;;EAuB/D,UAAMmT,MAAM,GAAI,KAAK7I,gBAAL,CAAuB7e,MAAvB,CAA8B,UAA9B,CAAD,CAA4C,CAA5C,CAAf,CAvB+D;;;EA0B/D,WAAK6e,gBAAL,CAAuB7e,MAAvB,CAA8B;EAC5B,eAAOwnB,MADqB;EAE5B,oBAAY,CAAC,CAACD,OAAD,GAAW,CAAZ,EAAeA,OAAO,GAAG,CAAzB,CAFgB;EAG5B,sBAAc,CAAC,CAACC,MAAD,GAAU,CAAX,EAAcA,MAAM,GAAG,CAAvB,CAHc;EAI5B,oBAAY,CAACE,MAAD,EAASF,MAAT;EAJgB,OAA9B;;EAMA,WAAKT,MAAL,CAAY;EAACx4B,QAAAA,GAAG,EAAEi5B;EAAN,OAAZ;EACD;EACF,GAnCO;;EAqCA,8BAAA,GAAR;EAAA,oBAAA;;EACE,SAAKnB,oBAAL,CAA2BrsB,EAA3B,CAA8BwqB,iBAAiB,CAAC/Y,MAAlB,CAAyB/E,KAAvD,EAA8D,UAAA9Q,CAAA;EAC5DhB,MAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAAC/E,KAA1B,EAAiC9Q,CAAjC,CAAb;EACD,KAFD;;EAIA,SAAKywB,oBAAL,CAA2BrsB,EAA3B,CAA8BwqB,iBAAiB,CAAC/Y,MAAlB,CAAyBpF,sBAAvD,EAA+E;EAC7EzR,MAAAA,KAAI,CAAC4xB,WAAL;;EACA5xB,MAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAAC/E,KAA1B,EAAiC;EAC5CrsB,QAAAA,IAAI,EAAE0rB,UAAU,CAACM,sBAD2B;EAE5CkH,QAAAA,OAAO,EAAE;EAFmC,OAAjC,CAAb;EAID,KAND;EAOD,GAZO;;EAcA,8BAAA,GAAR,UAA6BiY,cAA7B;EAAA,oBAAA;;EACE,SAAK3G,gBAAL,GAAwB,IAAI/Y,eAAJ,CAAoB0f,cAApB,CAAxB;;EAEA,SAAK3G,gBAAL,CAAsB7kB,EAAtB,CAAyByR,iBAAM,CAAChF,aAAhC,EAA+C,UAAA7Q,CAAA;EAC7ChB,MAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAAChF,aAA1B,EAAyC7Q,CAAzC,CAAb;EACD,KAFD;;EAIA,SAAKipB,gBAAL,CAAsB7kB,EAAtB,CAAyB,QAAzB,EAAmC,UAAApE,CAAA;EACjChB,MAAAA,KAAI,CAACowB,IAAL,GAAYpvB,CAAC,CAAC6I,GAAd;EACA7J,MAAAA,KAAI,CAACqwB,MAAL,GAAcrvB,CAAC,CAACoJ,KAAhB;EACApK,MAAAA,KAAI,CAACswB,IAAL,GAAYtvB,CAAC,CAACrH,GAAd;EACAqG,MAAAA,KAAI,CAAC8G,WAAL,GAAmB9F,CAAC,CAAC1Y,UAArB;;EAEA0X,MAAAA,KAAI,CAACoB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAACjF,WAA1B,EAAuC;EAClD/H,QAAAA,GAAG,EAAE7I,CAAC,CAAC6I,GAD2C;EAElDO,QAAAA,KAAK,EAAEpJ,CAAC,CAACoJ,KAFyC;EAGlDzQ,QAAAA,GAAG,EAAEqH,CAAC,CAACrH,GAH2C;EAIlDrR,QAAAA,UAAU,EAAE0Y,CAAC,CAAC1Y,UAJoC;EAKlDshB,QAAAA,SAAS,EAAE5I,CAAC,CAAC4I;EALqC,OAAvC,CAAb;EAOD,KAbD;EAcD,GArBO;;EAuBA,mBAAA,GAAR;EACE,SAAK6nB,oBAAL,CAA2BsB,QAA3B,CAAoC,KAAKhD,UAAzC;;EACA,SAAK9F,gBAAL,CAAuBppB,MAAvB;;EAEA,SAAKomB,wBAAL;EAEA,SAAK4J,QAAL,GAAgB,IAAhB;;EAGA,SAAKmC,uBAAL;;EAEA,SAAK5xB,OAAL,CAAa,IAAIC,gBAAJ,CAAmBwV,iBAAM,CAAClF,KAA1B,CAAb;;EACA,SAAK8f,oBAAL,CAA2BwB,WAA3B;EACD,GAbO;EAeR;;;;;EAGQ,qBAAA,GAAR;EACE;EACA,QAAM5tC,KAAK,GAAG,KAAK6tC,QAAL,EAAd;;EACA,QAAI7tC,KAAJ,EAAW;EACTA,MAAAA,KAAK,CAAC8tC,KAAN;EACD;;EAED,QAAI,KAAKtC,QAAT,EAAmB;EACjB,WAAKY,oBAAL,CAA2B2B,UAA3B;;EACA,WAAKnJ,gBAAL,CAAuB3kB,OAAvB;;EACA,WAAKurB,QAAL,GAAgB,KAAhB;EACD;;EAED,QAAI,KAAKY,oBAAT,EAA+B;EAC7B,WAAKA,oBAAL,CAA0BjqB,OAA1B;;EACA,WAAKiqB,oBAAL,GAA4B,IAA5B;EACD;EACF,GAjBO;EAh3BR;;;;;;;;;;;;EAUcf,EAAAA,kBAAA,GAAU1tC,OAAV;EACA0tC,EAAAA,qBAAA,GAAavf,UAAb;EACAuf,EAAAA,iBAAA,GAAS7Z,iBAAT;EACA6Z,EAAAA,0BAAA,GAAkB3e,eAAlB;EACA2e,EAAAA,oBAAA,GAAY1iC,SAAZ;EAEd;;EACc0iC,EAAAA,yBAAA,GAAiB3e,eAAjB;EACA2e,EAAAA,wBAAA,GAAgBre,aAAhB;EAEd;;;;;;;EAMcqe,EAAAA,0BAAA,GAAkB;EAC9B;;;;;;;;;EASAziC,IAAAA,IAAI,EAAEijB,eAAe,CAAC9jB,oBAVQ;;EAW9B;;;;;;;;;EASAkkC,IAAAA,GAAG,EAAEpgB,eAAe,CAAC7jB,mBApBS;;EAqB9B;;;;;;;;;EASAkkC,IAAAA,KAAK,EAAErgB,eAAe,CAAC5jB,qBA9BO;;EA+B9B;;;;;;;;;EASAkkC,IAAAA,GAAG,EAAEtgB,eAAe,CAAC3jB;EAxCS,GAAlB;EAw2BhB,mBAAA;EAAC,EAv8BwB8U,UAAzB;;ECjDA;MAOMgxB,gBAAgB,GAAG;EACvB3C,EAAAA,UAAU,YADa;EAEvB1tC,EAAAA,OAAO;EAFgB;EAKzBC,KAAK,CAACowC,gBAAD,EAAmBC,SAAnB,CAAL;;;;;;;;"} \ No newline at end of file diff --git a/dist/PanoViewer/view360.panoviewer.pkgd.min.js b/dist/PanoViewer/view360.panoviewer.pkgd.min.js new file mode 100644 index 000000000..592e5bf5c --- /dev/null +++ b/dist/PanoViewer/view360.panoviewer.pkgd.min.js @@ -0,0 +1,10 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):((t="undefined"!=typeof globalThis?globalThis:t||self).eg=t.eg||{},t.eg.view360=e())}(this,function(){"use strict";var i="3.6.3",r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)};function s(t,e){function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var h=function(){return(h=Object.assign||function(t){for(var e,n=1,i=arguments.length;na[0]&&e[1]=t.length&&(t=void 0),{value:t&&t[i++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function f(){for(var t=[],e=0;e=t.length&&(t=void 0),{value:t&&t[i++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function u(){for(var t=[],e=0;e]*)>/)?((n=document.createElement("div")).innerHTML=t,nt(n.childNodes)):nt(document.querySelectorAll(t)),e||(n=1<=n.length?n[0]:void 0)):t!==at&&(!t.nodeName||1!==t.nodeType&&9!==t.nodeType)?"jQuery"in at&&t instanceof jQuery||t.constructor.prototype.jquery?n=e?t.toArray():t.get(0):Array.isArray(t)&&(n=t.map(function(t){return lt(t)}),e||(n=1<=n.length?n[0]:void 0)):n=t,n},dt=at.requestAnimationFrame||at.webkitRequestAnimationFrame,ft=at.cancelAnimationFrame||at.webkitCancelAnimationFrame;dt&&!ft?(it={},rt=dt,dt=function(e){var n=rt(function(t){it[n]&&e(t)});return it[n]=!0,n},ft=function(t){delete it[t]}):dt&&ft||(dt=function(t){return at.setTimeout(function(){t(at.performance&&at.performance.now&&at.performance.now()||(new Date).getTime())},16)},ft=at.clearTimeout);function _t(t,e){var n,i={};for(n in t)n&&(i[n]=e(t[n],n));return i}function vt(t,e){var n,i={};for(n in t)n&&e(t[n],n)&&(i[n]=t[n]);return i}function pt(t,e){for(var n in t)if(n&&!e(t[n],n))return!1;return!0}function gt(t,n){return pt(t,function(t,e){return t===n[e]})}function mt(t,e){return St[e]||(St[e]=Dt(e)),St[e](t)}function yt(t,n){return t&&n?_t(t,function(t,e){return mt(t,"number"==typeof n?n:n[e])}):t}function Et(t){if(!isFinite(t))return 0;var e=""+t;if(0<=e.indexOf("e")){for(var n=0,i=1;Math.round(t*i)/i!==t;)i*=10,n++;return n}return 0<=e.indexOf(".")?e.length-e.indexOf(".")-1:0}function xt(e){var n=!0;return Object.keys(ct).forEach(function(t){e&&e[t]===ct[t]||(n=!1)}),n}function wt(e,t,n){var i,r=((r={})[1]="auto",r[30]="none",r[24]="pan-x",r[6]="pan-y",r),o={};return e&&e.style&&(n=t.touchAction||r[n],i=ot(ot({},ct),{"touch-action":"none"===e.style["touch-action"]?"none":n}),Object.keys(i).forEach(function(t){o[t]=e.style[t],e.style[t]=i[t]})),o}function Tt(e,n){e&&e.style&&n&&Object.keys(n).forEach(function(t){e.style[t]=n[t]})}function Rt(t,e,n,i){return e=[!n[0]&&i?e[0]-i[0]:e[0],!n[1]&&i?e[1]+i[1]:e[1]],t=Math.max(e[0],t),t=Math.min(e[1],t)}function bt(t,e){return te[1]}function Pt(t,e,n){return n[1]&&t>e[1]||n[0]&&te.range[1]&&0!==e.bounce[1]?(t-e.range[1])/e.bounce[1]:0})},t}(),Vt=function(){function t(t){this._options=t,this._prevented=!1}var e=t.prototype;return e.isInterrupting=function(){return this._options.interruptable||this._prevented},e.isInterrupted=function(){return!this._options.interruptable&&this._prevented},e.setInterrupt=function(t){this._options.interruptable||(this._prevented=t)},t}(),Ft=function(){function t(t){var n=this;this._axis=t,this._complementOptions(),this._pos=Object.keys(this._axis).reduce(function(t,e){return t[e]=n._axis[e].range[0],t},{})}var e=t.prototype;return e.getDelta=function(t,e){var n=this.get(t);return _t(this.get(e),function(t,e){return t-n[e]})},e.get=function(t){var n=this;return t&&Array.isArray(t)?t.reduce(function(t,e){return e&&e in n._pos&&(t[e]=n._pos[e]),t},{}):ot(ot({},this._pos),t||{})},e.moveTo=function(n,i){void 0===i&&(i=this._pos);var t=_t(this._pos,function(t,e){return e in n&&e in i?n[e]-i[e]:0});return this.set(this.map(n,function(t,e){return e?Ct(t,e.range,e.circular):0})),{pos:ot({},this._pos),delta:t}},e.set=function(t){for(var e in t)e&&e in this._pos&&(this._pos[e]=t[e])},e.every=function(t,n){var i=this._axis;return pt(t,function(t,e){return n(t,i[e],e)})},e.filter=function(t,n){var i=this._axis;return vt(t,function(t,e){return n(t,i[e],e)})},e.map=function(t,n){var i=this._axis;return _t(t,function(t,e){return n(t,i[e],e)})},e.isOutside=function(t){return!this.every(t?this.get(t):this._pos,function(t,e){return!bt(t,e.range)})},e.getAxisOptions=function(t){return this._axis[t]},e._complementOptions=function(){var r=this;Object.keys(this._axis).forEach(function(i){r._axis[i]=ot({range:[0,100],bounce:[0,0],circular:[!1,!1]},r._axis[i]),["bounce","circular"].forEach(function(t){var e=r._axis,n=e[i][t];/string|number|boolean/.test(typeof n)&&(e[i][t]=[n,n])})})},t}(),Nt="ontouchstart"in at,kt="PointerEvent"in at,Ut="MSPointerEvent"in at,Qt=kt||Ut,Bt=function(){function t(){var e=this;this._stopContextMenu=function(t){t.preventDefault(),at.removeEventListener("contextmenu",e._stopContextMenu)}}var e=t.prototype;return e.extendEvent=function(t){var e=this.prevEvent,n=this._getCenter(t),i=e?this._getMovement(t):{x:0,y:0},r=e?this._getScale(t):1,o=e?(d=n.x-e.center.x,l=n.y-e.center.y,180*Math.atan2(l,d)/Math.PI):0,a=e?e.deltaX+i.x:i.x,s=e?e.deltaY+i.y:i.y,u=i.x,h=i.y,c=this._latestInterval,l=Date.now(),d=c?l-c.timestamp:0,i=e?e.velocityX:0,e=e?e.velocityY:0;return(!c||16<=d)&&(c&&(i=(d=[(a-c.deltaX)/d,(s-c.deltaY)/d])[0],e=d[1]),this._latestInterval={timestamp:l,deltaX:a,deltaY:s}),{srcEvent:t,scale:r,angle:o,center:n,deltaX:a,deltaY:s,offsetX:u,offsetY:h,velocityX:i,velocityY:e,preventSystemEvent:!0}},e._getDistance=function(t,e){var n=e.clientX-t.clientX,t=e.clientY-t.clientY;return Math.sqrt(n*n+t*t)},e._getButton=function(t){var e={1:st,2:"right",4:"middle"},t=this._isTouchEvent(t)?st:e[t.buttons];return t||null},e._isTouchEvent=function(t){return-1=n[e]-1e-6&&t<=n[e]+1e-6)return n[e];e=i._getRoundUnit(t,e);return mt(t,e)})},e._getRoundUnit=function(t,e){var n=this._options.round,i=null;return n||(e=this.axisManager.getAxisOptions(e),t=Math.max(Et(e.range[0]),Et(e.range[1]),Et(t)),i=1/Math.pow(10,t)),i||n},t}()),Ht=function(r){function t(t,e,n){void 0===t&&(t={}),void 0===e&&(e={}),void 0===n&&(n=null);var i=r.call(this)||this;return i.axis=t,i._inputs=[],i.options=ot({easing:function(t){return 1-Math.pow(1-t,3)},interruptable:!0,maximumDuration:1/0,minimumDuration:0,deceleration:6e-4,round:null,nested:!1},e),i.interruptManager=new Vt(i.options),i.axisManager=new Ft(i.axis),i.eventManager=new Lt(i),i.animationManager=new jt(i),i.inputObserver=new Yt(i),i.eventManager.setAnimationManager(i.animationManager),n&&i.eventManager.triggerChange(n),i}et(t,r);var e=t.prototype;return e.connect=function(t,e){t="string"==typeof t?t.split(" "):t.concat();return~this._inputs.indexOf(e)&&this.disconnect(e),e.mapAxes(t),e.connect(this.inputObserver),this._inputs.push(e),this},e.disconnect=function(t){return t?0<=(t=this._inputs.indexOf(t))&&(this._inputs[t].disconnect(),this._inputs.splice(t,1)):(this._inputs.forEach(function(t){return t.disconnect()}),this._inputs=[]),this},e.get=function(t){return this.axisManager.get(t)},e.setTo=function(t,e){return void 0===e&&(e=0),this.animationManager.setTo(t,e),this},e.setBy=function(t,e){return void 0===e&&(e=0),this.animationManager.setBy(t,e),this},e.stopAnimation=function(){return this.animationManager.stopAnimation(),this},e.updateAnimation=function(t){return this.animationManager.updateAnimation(t),this},e.isBounceArea=function(t){return this.axisManager.isOutside(t)},e.destroy=function(){this.disconnect(),this.eventManager.destroy()},t.VERSION="3.3.0",t.TRANSFORM=ht,t.DIRECTION_NONE=1,t.DIRECTION_LEFT=2,t.DIRECTION_RIGHT=4,t.DIRECTION_UP=8,t.DIRECTION_DOWN=16,t.DIRECTION_HORIZONTAL=6,t.DIRECTION_VERTICAL=24,t.DIRECTION_ALL=30,t}(t),z=function(){function t(t,e){var n=this;this.axes=[],this.element=null,this._enabled=!1,this._activeEvent=null,this._atRightEdge=!1,this._rightEdgeTimer=0,this._forceRelease=function(){var t=n._activeEvent,e=t.prevEvent;t.onRelease(),n._observer.release(n,e,[0,0]),n._detachWindowEvent(t)},this._voidFunction=function(){},this.element=lt(t),this.options=ot({inputType:["touch","mouse","pointer"],inputButton:[st],scale:[1,1],thresholdAngle:45,threshold:0,iOSEdgeSwipeThreshold:30,releaseOnScroll:!1,touchAction:null},e),this._onPanstart=this._onPanstart.bind(this),this._onPanmove=this._onPanmove.bind(this),this._onPanend=this._onPanend.bind(this)}var e=t.prototype;return e.mapAxes=function(t){var e=!!t[0],n=!!t[1];this._direction=e&&n?30:e?6:n?24:1,this.axes=t},e.connect=function(t){return this._activeEvent&&(this._detachElementEvent(),this._detachWindowEvent(this._activeEvent)),this._attachElementEvent(t),this._originalCssProps=wt(this.element,this.options,this._direction),this},e.disconnect=function(){return this._detachElementEvent(),this._detachWindowEvent(this._activeEvent),xt(this._originalCssProps)||Tt(this.element,this._originalCssProps),this._direction=1,this},e.destroy=function(){this.disconnect(),this.element=null},e.enable=function(){return this._enabled=!0,this},e.disable=function(){return this._enabled=!1,this},e.isEnabled=function(){return this._enabled},e._onPanstart=function(t){var e=this._activeEvent,n=e.onEventStart(t,this.options.inputButton);!n||!this._enabled||1window.innerWidth-t,this._attachWindowEvent(e),e.prevEvent=n)},e._onPanmove=function(t){var e=this,n=this._activeEvent,i=n.onEventMove(t,this.options.inputButton);if(i&&this._enabled&&!(1Math.abs(t.z)?Ye.set(-t.y,t.x,0):Ye.set(0,-t.z,t.y)):Ye.crossVectors(t,e),this.x=Ye.x,this.y=Ye.y,this.z=Ye.z,this.w=je,this.normalize(),this}};var tn,en,nn,rn,on,an,sn,un,hn,cn=null!==(Ut=null==B?void 0:B.userAgent)&&void 0!==Ut?Ut:"",ln=U.Util||{};function dn(t,e,n,i,r){c=t,a=i?i.fieldOfView:null,o=r.depthNear,h=r.depthFar,l=Math.tan(a?a.upDegrees*an:sn),u=Math.tan(a?a.downDegrees*an:sn),f=Math.tan(a?a.leftDegrees*an:sn),d=Math.tan(a?a.rightDegrees*an:sn),s=2/(f+d),a=2/(l+u),c[0]=s,c[1]=0,c[2]=0,c[3]=0,c[4]=0,c[5]=a,c[6]=0,c[7]=0,c[8]=-(f-d)*s*.5,c[9]=(l-u)*a*.5,c[10]=h/(o-h),c[11]=-1,c[12]=0,c[13]=0,c[14]=h*o/(o-h),c[15]=0;var o,a,s,u,h,c,l,d,f,_,v,p,g,m,y,E,x,w,T,R,b,P,C,M,A,I,t=n.orientation||un,r=n.position||hn;f=e,d=r,l=(s=t)[0],u=s[1],a=s[2],o=s[3],c=l*(h=l+l),r=l*(n=u+u),s=l*(t=a+a),l=u*n,u*=t,a*=t,h*=o,n*=o,t*=o,f[0]=1-(l+a),f[1]=r+t,f[2]=s-n,f[3]=0,f[4]=r-t,f[5]=1-(c+a),f[6]=u+h,f[7]=0,f[8]=s+n,f[9]=u-h,f[10]=1-(c+l),f[11]=0,f[12]=d[0],f[13]=d[1],f[14]=d[2],f[15]=1,i&&(b=A=e,R=i.offset,M=R[0],C=R[1],P=R[2],b===A?(A[12]=b[0]*M+b[4]*C+b[8]*P+b[12],A[13]=b[1]*M+b[5]*C+b[9]*P+b[13],A[14]=b[2]*M+b[6]*C+b[10]*P+b[14],A[15]=b[3]*M+b[7]*C+b[11]*P+b[15]):(_=b[0],g=b[1],E=b[2],w=b[3],v=b[4],m=b[5],I=b[6],T=b[7],p=b[8],y=b[9],x=b[10],R=b[11],A[0]=_,A[1]=g,A[2]=E,A[3]=w,A[4]=v,A[5]=m,A[6]=I,A[7]=T,A[8]=p,A[9]=y,A[10]=x,A[11]=R,A[12]=_*M+v*C+p*P+b[12],A[13]=g*M+m*C+y*P+b[13],A[14]=E*M+I*C+x*P+b[14],A[15]=w*M+T*C+R*P+b[15])),a=(t=r=e)[0],s=t[1],n=t[2],u=t[3],h=t[4],c=t[5],l=t[6],d=t[7],f=t[8],i=t[9],_=t[10],v=t[11],p=t[12],g=t[13],m=t[14],y=t[15],(t=(E=a*c-s*h)*(I=_*y-v*m)-(x=a*l-n*h)*(A=i*y-v*g)+(w=a*d-u*h)*(M=i*m-_*g)+(T=s*l-n*c)*(C=f*y-v*p)-(R=s*d-u*c)*(P=f*m-_*p)+(b=n*d-u*l)*(e=f*g-i*p))&&(t=1/t,r[0]=(c*I-l*A+d*M)*t,r[1]=(n*A-s*I-u*M)*t,r[2]=(g*b-m*R+y*T)*t,r[3]=(_*R-i*b-v*T)*t,r[4]=(l*C-h*I-d*P)*t,r[5]=(a*I-n*C+u*P)*t,r[6]=(m*w-p*b-y*x)*t,r[7]=(f*b-_*w+v*x)*t,r[8]=(h*A-c*C+d*e)*t,r[9]=(s*C-a*A-u*e)*t,r[10]=(p*R-g*w+y*E)*t,r[11]=(i*w-f*R-v*E)*t,r[12]=(c*P-h*M-l*e)*t,r[13]=(a*M-s*P+n*e)*t,r[14]=(g*x-p*T-m*E)*t,r[15]=(f*T-i*x+_*E)*t)}ln.MIN_TIMESTEP=.001,ln.MAX_TIMESTEP=1,ln.base64=function(t,e){return"data:"+t+";base64,"+e},ln.clamp=function(t,e,n){return Math.min(Math.max(e,t),n)},ln.lerp=function(t,e,n){return t+(e-t)*n},ln.isIOS=(tn=/iPad|iPhone|iPod/.test(null==B?void 0:B.platform),function(){return tn}),ln.isWebViewAndroid=(en=-1!==cn.indexOf("Version")&&-1!==cn.indexOf("Android")&&-1!==cn.indexOf("Chrome"),function(){return en}),ln.isSafari=(nn=/^((?!chrome|android).)*safari/i.test(cn),function(){return nn}),ln.isFirefoxAndroid=(rn=-1!==cn.indexOf("Firefox")&&-1!==cn.indexOf("Android"),function(){return rn}),ln.isR7=(on=-1!==cn.indexOf("R7 Build"),function(){return on}),ln.isLandscapeMode=function(){var t=90===U.orientation||-90===U.orientation;return ln.isR7()?!t:t},ln.isTimestampDeltaValid=function(t){return!isNaN(t)&&(!(t<=ln.MIN_TIMESTEP)&&!(t>ln.MAX_TIMESTEP))},ln.getScreenWidth=function(){return Math.max(U.screen.width,U.screen.height)*U.devicePixelRatio},ln.getScreenHeight=function(){return Math.min(U.screen.width,U.screen.height)*U.devicePixelRatio},ln.requestFullscreen=function(t){if(ln.isWebViewAndroid())return!1;if(t.requestFullscreen)t.requestFullscreen();else if(t.webkitRequestFullscreen)t.webkitRequestFullscreen();else if(t.mozRequestFullScreen)t.mozRequestFullScreen();else{if(!t.msRequestFullscreen)return!1;t.msRequestFullscreen()}return!0},ln.exitFullscreen=function(){if(Q.exitFullscreen)Q.exitFullscreen();else if(Q.webkitExitFullscreen)Q.webkitExitFullscreen();else if(Q.mozCancelFullScreen)Q.mozCancelFullScreen();else{if(!Q.msExitFullscreen)return!1;Q.msExitFullscreen()}return!0},ln.getFullscreenElement=function(){return Q.fullscreenElement||Q.webkitFullscreenElement||Q.mozFullScreenElement||Q.msFullscreenElement},ln.linkProgram=function(t,e,n,i){var r=t.createShader(t.VERTEX_SHADER);t.shaderSource(r,e),t.compileShader(r);e=t.createShader(t.FRAGMENT_SHADER);t.shaderSource(e,n),t.compileShader(e);var o,a=t.createProgram();for(o in t.attachShader(a,r),t.attachShader(a,e),i)t.bindAttribLocation(a,i[o],o);return t.linkProgram(a),t.deleteShader(r),t.deleteShader(e),a},ln.getProgramUniforms=function(t,e){for(var n={},i=t.getProgramParameter(e,t.ACTIVE_UNIFORMS),r="",o=0;oe[1]&&(i=e[1]),n!==i&&(o.setTo({fov:i},0),this._updateControlScale(),this.updatePanScale())),t.some(function(t){return"gyroMode"===t})&&q&&(this._axesTiltMotionInput&&(this._axes.disconnect(this._axesTiltMotionInput),this._axesTiltMotionInput.destroy(),this._axesTiltMotionInput=null),this._deviceQuaternion&&(this._deviceQuaternion.destroy(),this._deviceQuaternion=null),a?this._initDeviceQuaternion():s&&(this._axesTiltMotionInput=new mn(this._element),this._axes.connect(["yaw","pitch"],this._axesTiltMotionInput)),this._axesPanInput.setUseRotation(a)),t.some(function(t){return"useKeyboard"===t})&&(r.useKeyboard?o.connect(["yaw","pitch"],this._axesMoveKeyInput):o.disconnect(this._axesMoveKeyInput)),t.some(function(t){return"useZoom"===t})&&(a=r.useZoom,o.disconnect(this._axesWheelInput),a&&o.connect(["fov"],this._axesWheelInput)),this._togglePinchInputByOption(r.touchDirection,r.useZoom),t.some(function(t){return"touchDirection"===t})&&this._enabled&&this._enableTouch(u)},e._togglePinchInputByOption=function(t,e){this._axesPinchInput&&(this._axes.disconnect(this._axesPinchInput),e&&6===t&&-1===this._axes._inputs.indexOf(this._axesPinchInput)&&this._axes.connect(["fov"],this._axesPinchInput))},e._enableTouch=function(t){this._axesPanInput&&this._axes.disconnect(this._axesPanInput);var e=2&t?"yaw":null,t=4&t?"pitch":null;this._axes.connect([e,t],this._axesPanInput)},e._initDeviceQuaternion=function(){var e=this;this._deviceQuaternion=new Rn,this._deviceQuaternion.on("change",function(t){e._triggerChange(t)})},e._getValidYawRange=function(t,e,n){n=this._adjustAspectRatio(n||this.options.aspectRatio||1),n=(e||this._axes.get().fov)*n;return t[1]-t[0]>=n?t:this.options.yawRange||bn},e._getValidPitchRange=function(t,e){e=e||this._axes.get().fov;return t[1]-t[0]>=e?t:this.options.pitchRange||Pn},e._isCircular=function(t){return t[1]-t[0]<360?[!1,!1]:[!0,!0]},e._updateControlScale=function(t){var e=this.options,n=this._axes.get().fov,i=this._updatePitchRange(e.pitchRange,n,e.showPolePoint),r=this._updateYawRange(e.yawRange,n,e.aspectRatio),n=this._axes.get(),e=n.yaw,n=n.pitch;return ke(this._axes.axis.yaw.range,r),ke(this._axes.axis.pitch.range,i),this._axes.axis.yaw.circular=this._isCircular(r),this._axes.axis.pitch.circular=this._isCircular(i),er[1]&&(e=r[1]),ni[1]&&(n=i[1]),t&&t.set({yaw:e,pitch:n}),this._axes.setTo({yaw:e,pitch:n},0),this},e._updatePitchRange=function(t,e,n){if(this.options.gyroMode===Je.VR)return Cn;var i=t[1]-t[0],e=e/2;return!n||i<180?[t[0]+e,t[1]-e]:t.concat()},e._updateYawRange=function(t,e,n){if(this.options.gyroMode===Je.VR)return bn;if(360<=t[1]-t[0])return t.concat();e=We.toDegree(Math.atan2(n,1/Math.tan(e/2*te)));return[t[0]+e,t[1]-e]},e._triggerChange=function(t){var e=this._axes.get(),n=this.options,t={targetElement:n.element,isTrusted:t.isTrusted,yaw:e.yaw,pitch:e.pitch,fov:e.fov,quaternion:null};n.gyroMode===Je.VR&&this._deviceQuaternion&&(t.quaternion=this._deviceQuaternion.getCombinedQuaternion(e.yaw)),this.trigger(new p("change",t))},e._adjustAspectRatio=function(t){for(var e=[.52,.54,.563,.57,.584,.59,.609,.67,.702,.72,.76,.78,.82,.92,.97,1,1.07,1.14,1.19,1.25,1.32,1.38,1.4,1.43,1.53,1.62,1.76,1.77,1.86,1.96,2.26,2.3,2.6,3,5,6],n=[.51,.54,.606,.56,.628,.63,.647,.71,.736,.757,.78,.77,.8,.89,.975,1,1.07,1.1,1.15,1.18,1.22,1.27,1.3,1.33,1.39,1.45,1.54,1.55,1.58,1.62,1.72,1.82,1.92,2,2.24,2.3],i=-1,r=0;r=t.length&&(t=void 0),{value:t&&t[i++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}(a),h=u.next();!h.done;h=u.next()){if(h.value===e){a.splice(s,1);break}s++}}catch(t){n={error:t}}finally{try{h&&!h.done&&(i=u.return)&&i.call(u)}finally{if(n)throw n.error}}}return this},t.VERSION="2.2.2",t}(),In=function(t,e){return(In=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])})(t,e)};function On(t,e){function n(){this.constructor=t}In(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var Sn=function(){return(Sn=Object.assign||function(t){for(var e,n=1,i=arguments.length;n= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"},n.getVertexPositionData=function(){return this._vertices||(this._vertices=[1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1]),this._vertices},n.getIndexData=function(){var n=this;return function(){for(var t=[],e=0;e(target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","/**\n * Original Code\n * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js\n * Math Util\n * modified by egjs\n */\n/**\n * @fileoverview gl-matrix - High performance matrix and vector operations\n * @author Brandon Jones\n * @author Colin MacKenzie IV\n * @version 2.3.2\n */\n\n/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE. */\n\n// Some minimal math functionality borrowed from gl-Matrix and stripped down\n// for the purposes of this library.\n\nimport { vec2, vec3, quat } from \"gl-matrix\";\n\nimport { ValueOf } from \"../types/internal\";\n\nconst quatToVec3 = (quaternion: quat) => {\n const baseV = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(baseV, baseV, quaternion);\n return baseV;\n};\n\nconst toDegree = (a: number) => a * 180 / Math.PI;\n\nconst util: any = {};\n\nutil.isPowerOfTwo = (n: number) => n && (n & (n - 1)) === 0;\n\nutil.extractPitchFromQuat = (quaternion: quat) => {\n const baseV = quatToVec3(quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n};\n\nutil.hypot = Math.hypot || ((x: number, y: number) => Math.sqrt(x * x + y * y));\n\n// implement reference\n// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식\n// calculating angle between two vectors : http://darkpgmr.tistory.com/121\nconst ROTATE_CONSTANT: {\n PITCH_DELTA: 1;\n YAW_DELTA_BY_ROLL: 2;\n YAW_DELTA_BY_YAW: 3;\n} = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n};\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nconst getRotationDelta = (prevQ: quat, curQ: quat, rotateKind: ValueOf) => {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n // const coefficientD = -1 * vec3.dot(vecN, meshPoint1);\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance =\n coefficientA * crossVec[0] +\n coefficientB * crossVec[1] +\n coefficientC * crossVec[2];\n\n let thetaDirection;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return toDegree(deltaRadian);\n};\n\nconst angleBetweenVec2 = (v1: vec2, v2: vec2) => {\n const det = v1[0] * v2[1] - v2[0] * v1[1];\n const theta = -Math.atan2(det, vec2.dot(v1, v2));\n return theta;\n};\n\nutil.yawOffsetBetween = (viewDir: number, targetDir: number) => {\n const viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]);\n const targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]);\n\n vec2.normalize(viewDirXZ, viewDirXZ);\n vec2.normalize(targetDirXZ, targetDirXZ);\n\n const theta = -angleBetweenVec2(viewDirXZ, targetDirXZ);\n\n return theta;\n};\n\nutil.sign = (x: number) => Math.sign\n ? Math.sign(x)\n : (Number(x > 0) - Number(x < 0)) || +x;\n\nutil.toDegree = toDegree;\nutil.getRotationDelta = getRotationDelta;\nutil.angleBetweenVec2 = angleBetweenVec2;\n\nexport {\n util,\n ROTATE_CONSTANT\n};\n","import { userAgent } from \"../utils/browserFeature\";\n/**\n * Returns a number value indiciating the version of Chrome being used,\n * or otherwise `null` if not on Chrome.\n *\n * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19\n */\n/**\n * In Chrome m65, `devicemotion` events are broken but subsequently fixed\n * in 65.0.3325.148. Since many browsers use Chromium, ensure that\n * we scope this detection by branch and build numbers to provide\n * a proper fallback.\n * https://github.com/immersive-web/webvr-polyfill/issues/307\n */\nlet version = -1; // It should not be null because it will be compared with number\nlet branch: string | null = null;\nlet build: string | null = null;\n\nconst match = /Chrome\\/([0-9]+)\\.(?:[0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(userAgent);\n\nif (match) {\n version = parseInt(match[1], 10);\n branch = match[2];\n build = match[3];\n}\n\nconst CHROME_VERSION = version;\nconst IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === \"3325\" && parseInt(build!, 10) < 148;\nconst IS_ANDROID = /Android/i.test(userAgent);\n\nconst CONTROL_MODE_VR = 1;\nconst CONTROL_MODE_YAWPITCH = 2;\n\nconst TOUCH_DIRECTION_NONE = 1;\nconst TOUCH_DIRECTION_YAW = 2;\nconst TOUCH_DIRECTION_PITCH = 4;\nconst TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH;\n\n/* Const for MovableCoord */\nconst MC_DECELERATION = 0.0014;\nconst MC_MAXIMUM_DURATION = 1000;\nconst MC_BIND_SCALE = [0.20, 0.20];\n\nconst MIN_FIELD_OF_VIEW = 20;\nconst MAX_FIELD_OF_VIEW = 110;\nconst PAN_SCALE = 320;\n\n// const DELTA_THRESHOLD = 0.015;\n// const DELTA_THRESHOLD = 0.09; // Note4\n// const DELTA_THRESHOLD = 0.0825;\n// const DELTA_THRESHOLD = 0.075;\n// const DELTA_THRESHOLD = 0.06;\n// const DELTA_THRESHOLD = 0.045;\nconst DELTA_THRESHOLD = 0.0375; // Note2\n\nconst YAW_RANGE_HALF = 180;\nconst PITCH_RANGE_HALF = 90;\nconst CIRCULAR_PITCH_RANGE_HALF = 180;\nconst PINCH_EVENTS = \"pinchstart pinchmove pinchend\";\n\nconst KEYMAP = {\n LEFT_ARROW: 37,\n A: 65,\n UP_ARROW: 38,\n W: 87,\n RIGHT_ARROW: 39,\n D: 68,\n DOWN_ARROW: 40,\n S: 83\n};\n\nconst GYRO_MODE: {\n NONE: \"none\";\n YAWPITCH: \"yawPitch\";\n VR: \"VR\";\n} = {\n NONE: \"none\",\n YAWPITCH: \"yawPitch\",\n VR: \"VR\"\n};\n\nexport {\n GYRO_MODE,\n\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n\n TOUCH_DIRECTION_NONE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MIN_FIELD_OF_VIEW,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n DELTA_THRESHOLD,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n PINCH_EVENTS,\n KEYMAP,\n\n CHROME_VERSION,\n IS_CHROME_WITHOUT_DEVICE_MOTION,\n IS_ANDROID\n};\n","/* eslint-disable */\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { window as win } from \"../../../../utils/browser\";\n\nconst MathUtil = win.MathUtil || {};\n\nMathUtil.degToRad = Math.PI / 180;\nMathUtil.radToDeg = 180 / Math.PI;\n\n// Some minimal math functionality borrowed from THREE.Math and stripped down\n// for the purposes of this library.\n\n\nMathUtil.Vector2 = function( x, y ) {\n this.x = x || 0;\n this.y = y || 0;\n};\n\nMathUtil.Vector2.prototype = {\n constructor: MathUtil.Vector2,\n\n set: function( x, y ) {\n this.x = x;\n this.y = y;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n },\n\n subVectors: function( a, b ) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n\n return this;\n }\n};\n\nMathUtil.Vector3 = function( x, y, z ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n};\n\nMathUtil.Vector3.prototype = {\n constructor: MathUtil.Vector3,\n\n set: function( x, y, z ) {\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n\n return this;\n },\n\n length: function() {\n return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n },\n\n normalize: function() {\n const scalar = this.length();\n\n if ( scalar !== 0 ) {\n const invScalar = 1 / scalar;\n\n this.multiplyScalar(invScalar);\n } else {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n }\n\n return this;\n },\n\n multiplyScalar: function( scalar ) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n },\n\n applyQuaternion: function( q ) {\n const x = this.x;\n const y = this.y;\n const z = this.z;\n\n const qx = q.x;\n const qy = q.y;\n const qz = q.z;\n const qw = q.w;\n\n // calculate quat * vector\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = - qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n return this;\n },\n\n dot: function( v ) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n },\n\n crossVectors: function( a, b ) {\n const ax = a.x;\n const ay = a.y;\n const az = a.z;\n const bx = b.x;\n const by = b.y;\n const bz = b.z;\n\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n\n return this;\n }\n};\n\nMathUtil.Quaternion = function( x, y, z, w ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n this.w = ( w !== undefined ) ? w : 1;\n};\n\nMathUtil.Quaternion.prototype = {\n constructor: MathUtil.Quaternion,\n\n set: function( x, y, z, w ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n\n return this;\n },\n\n copy: function( quaternion ) {\n this.x = quaternion.x;\n this.y = quaternion.y;\n this.z = quaternion.z;\n this.w = quaternion.w;\n\n return this;\n },\n\n setFromEulerXYZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 + s1 * s2 * c3;\n this.w = c1 * c2 * c3 - s1 * s2 * s3;\n\n return this;\n },\n\n setFromEulerYXZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 - s1 * s2 * c3;\n this.w = c1 * c2 * c3 + s1 * s2 * s3;\n\n return this;\n },\n\n setFromAxisAngle: function( axis, angle ) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n // assumes axis is normalized\n\n const halfAngle = angle / 2;\n const s = Math.sin( halfAngle );\n\n this.x = axis.x * s;\n this.y = axis.y * s;\n this.z = axis.z * s;\n this.w = Math.cos( halfAngle );\n\n return this;\n },\n\n multiply: function( q ) {\n return this.multiplyQuaternions( this, q );\n },\n\n multiplyQuaternions: function( a, b ) {\n // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n const qax = a.x;\n const qay = a.y;\n const qaz = a.z;\n const qaw = a.w;\n const qbx = b.x;\n const qby = b.y;\n const qbz = b.z;\n const qbw = b.w;\n\n this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n return this;\n },\n\n inverse: function() {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n\n this.normalize();\n\n return this;\n },\n\n normalize: function() {\n let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n if ( l === 0 ) {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n this.w = 1;\n } else {\n l = 1 / l;\n\n this.x = this.x * l;\n this.y = this.y * l;\n this.z = this.z * l;\n this.w = this.w * l;\n }\n\n return this;\n },\n\n slerp: function( qb, t ) {\n if ( t === 0 ) return this;\n if ( t === 1 ) return this.copy( qb );\n\n const x = this.x;\n const y = this.y;\n const z = this.z;\n const w = this.w;\n\n // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n let cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;\n\n if ( cosHalfTheta < 0 ) {\n this.w = - qb.w;\n this.x = - qb.x;\n this.y = - qb.y;\n this.z = - qb.z;\n\n cosHalfTheta = - cosHalfTheta;\n } else {\n this.copy( qb );\n }\n\n if ( cosHalfTheta >= 1.0 ) {\n this.w = w;\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n }\n\n const halfTheta = Math.acos( cosHalfTheta );\n const sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n if ( Math.abs( sinHalfTheta ) < 0.001 ) {\n this.w = 0.5 * ( w + this.w );\n this.x = 0.5 * ( x + this.x );\n this.y = 0.5 * ( y + this.y );\n this.z = 0.5 * ( z + this.z );\n\n return this;\n }\n\n const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;\n const ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n this.w = ( w * ratioA + this.w * ratioB );\n this.x = ( x * ratioA + this.x * ratioB );\n this.y = ( y * ratioA + this.y * ratioB );\n this.z = ( z * ratioA + this.z * ratioB );\n\n return this;\n },\n\n setFromUnitVectors: function() {\n // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n // assumes direction vectors vFrom and vTo are normalized\n\n let v1;\n let r;\n const EPS = 0.000001;\n\n return function( vFrom, vTo ) {\n if ( v1 === undefined ) v1 = new MathUtil.Vector3();\n\n r = vFrom.dot( vTo ) + 1;\n\n if ( r < EPS ) {\n r = 0;\n\n if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n v1.set( - vFrom.y, vFrom.x, 0 );\n } else {\n v1.set( 0, - vFrom.z, vFrom.y );\n }\n } else {\n v1.crossVectors( vFrom, vTo );\n }\n\n this.x = v1.x;\n this.y = v1.y;\n this.z = v1.z;\n this.w = r;\n\n this.normalize();\n\n return this;\n };\n }()\n};\n\nexport default MathUtil;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tslint:disable: only-arrow-functions\n\nimport { window as win, document as doc, navigator as nav } from \"../../../../utils/browser\";\n\nconst userAgent = nav?.userAgent ?? \"\";\nconst Util = (win ).Util || {};\n\nUtil.MIN_TIMESTEP = 0.001;\nUtil.MAX_TIMESTEP = 1;\n\nUtil.base64 = function(mimeType, base64) {\n return \"data:\" + mimeType + \";base64,\" + base64;\n};\n\nUtil.clamp = function(value, min, max) {\n return Math.min(Math.max(min, value), max);\n};\n\nUtil.lerp = function(a, b, t) {\n return a + ((b - a) * t);\n};\n\nUtil.isIOS = (function() {\n const isIOS = /iPad|iPhone|iPod/.test(nav?.platform);\n return function() {\n return isIOS;\n };\n})();\n\nUtil.isWebViewAndroid = (function() {\n const isWebViewAndroid = userAgent.indexOf(\"Version\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1 &&\n userAgent.indexOf(\"Chrome\") !== -1;\n return function() {\n return isWebViewAndroid;\n };\n})();\n\nUtil.isSafari = (function() {\n const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n return function() {\n return isSafari;\n };\n})();\n\nUtil.isFirefoxAndroid = (function() {\n const isFirefoxAndroid = userAgent.indexOf(\"Firefox\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1;\n return function() {\n return isFirefoxAndroid;\n };\n})();\n\nUtil.isR7 = (function() {\n const isR7 = userAgent.indexOf(\"R7 Build\") !== -1;\n return function() {\n return isR7;\n };\n})();\n\nUtil.isLandscapeMode = function() {\n const rtn = (win.orientation === 90 || win.orientation === -90);\n return Util.isR7() ? !rtn : rtn;\n};\n\n// Helper method to validate the time steps of sensor timestamps.\nUtil.isTimestampDeltaValid = function(timestampDeltaS) {\n if (isNaN(timestampDeltaS)) {\n return false;\n }\n if (timestampDeltaS <= Util.MIN_TIMESTEP) {\n return false;\n }\n if (timestampDeltaS > Util.MAX_TIMESTEP) {\n return false;\n }\n return true;\n};\n\nUtil.getScreenWidth = function() {\n return Math.max(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.getScreenHeight = function() {\n return Math.min(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.requestFullscreen = function(element) {\n if (Util.isWebViewAndroid()) {\n return false;\n }\n if (element.requestFullscreen) {\n element.requestFullscreen();\n } else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n } else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n } else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.exitFullscreen = function() {\n if (doc.exitFullscreen) {\n doc.exitFullscreen();\n } else if (doc.webkitExitFullscreen) {\n doc.webkitExitFullscreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.getFullscreenElement = function() {\n return doc.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n};\n\nUtil.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {\n // No error checking for brevity.\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n const program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n\n for (const attribName in attribLocationMap)\n gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);\n\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n};\n\nUtil.getProgramUniforms = function(gl, program) {\n const uniforms = {};\n const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n let uniformName = \"\";\n for (let i = 0; i < uniformCount; i++) {\n const uniformInfo = gl.getActiveUniform(program, i);\n uniformName = uniformInfo.name.replace(\"[0]\", \"\");\n uniforms[uniformName] = gl.getUniformLocation(program, uniformName);\n }\n return uniforms;\n};\n\nUtil.orthoMatrix = function(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right);\n const bt = 1 / (bottom - top);\n const nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n};\n\nUtil.copyArray = function(source, dest) {\n for (let i = 0, n = source.length; i < n; i++) {\n dest[i] = source[i];\n }\n};\n\nUtil.isMobile = function() {\n let check = false;\n (function(a) {\n if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))check = true;\n })(userAgent || nav?.vendor || win.opera);\n return check;\n};\n\nUtil.extend = function(dest, src) {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n dest[key] = src[key];\n }\n }\n\n return dest;\n};\n\nUtil.safariCssSizeWorkaround = function(canvas) {\n // TODO(smus): Remove this workaround when Safari for iOS is fixed.\n // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).\n //\n // \"To the last I grapple with thee;\n // from hell's heart I stab at thee;\n // for hate's sake I spit my last breath at thee.\"\n // -- Moby Dick, by Herman Melville\n if (Util.isIOS()) {\n const width = canvas.style.width;\n const height = canvas.style.height;\n canvas.style.width = (parseInt(width) + 1) + \"px\";\n canvas.style.height = (parseInt(height)) + \"px\";\n setTimeout(function() {\n canvas.style.width = width;\n canvas.style.height = height;\n }, 100);\n }\n\n // Debug only.\n win.Util = Util;\n win.canvas = canvas;\n};\n\nUtil.isDebug = function() {\n return Util.getQueryParameter(\"debug\");\n};\n\nUtil.getQueryParameter = function(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n const results = regex.exec(location.search);\n return results === null ? \"\" : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n};\n\nUtil.frameDataFromPose = (function() {\n const piOver180 = Math.PI / 180.0;\n const rad45 = Math.PI * 0.25;\n\n // Borrowed from glMatrix.\n function mat4_perspectiveFromFieldOfView(out, fov, near, far) {\n const upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45);\n const downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45);\n const leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45);\n const rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45);\n const xScale = 2.0 / (leftTan + rightTan);\n const yScale = 2.0 / (upTan + downTan);\n\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = ((upTan - downTan) * yScale * 0.5);\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = (far * near) / (near - far);\n out[15] = 0.0;\n return out;\n }\n\n function mat4_fromRotationTranslation(out, q, v) {\n // Quaternion math\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n\n return out;\n }\n\n function mat4_translate(out, a, v) {\n const x = v[0];\n const y = v[1];\n const z = v[2];\n let a00;\n let a01;\n let a02;\n let a03;\n let a10;\n let a11;\n let a12;\n let a13;\n let a20;\n let a21;\n let a22;\n let a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];\n a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];\n a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];\n\n out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;\n out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;\n out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;\n\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n }\n\n function mat4_invert(out, a) {\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n }\n\n const defaultOrientation = new Float32Array([0, 0, 0, 1]);\n const defaultPosition = new Float32Array([0, 0, 0]);\n\n function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {\n mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);\n\n const orientation = pose.orientation || defaultOrientation;\n const position = pose.position || defaultPosition;\n\n mat4_fromRotationTranslation(view, orientation, position);\n if (parameters)\n mat4_translate(view, view, parameters.offset);\n mat4_invert(view, view);\n }\n\n return function(frameData, pose, vrDisplay) {\n if (!frameData || !pose)\n return false;\n\n frameData.pose = pose;\n frameData.timestamp = pose.timestamp;\n\n updateEyeMatrices(\n frameData.leftProjectionMatrix, frameData.leftViewMatrix,\n pose, vrDisplay.getEyeParameters(\"left\"), vrDisplay);\n updateEyeMatrices(\n frameData.rightProjectionMatrix, frameData.rightViewMatrix,\n pose, vrDisplay.getEyeParameters(\"right\"), vrDisplay);\n\n return true;\n };\n})();\n\nUtil.isInsideCrossDomainIFrame = function() {\n const isFramed = (win.self !== win.top);\n const refDomain = Util.getDomainFromUrl(doc.referrer);\n const thisDomain = Util.getDomainFromUrl(win.location.href);\n\n return isFramed && (refDomain !== thisDomain);\n};\n\n// From http://stackoverflow.com/a/23945027.\nUtil.getDomainFromUrl = function(url) {\n let domain;\n // Find & remove protocol (http, ftp, etc.) and get domain.\n if (url.indexOf(\"://\") > -1) {\n domain = url.split(\"/\")[2];\n } else {\n domain = url.split(\"/\")[0];\n }\n\n // find & remove port number\n domain = domain.split(\":\")[0];\n\n return domain;\n};\n\nexport default Util;\n","/* eslint-disable */\n\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * Given an orientation and the gyroscope data, predicts the future orientation\n * of the head. This makes rendering appear faster.\n *\n * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf\n * @param {Number} predictionTimeS time from head movement to the appearance of\n * the corresponding image.\n */\nclass PosePredictor {\n public predictionTimeS;\n public previousQ;\n public previousTimestampS;\n public deltaQ;\n public outQ;\n\n public constructor(predictionTimeS) {\n this.predictionTimeS = predictionTimeS;\n\n // The quaternion corresponding to the previous state.\n this.previousQ = new MathUtil.Quaternion();\n // Previous time a prediction occurred.\n this.previousTimestampS = null;\n\n // The delta quaternion that adjusts the current pose.\n this.deltaQ = new MathUtil.Quaternion();\n // The output quaternion.\n this.outQ = new MathUtil.Quaternion();\n }\n\n public getPrediction(currentQ, gyro, timestampS) {\n if (!this.previousTimestampS) {\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n return currentQ;\n }\n\n // Calculate axis and angle based on gyroscope rotation rate data.\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n\n const angularSpeed = gyro.length();\n\n // If we're rotating slowly, don't do prediction.\n if (angularSpeed < MathUtil.degToRad * 20) {\n if (Util.isDebug()) {\n console.log(\"Moving slowly, at %s deg/s: no prediction\",\n (MathUtil.radToDeg * angularSpeed).toFixed(1));\n }\n this.outQ.copy(currentQ);\n this.previousQ.copy(currentQ);\n return this.outQ;\n }\n\n // Get the predicted angle based on the time delta and latency.\n const deltaT = timestampS - this.previousTimestampS;\n const predictAngle = angularSpeed * this.predictionTimeS;\n\n this.deltaQ.setFromAxisAngle(axis, predictAngle);\n this.outQ.copy(this.previousQ);\n this.outQ.multiply(this.deltaQ);\n\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n\n return this.outQ;\n }\n}\n\nexport default PosePredictor;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3 } from \"gl-matrix\";\n\nimport { Mutable } from \"../../types/internal\";\nimport { window } from \"../../utils/browser\";\nimport { IS_CHROME_WITHOUT_DEVICE_MOTION, IS_ANDROID } from \"../consts\";\n\nconst STILLNESS_THRESHOLD = 200; // millisecond\n\nexport default class DeviceMotion extends Component<{\n devicemotion: {\n inputEvent: DeviceMotionEvent | {\n deviceorientation: {\n alpha: number;\n beta: number;\n gamma: number;\n };\n };\n };\n}> {\n public readonly isWithoutDeviceMotion: boolean;\n public readonly isAndroid: boolean;\n\n public stillGyroVec: vec3;\n public rawGyroVec: vec3;\n public adjustedGyroVec: vec3;\n public lastDevicemotionTimestamp: number;\n\n private _timer: number;\n private _isEnabled: boolean;\n\n public constructor() {\n super();\n this._onDeviceMotion = this._onDeviceMotion.bind(this);\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onChromeWithoutDeviceMotion = this._onChromeWithoutDeviceMotion.bind(this);\n\n this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION;\n this.isAndroid = IS_ANDROID;\n\n this.stillGyroVec = vec3.create();\n this.rawGyroVec = vec3.create();\n this.adjustedGyroVec = vec3.create();\n\n this._timer = -1;\n\n this.lastDevicemotionTimestamp = 0;\n this._isEnabled = false;\n this.enable();\n }\n\n public enable() {\n if (this.isAndroid) {\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n }\n if (this.isWithoutDeviceMotion) {\n window.addEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n } else {\n window.addEventListener(\"devicemotion\", this._onDeviceMotion);\n }\n this._isEnabled = true;\n }\n\n public disable() {\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n window.removeEventListener(\"devicemotion\", this._onDeviceMotion);\n this._isEnabled = false;\n }\n\n private _onChromeWithoutDeviceMotion(e: DeviceOrientationEvent) {\n let {alpha, beta, gamma} = e;\n\n // There is deviceorientation event trigged with empty values\n // on Headless Chrome.\n if (alpha === null) {\n return;\n }\n\n // convert to radian\n alpha = (alpha || 0) * Math.PI / 180;\n beta = (beta || 0) * Math.PI / 180;\n gamma = (gamma || 0) * Math.PI / 180;\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: {\n deviceorientation: {\n alpha,\n beta,\n gamma: -gamma\n }\n }\n }));\n }\n\n private _onDeviceOrientation() {\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timer = window.setTimeout(() => {\n if ((new Date().getTime() - this.lastDevicemotionTimestamp) < STILLNESS_THRESHOLD) {\n vec3.copy(this.stillGyroVec, this.rawGyroVec);\n }\n }, STILLNESS_THRESHOLD);\n }\n\n private _onDeviceMotion(e: DeviceMotionEvent) {\n // desktop chrome triggers devicemotion event with empthy sensor values.\n // Those events should ignored.\n const isGyroSensorAvailable = !(e.rotationRate!.alpha == null);\n const isGravitySensorAvailable = !(e.accelerationIncludingGravity!.x == null);\n\n if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) {\n return;\n }\n\n const devicemotionEvent = {...e} as Mutable;\n\n devicemotionEvent.interval = e.interval;\n devicemotionEvent.timeStamp = e.timeStamp;\n devicemotionEvent.type = e.type;\n devicemotionEvent.rotationRate = {\n alpha: e.rotationRate!.alpha,\n beta: e.rotationRate!.beta,\n gamma: e.rotationRate!.gamma\n };\n devicemotionEvent.accelerationIncludingGravity = {\n x: e.accelerationIncludingGravity!.x,\n y: e.accelerationIncludingGravity!.y,\n z: e.accelerationIncludingGravity!.z\n };\n devicemotionEvent.acceleration = {\n x: e.acceleration!.x,\n y: e.acceleration!.y,\n z: e.acceleration!.z\n };\n\n if (this.isAndroid) {\n vec3.set(\n this.rawGyroVec,\n e.rotationRate!.alpha || 0,\n e.rotationRate!.beta || 0,\n e.rotationRate!.gamma || 0);\n vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec);\n this.lastDevicemotionTimestamp = new Date().getTime();\n\n (devicemotionEvent as any).adjustedRotationRate = {\n alpha: this.adjustedGyroVec[0],\n beta: this.adjustedGyroVec[1],\n gamma: this.adjustedGyroVec[2]};\n }\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: devicemotionEvent\n }));\n }\n}\n","class SensorSample {\n public sample;\n public timestampS;\n\n public constructor(sample?, timestampS?) {\n this.set(sample, timestampS);\n }\n\n public set(sample, timestampS) {\n this.sample = sample;\n this.timestampS = timestampS;\n }\n\n public copy(sensorSample) {\n this.set(sensorSample.sample, sensorSample.timestampS);\n }\n}\n\nexport default SensorSample;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SensorSample from \"./sensor-sample\";\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * An implementation of a simple complementary filter, which fuses gyroscope and\n * accelerometer data from the 'devicemotion' event.\n *\n * Accelerometer data is very noisy, but stable over the long term.\n * Gyroscope data is smooth, but tends to drift over the long term.\n *\n * This fusion is relatively simple:\n * 1. Get orientation estimates from accelerometer by applying a low-pass filter\n * on that data.\n * 2. Get orientation estimates from gyroscope by integrating over time.\n * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the\n * short term.\n */\nclass ComplementaryFilter {\n public kFilter;\n public currentAccelMeasurement;\n public currentGyroMeasurement;\n public previousGyroMeasurement;\n public filterQ;\n public previousFilterQ;\n public accelQ;\n public isOrientationInitialized;\n public estimatedGravity;\n public measuredGravity;\n public gyroIntegralQ;\n\n constructor(kFilter) {\n this.kFilter = kFilter;\n\n // Raw sensor measurements.\n this.currentAccelMeasurement = new SensorSample();\n this.currentGyroMeasurement = new SensorSample();\n this.previousGyroMeasurement = new SensorSample();\n\n // Set default look direction to be in the correct direction.\n if (Util.isIOS()) {\n this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);\n } else {\n this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);\n }\n this.previousFilterQ = new MathUtil.Quaternion();\n this.previousFilterQ.copy(this.filterQ);\n\n // Orientation based on the accelerometer.\n this.accelQ = new MathUtil.Quaternion();\n // Whether or not the orientation has been initialized.\n this.isOrientationInitialized = false;\n // Running estimate of gravity based on the current orientation.\n this.estimatedGravity = new MathUtil.Vector3();\n // Measured gravity based on accelerometer.\n this.measuredGravity = new MathUtil.Vector3();\n\n // Debug only quaternion of gyro-based orientation.\n this.gyroIntegralQ = new MathUtil.Quaternion();\n }\n\n public addAccelMeasurement(vector, timestampS) {\n this.currentAccelMeasurement.set(vector, timestampS);\n }\n\n public addGyroMeasurement = function(vector, timestampS) {\n this.currentGyroMeasurement.set(vector, timestampS);\n\n const deltaT = timestampS - this.previousGyroMeasurement.timestampS;\n if (Util.isTimestampDeltaValid(deltaT)) {\n this.run_();\n }\n\n this.previousGyroMeasurement.copy(this.currentGyroMeasurement);\n };\n\n public getOrientation() {\n return this.filterQ;\n }\n\n public run_() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n if (Util.isDebug()) {\n console.log(\"Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)\",\n MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),\n (this.estimatedGravity.x).toFixed(1),\n (this.estimatedGravity.y).toFixed(1),\n (this.estimatedGravity.z).toFixed(1),\n (this.measuredGravity.x).toFixed(1),\n (this.measuredGravity.y).toFixed(1),\n (this.measuredGravity.z).toFixed(1));\n }\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n }\n\n private accelToQuaternion_(accel) {\n const normAccel = new MathUtil.Vector3();\n normAccel.copy(accel);\n normAccel.normalize();\n const quat = new MathUtil.Quaternion();\n quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);\n quat.inverse();\n return quat;\n }\n\n private gyroToQuaternionDelta_(gyro, dt) {\n // Extract axis and angle from the gyroscope data.\n const quat = new MathUtil.Quaternion();\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n quat.setFromAxisAngle(axis, gyro.length() * dt);\n return quat;\n }\n}\n\nexport default ComplementaryFilter;\n","import MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport ComplementaryFilter from \"./lib/webvr-polyfill/complementary-filter\";\n\nComplementaryFilter.prototype.run_ = function() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n\n if (!this.isFilterQuaternionInitialized) {\n this.isFilterQuaternionInitialized = true;\n }\n};\n\nComplementaryFilter.prototype.getOrientation = function() {\n if (this.isFilterQuaternionInitialized) {\n return this.filterQ;\n } else {\n return null;\n }\n};\n\nexport default ComplementaryFilter;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\n\nimport { window, IS_IOS, IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { CHROME_VERSION } from \"../consts\";\n\nimport PosePredictor from \"./lib/webvr-polyfill/pose-predictor\";\nimport MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport Util from \"./lib/webvr-polyfill/util\";\nimport DeviceMotion from \"./DeviceMotion\";\nimport ComplementaryFilter from \"./ComplementaryFilter\";\n\n\nconst K_FILTER = 0.98;\nconst PREDICTION_TIME_S = 0.040;\n\nexport default class FusionPoseSensor extends Component<{\n change: {\n quaternion: quat;\n };\n}> {\n public deviceMotion: DeviceMotion | null;\n public accelerometer: any;\n public gyroscope: any;\n public filter: ComplementaryFilter;\n public posePredictor: PosePredictor;\n public filterToWorldQ: any;\n public isFirefoxAndroid: boolean;\n public isIOS: boolean;\n public isChromeUsingDegrees: boolean;\n public inverseWorldToScreenQ: any;\n public worldToScreenQ: any;\n public originalPoseAdjustQ: any;\n public resetQ: any;\n public deviceOrientationFixQ: any;\n public predictedQ: any;\n public previousTimestampS: number;\n\n private _isEnabled: boolean;\n private _deviceOrientationQ: any;\n private _prevOrientation: quat;\n private _alpha: number;\n\n public constructor() {\n super();\n\n this.deviceMotion = new DeviceMotion();\n\n this.accelerometer = new MathUtil.Vector3();\n this.gyroscope = new MathUtil.Vector3();\n\n this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);\n this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);\n\n this.filter = new ComplementaryFilter(K_FILTER);\n this.posePredictor = new PosePredictor(PREDICTION_TIME_S);\n\n this.filterToWorldQ = new MathUtil.Quaternion();\n\n this.isFirefoxAndroid = Util.isFirefoxAndroid();\n // This includes iPhone & iPad(both desktop and mobile mode) ref #326\n this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP;\n\n // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18\n this.isChromeUsingDegrees = CHROME_VERSION >= 66;\n\n this._isEnabled = false;\n\n // Set the filter to world transform, depending on OS.\n if (this.isIOS) {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);\n } else {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n this.inverseWorldToScreenQ = new MathUtil.Quaternion();\n this.worldToScreenQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),\n -window.orientation * Math.PI / 180);\n\n this._setScreenTransform();\n // Adjust this filter for being in landscape mode.\n if (Util.isLandscapeMode()) {\n this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);\n }\n\n // Keep track of a reset transform for resetSensor.\n this.resetQ = new MathUtil.Quaternion();\n\n this.deviceMotion.on(\"devicemotion\", this._onDeviceMotionChange);\n this.enable();\n }\n\n public enable() {\n if (this.isEnabled()) {\n return;\n }\n this.deviceMotion!.enable();\n this._isEnabled = true;\n window.addEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public disable() {\n if (!this.isEnabled()) {\n return;\n }\n this.deviceMotion!.disable();\n this._isEnabled = false;\n window.removeEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public isEnabled() {\n return this._isEnabled;\n }\n\n public destroy() {\n this.disable();\n this.deviceMotion = null;\n }\n\n public getOrientation() {\n let orientation;\n\n // Hack around using deviceorientation instead of devicemotion\n if (this.deviceMotion!.isWithoutDeviceMotion && this._deviceOrientationQ) {\n this.deviceOrientationFixQ = this.deviceOrientationFixQ || (() => {\n const y = new MathUtil.Quaternion()\n .setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -this._alpha);\n\n return y;\n })();\n\n orientation = this._deviceOrientationQ;\n const out = new MathUtil.Quaternion();\n\n out.copy(orientation);\n out.multiply(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.worldToScreenQ);\n out.multiplyQuaternions(this.deviceOrientationFixQ, out);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n } else {\n // Convert from filter space to the the same system used by the\n // deviceorientation event.\n orientation = this.filter.getOrientation();\n\n if (!orientation) {\n return null;\n }\n\n const out = this._convertFusionToPredicted(orientation);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n }\n }\n\n private _triggerChange() {\n const orientation = this.getOrientation();\n\n // if orientation is not prepared. don't trigger change event\n if (!orientation) {\n return;\n }\n\n if (!this._prevOrientation) {\n this._prevOrientation = orientation;\n return;\n }\n\n if (quat.equals(this._prevOrientation, orientation)) {\n return;\n }\n\n this.trigger(new ComponentEvent(\"change\", { quaternion: orientation }));\n }\n\n private _convertFusionToPredicted(orientation: quat) {\n // Predict orientation.\n this.predictedQ =\n this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);\n\n // Convert to THREE coordinate system: -Z forward, Y up, X right.\n const out = new MathUtil.Quaternion();\n\n out.copy(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.predictedQ);\n out.multiply(this.worldToScreenQ);\n\n return out;\n }\n\n private _onDeviceMotionChange({ inputEvent }) {\n const deviceorientation = inputEvent.deviceorientation;\n const deviceMotion = inputEvent;\n const accGravity = deviceMotion.accelerationIncludingGravity;\n const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;\n let timestampS = deviceMotion.timeStamp / 1000;\n\n if (deviceorientation) {\n if (!this._alpha) {\n this._alpha = deviceorientation.alpha;\n }\n this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();\n this._deviceOrientationQ.setFromEulerYXZ(\n deviceorientation.beta,\n deviceorientation.alpha,\n deviceorientation.gamma\n );\n\n this._triggerChange();\n } else {\n // Firefox Android timeStamp returns one thousandth of a millisecond.\n if (this.isFirefoxAndroid) {\n timestampS /= 1000;\n }\n\n this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);\n this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);\n\n // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate`\n // is reported in degrees, so we first convert to radians.\n if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) {\n this.gyroscope.multiplyScalar(Math.PI / 180);\n }\n\n this.filter.addAccelMeasurement(this.accelerometer, timestampS);\n this.filter.addGyroMeasurement(this.gyroscope, timestampS);\n\n this._triggerChange();\n\n this.previousTimestampS = timestampS;\n }\n }\n\n private _onScreenOrientationChange() {\n this._setScreenTransform();\n }\n\n private _setScreenTransform() {\n this.worldToScreenQ.set(0, 0, 0, 1);\n\n const orientation = window.orientation;\n\n switch (orientation) {\n case 0:\n break;\n case 90:\n case -90:\n case 180:\n this.worldToScreenQ\n .setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI);\n break;\n default:\n break;\n }\n this.inverseWorldToScreenQ.copy(this.worldToScreenQ);\n this.inverseWorldToScreenQ.inverse();\n }\n}\n","import Component from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\n\nimport { toAxis } from \"../utils\";\nimport { util, ROTATE_CONSTANT } from \"../../utils/math-util\";\n\nimport FusionPoseSensor from \"./FusionPoseSensor\";\n\nconst getDeltaYaw = (prvQ: quat, curQ: quat): number => {\n const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(util.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nconst getDeltaPitch = (prvQ: quat, curQ: quat): number => {\n const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport default class TiltMotionInput extends Component<{}> {\n public element: HTMLElement;\n public options: { scale: number; threshold: number };\n public fusionPoseSensor: FusionPoseSensor | null;\n public axes: string[];\n public observer: InputTypeObserver | null;\n\n private _prevQuaternion: quat | null;\n private _quaternion: quat | null;\n\n public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {\n super();\n this.element = el;\n\n this._prevQuaternion = null;\n this._quaternion = null;\n\n this.fusionPoseSensor = null;\n\n this.options = {\n ...{\n scale: 1,\n threshold: 0\n }, ...options\n };\n\n this._onPoseChange = this._onPoseChange.bind(this);\n }\n\n public mapAxes(axes: string[]) {\n this.axes = axes;\n }\n\n public connect(observer: InputTypeObserver) {\n if (this.observer) {\n return this;\n }\n this.observer = observer;\n this.fusionPoseSensor = new FusionPoseSensor();\n this.fusionPoseSensor.enable();\n this._attachEvent();\n return this;\n }\n\n public disconnect() {\n if (!this.observer) {\n return this;\n }\n\n this._dettachEvent();\n this.fusionPoseSensor!.disable();\n this.fusionPoseSensor!.destroy();\n this.fusionPoseSensor = null;\n this.observer = null;\n return this;\n }\n\n public destroy() {\n this.disconnect();\n (this.element as any) = null;\n (this.options as any) = null;\n (this.axes as any) = null;\n this._prevQuaternion = null;\n this._quaternion = null;\n }\n\n private _onPoseChange(event) {\n if (!this._prevQuaternion) {\n this._prevQuaternion = quat.clone(event.quaternion);\n this._quaternion = quat.clone(event.quaternion);\n return;\n }\n\n quat.copy(this._prevQuaternion, this._quaternion!);\n quat.copy(this._quaternion!, event.quaternion);\n\n this.observer!.change(this, event, toAxis(this.axes, [\n getDeltaYaw(this._prevQuaternion, this._quaternion as quat),\n getDeltaPitch(this._prevQuaternion, this._quaternion as quat)\n ]));\n }\n\n private _attachEvent() {\n this.fusionPoseSensor!.on(\"change\", this._onPoseChange);\n }\n\n private _dettachEvent() {\n this.fusionPoseSensor!.off(\"change\", this._onPoseChange);\n }\n}\n","import { quat } from \"gl-matrix\";\n\nimport {\n util as mathUtil,\n ROTATE_CONSTANT\n} from \"../utils/math-util\";\n\nexport const toAxis = (source, offset) => offset.reduce((acc, v, i) => {\n if (source[i]) {\n acc[source[i]] = v;\n }\n return acc;\n}, {});\n\nexport const getDeltaYaw = (prvQ: quat, curQ: quat) => {\n const yawDeltaByYaw = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(mathUtil.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nexport const getDeltaPitch = (prvQ: quat, curQ: quat) => {\n const pitchDelta = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n","import { glMatrix } from \"gl-matrix\";\n\nimport { window } from \"../utils/browser\";\n\n// Singleton\nlet screenRotationAngleInst: ScreenRotationAngle | null = null;\nlet refCount = 0;\n\nexport default class ScreenRotationAngle {\n private _spinR: number;\n private _screenOrientationAngle: number;\n\n public constructor() {\n refCount++;\n\n if (screenRotationAngleInst) {\n return screenRotationAngleInst;\n }\n /* eslint-disable */\n screenRotationAngleInst = this;\n /* eslint-enable */\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n\n this._spinR = 0;\n\n this._screenOrientationAngle = 0;\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.addEventListener(\"orientationchange\", this._onOrientationChange);\n }\n\n public getRadian() {\n // Join with screen orientation\n // this._testVal = this._spinR + \", \" + this._screenOrientationAngle + \", \" + window.orientation;\n return this._spinR + glMatrix.toRadian(this._screenOrientationAngle);\n }\n\n public unref() {\n if (--refCount > 0) {\n return;\n }\n\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"orientationchange\", this._onOrientationChange);\n\n this._spinR = 0;\n this._screenOrientationAngle = 0;\n /* eslint-disable */\n screenRotationAngleInst = null;\n /* eslint-enable */\n refCount = 0;\n }\n\n private _onDeviceOrientation(e: DeviceOrientationEvent) {\n if (e.beta === null || e.gamma === null) {\n // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it.\n return;\n }\n\n // Radian\n const betaR = glMatrix.toRadian(e.beta);\n const gammaR = glMatrix.toRadian(e.gamma);\n\n /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */\n this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR));\n }\n\n private _onOrientationChange() {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientationAngle = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n /* iOS */\n this._screenOrientationAngle = window.orientation >= 0 ?\n window.orientation : 360 + (window.orientation as number);\n }\n }\n}\n","import Axes, { PanInput } from \"@egjs/axes\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\nimport { PanInputOption } from \"@egjs/axes/declaration/inputType/PanInput\";\n\nimport ScreenRotationAngle from \"../ScreenRotationAngle\";\n\n/**\n * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle.\n *\n * The reason for using this function is that in VR mode,\n * the roll angle is adjusted in the direction opposite to the screen rotation angle.\n *\n * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move.\n * @extends PanInput\n */\nexport default class RotationPanInput extends PanInput {\n private _useRotation: boolean;\n private _screenRotationAngle: ScreenRotationAngle | null;\n private _userDirection: number;\n\n /**\n * Constructor\n * @private\n * @param {HTMLElement} el target element\n * @param {Object} [options] The option object\n * @param {Boolean} [options.useRotation] Whether to use rotation(or VR)\n */\n public constructor(el: HTMLElement, options: Partial<{ useRotation: boolean } & PanInputOption> = {}) {\n super(el, options);\n\n this._useRotation = false;\n this._screenRotationAngle = null;\n\n this.setUseRotation(!!(options && options.useRotation));\n\n this._userDirection = Axes.DIRECTION_ALL;\n }\n\n public setUseRotation(useRotation: boolean) {\n this._useRotation = useRotation;\n\n if (this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n this._screenRotationAngle = null;\n }\n\n if (this._useRotation) {\n this._screenRotationAngle = new ScreenRotationAngle();\n }\n }\n\n public connect(observer: InputTypeObserver) {\n // User intetened direction\n this._userDirection = this._direction;\n\n // In VR Mode, Use ALL direction if direction is not none\n // Because horizontal and vertical is changed dynamically by screen rotation.\n // this._direction is used to initialize hammerjs\n if (this._useRotation && (this._direction & Axes.DIRECTION_ALL)) {\n this._direction = Axes.DIRECTION_HORIZONTAL;\n }\n\n return super.connect(observer);\n }\n\n public destroy() {\n if (this._useRotation && this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n }\n\n super.destroy();\n }\n\n protected _getOffset(properties: number[], useDirection: boolean[]) {\n if (this._useRotation === false) {\n return super._getOffset(properties, useDirection);\n }\n\n const offset = super._getOffset(properties, [true, true]);\n const newOffset = [0, 0];\n\n const theta = this._screenRotationAngle!.getRadian();\n\n const cosTheta = Math.cos(theta);\n const sinTheta = Math.sin(theta);\n\n // RotateZ\n newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta;\n newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta;\n\n // Use only user allowed direction.\n if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) {\n newOffset[0] = 0;\n } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) {\n newOffset[1] = 0;\n }\n\n return newOffset;\n }\n}\n\n/**\n * Override getDirectionByAngle to return DIRECTION_ALL\n * Ref: https://github.com/naver/egjs-axes/issues/99\n *\n * But we obey axes's rule. If axes's rule is problem, let's apply following code.\n */\n// PanInput.getDirectionByAngle = function (angle, thresholdAngle) {\n// \treturn DIRECTION_ALL;\n// };\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3, glMatrix, quat } from \"gl-matrix\";\n\nimport FusionPoseSensor from \"./input/FusionPoseSensor\";\n\nconst Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0);\n\nexport default class DeviceQuaternion extends Component<{\n change: {\n isTrusted: boolean;\n };\n}> {\n private _fusionPoseSensor: FusionPoseSensor | null;\n private _quaternion: quat;\n\n public constructor() {\n super();\n\n this._fusionPoseSensor = new FusionPoseSensor();\n this._quaternion = quat.create();\n\n this._fusionPoseSensor.enable();\n this._fusionPoseSensor.on(\"change\", e => {\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(\"change\", { isTrusted: true }));\n });\n }\n\n public getCombinedQuaternion(yaw: number) {\n const yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw));\n const conj = quat.conjugate(quat.create(), this._quaternion);\n // Multiply pitch quaternion -> device quaternion -> yaw quaternion\n const outQ = quat.multiply(quat.create(), conj, yawQ);\n\n return outQ;\n }\n\n public destroy() {\n // detach all event handler\n this.off();\n\n if (this._fusionPoseSensor) {\n this._fusionPoseSensor.off();\n this._fusionPoseSensor.destroy();\n this._fusionPoseSensor = null;\n }\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PinchInput, MoveKeyInput, WheelInput } from \"@egjs/axes\";\nimport { vec2, quat, glMatrix } from \"gl-matrix\";\n\nimport { SUPPORT_TOUCH, SUPPORT_DEVICEMOTION } from \"../utils/browserFeature\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { ValueOf } from \"../types/internal\";\n\nimport TiltMotionInput from \"./input/TiltMotionInput\";\nimport RotationPanInput from \"./input/RotationPanInput\";\nimport DeviceQuaternion from \"./DeviceQuaternion\";\nimport {\n GYRO_MODE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n TOUCH_DIRECTION_NONE\n} from \"./consts\";\n\n\nconst DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF];\nconst DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF];\nconst CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF];\n\nexport interface YawPitchControlOptions {\n element: HTMLElement | null;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n touchDirection: number;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n aspectRatio: number;\n}\ninterface YawPitchControlEvents {\n change: ComponentEvent<{\n yaw: number;\n pitch: number;\n fov: number;\n quaternion: quat | null;\n targetElement: HTMLElement;\n isTrusted: boolean;\n }>;\n hold: ComponentEvent<{\n isTrusted: boolean;\n }>;\n animationEnd: ComponentEvent<{\n isTrusted: boolean;\n }>;\n}\n\n/**\n * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates.\n * @alias eg.YawPitchControl\n * @extends eg.Component\n *\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass YawPitchControl extends Component {\n public static VERSION = VERSION;\n // Expose DeviceOrientationControls sub module for test purpose\n public static CONTROL_MODE_VR = CONTROL_MODE_VR;\n public static CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH;\n public static TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL;\n public static TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW;\n public static TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH;\n public static TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE;\n\n public options: YawPitchControlOptions;\n\n private _element: HTMLElement | null;\n private _initialFov: number;\n private _enabled: boolean;\n private _isAnimating: boolean;\n private _deviceQuaternion: DeviceQuaternion | null;\n\n private _axes: Axes;\n private _axesPanInput: RotationPanInput;\n private _axesWheelInput: WheelInput;\n private _axesTiltMotionInput: TiltMotionInput | null;\n private _axesPinchInput: PinchInput | null;\n private _axesMoveKeyInput: MoveKeyInput;\n\n /**\n * @param {object} options The option object of the eg.YawPitch module\n * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module\n * @param {number} [options.yaw=0] initial yaw (degree)\n * @param {number} [options.pitch=0] initial pitch (degree)\n * @param {number} [options.fov=65] initial field of view (degree)\n * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown\n * @param {boolean} [options.useZoom=true] Indicates whether zoom is available\n * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled\n * @param {string} [config.gyroMode=yawPitch] Enables control through device motion.\n * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move)\n * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw\n * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch\n * @param {number[]} [options.fovRange=[30, 110] Range of FOV\n * @param {number} [options.aspectRatio=1] Aspect Ratio\n */\n public constructor(options: Partial) {\n super();\n this.options = {} as any;\n\n const opt = {\n ...{\n element: null,\n yaw: 0,\n pitch: 0,\n fov: 65,\n showPolePoint: false,\n useZoom: true,\n useKeyboard: true,\n gyroMode: GYRO_MODE.YAWPITCH,\n touchDirection: TOUCH_DIRECTION_ALL,\n yawRange: DEFAULT_YAW_RANGE,\n pitchRange: DEFAULT_PITCH_RANGE,\n fovRange: [30, 110],\n aspectRatio: 1 /* TODO: Need Mandatory? */\n }, ...options\n };\n\n this._element = opt.element;\n this._initialFov = opt.fov;\n this._enabled = false;\n this._isAnimating = false;\n this._deviceQuaternion = null;\n\n this._initAxes(opt);\n this.option(opt);\n }\n\n /**\n * Update Pan Scale\n *\n * Scale(Sensitivity) values of panning is related with fov and height.\n * If at least one of them is changed, this function need to be called.\n * @param {*} param\n */\n public updatePanScale(param: Partial<{\n height: number;\n }> = {}) {\n const fov = this._axes.get().fov;\n const areaHeight = param.height || parseInt(window.getComputedStyle(this._element!).height, 10);\n const scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight;\n\n this._axesPanInput.options.scale = [scale, scale];\n this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW;\n\n return this;\n }\n\n public option(): YawPitchControlOptions;\n public option(key: K): YawPitchControlOptions[K];\n public option(key: K, newValue: YawPitchControlOptions[K]): YawPitchControl;\n public option(newOptions: Partial): YawPitchControl;\n /*\n * Override component's option method\n * to call method for updating values which is affected by option change.\n *\n * @param {*} args\n */\n public option(key?: K | Partial, newValue?: YawPitchControlOptions[K]) {\n // Getter\n if (!key) {\n return this._getOptions();\n } else if (key && typeof key === \"string\" && typeof newValue === \"undefined\") {\n return this._getOptions(key);\n }\n\n // Setter\n let newOptions: Partial = {};\n let changedKeyList: string[] = []; // TODO: if value is not changed, then do not push on changedKeyList.\n\n if (typeof key === \"string\") {\n changedKeyList.push(key);\n newOptions[key] = newValue;\n } else {\n const options = key; // Retrieving object here\n changedKeyList = Object.keys(options);\n newOptions = {...options};\n }\n\n this._setOptions(this._getValidatedOptions(newOptions));\n this._applyOptions(changedKeyList);\n return this;\n }\n\n /**\n * Enable YawPitch functionality\n * @method eg.YawPitch#enable\n */\n public enable() {\n if (this._enabled) {\n return this;\n }\n\n this._enabled = true;\n\n // touchDirection is decided by parameter is valid string (Ref. Axes.connect)\n this._applyOptions(Object.keys(this.options));\n\n // TODO: Is this code is needed? Check later.\n this.updatePanScale();\n\n return this;\n }\n\n /**\n * Disable YawPitch functionality\n * @method eg.YawPitch#disable\n */\n public disable(persistOrientation: boolean = false) {\n if (!this._enabled) {\n return this;\n }\n\n // TODO: Check peristOrientation is needed!\n if (!persistOrientation) {\n this._resetOrientation();\n }\n this._axes.disconnect();\n this._enabled = false;\n return this;\n }\n\n /**\n * Set one or more of yaw, pitch, fov\n * @param {Object} coordinate yaw, pitch, fov\n * @param {Number} duration Animation duration. if it is above 0 then it's animated.\n */\n public lookAt({yaw, pitch, fov}, duration) {\n const pos = this._axes.get();\n\n const y = yaw === undefined ? 0 : yaw - pos.yaw;\n const p = pitch === undefined ? 0 : pitch - pos.pitch;\n const f = fov === undefined ? 0 : fov - pos.fov;\n\n // Allow duration of animation to have more than MC_MAXIMUM_DURATION.\n this._axes.options.maximumDuration = Infinity;\n\n this._axes.setBy({\n yaw: y,\n pitch: p,\n fov: f\n }, duration);\n }\n\n public getYawPitch() {\n const yawPitch = this._axes.get();\n\n return {\n yaw: yawPitch.yaw,\n pitch: yawPitch.pitch\n };\n }\n\n public getFov() {\n return this._axes.get().fov;\n }\n\n public getQuaternion() {\n const pos = this._axes.get();\n\n return this._deviceQuaternion!.getCombinedQuaternion(pos.yaw);\n }\n\n public shouldRenderWithQuaternion() {\n return this.options.gyroMode === GYRO_MODE.VR;\n }\n\n /**\n * Destroys objects\n */\n public destroy() {\n /* eslint-disable @typescript-eslint/no-unused-expressions */\n this._axes && this._axes.destroy();\n this._axesPanInput && this._axesPanInput.destroy();\n this._axesWheelInput && this._axesWheelInput.destroy();\n this._axesTiltMotionInput && this._axesTiltMotionInput.destroy();\n this._axesPinchInput && this._axesPinchInput.destroy();\n this._axesMoveKeyInput && this._axesMoveKeyInput.destroy();\n this._deviceQuaternion && this._deviceQuaternion.destroy();\n /* eslint-enable @typescript-eslint/no-unused-expressions */\n }\n\n private _initAxes(opt: YawPitchControlOptions) {\n const yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio);\n const pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint);\n const useRotation = opt.gyroMode === GYRO_MODE.VR;\n\n this._axesPanInput = new RotationPanInput(this._element!, {useRotation});\n this._axesWheelInput = new WheelInput(this._element, {scale: -4});\n this._axesTiltMotionInput = null;\n this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, {scale: -1}) : null;\n this._axesMoveKeyInput = new MoveKeyInput(this._element, {scale: [-6, 6]});\n\n this._axes = new Axes({\n yaw: {\n range: yRange,\n circular: this._isCircular(yRange),\n bounce: [0, 0]\n },\n pitch: {\n range: pRange,\n circular: this._isCircular(pRange),\n bounce: [0, 0]\n },\n fov: {\n range: opt.fovRange,\n circular: [false, false],\n bounce: [0, 0]\n }\n }, {\n deceleration: MC_DECELERATION,\n maximumDuration: MC_MAXIMUM_DURATION\n }, {\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }).on({\n // TODO: change event type after Axes event type inference update\n hold: (evt: any) => {\n // Restore maximumDuration not to be spin too mush.\n this._axes.options.maximumDuration = MC_MAXIMUM_DURATION;\n\n this.trigger(new ComponentEvent(\"hold\", { isTrusted: evt.isTrusted }));\n },\n change: (evt: any) => {\n if (evt.delta.fov !== 0) {\n this._updateControlScale(evt);\n this.updatePanScale();\n }\n this._triggerChange(evt);\n },\n release: evt => {\n this._triggerChange(evt);\n },\n animationEnd: (evt: any) => {\n this.trigger(new ComponentEvent(\"animationEnd\", { isTrusted: evt.isTrusted }));\n }\n });\n }\n\n private _getValidatedOptions(newOptions: Partial) {\n if (newOptions.yawRange) {\n newOptions.yawRange =\n this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio);\n }\n if (newOptions.pitchRange) {\n newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov);\n }\n return newOptions;\n }\n\n private _getOptions(): YawPitchControlOptions;\n private _getOptions(key: K): YawPitchControlOptions[K];\n private _getOptions(key?: K) {\n let value;\n\n if (typeof key === \"string\") {\n value = this.options[key];\n } else if (arguments.length === 0) {\n value = this.options;\n }\n return value;\n }\n\n private _setOptions(options: Partial): void {\n for (const key in options) {\n this.options[key] = options[key];\n }\n }\n\n private _applyOptions(keys: string[]) {\n const options = this.options;\n const axes = this._axes;\n const isVR = options.gyroMode === GYRO_MODE.VR;\n const isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH;\n // If it's VR mode, restrict user interaction to yaw direction only\n const touchDirection = isVR ?\n (TOUCH_DIRECTION_YAW & options.touchDirection) :\n options.touchDirection;\n\n // If one of below is changed, call updateControlScale()\n if (keys.some(key =>\n key === \"showPolePoint\" || key === \"fov\" || key === \"aspectRatio\" ||\n key === \"yawRange\" || key === \"pitchRange\"\n )) {\n // If fov is changed, update pan scale\n if (keys.indexOf(\"fov\") >= 0) {\n axes.setTo({\"fov\": options.fov});\n this.updatePanScale();\n }\n\n this._updateControlScale();\n }\n\n if (keys.some(key => key === \"fovRange\")) {\n const fovRange = options.fovRange;\n const prevFov = axes.get().fov;\n let nextFov = axes.get().fov;\n\n vec2.copy(axes.axis.fov.range as vec2, fovRange as vec2);\n\n if (nextFov < fovRange[0]) {\n nextFov = fovRange[0];\n } else if (prevFov > fovRange[1]) {\n nextFov = fovRange[1];\n }\n\n if (prevFov !== nextFov) {\n axes.setTo({\n fov: nextFov\n }, 0);\n this._updateControlScale();\n this.updatePanScale();\n }\n }\n\n if (keys.some(key => key === \"gyroMode\") && SUPPORT_DEVICEMOTION) {\n // Disconnect first\n if (this._axesTiltMotionInput) {\n this._axes.disconnect(this._axesTiltMotionInput);\n this._axesTiltMotionInput.destroy();\n this._axesTiltMotionInput = null;\n }\n\n if (this._deviceQuaternion) {\n this._deviceQuaternion.destroy();\n this._deviceQuaternion = null;\n }\n\n if (isVR) {\n this._initDeviceQuaternion();\n } else if (isYawPitch) {\n this._axesTiltMotionInput = new TiltMotionInput(this._element!);\n this._axes.connect([\"yaw\", \"pitch\"], this._axesTiltMotionInput);\n }\n\n this._axesPanInput.setUseRotation(isVR);\n }\n\n if (keys.some(key => key === \"useKeyboard\")) {\n const useKeyboard = options.useKeyboard;\n\n if (useKeyboard) {\n axes.connect([\"yaw\", \"pitch\"], this._axesMoveKeyInput);\n } else {\n axes.disconnect(this._axesMoveKeyInput);\n }\n }\n\n if (keys.some(key => key === \"useZoom\")) {\n const useZoom = options.useZoom;\n\n // Disconnect first\n axes.disconnect(this._axesWheelInput);\n if (useZoom) {\n axes.connect([\"fov\"], this._axesWheelInput);\n }\n }\n\n this._togglePinchInputByOption(options.touchDirection, options.useZoom);\n\n if (keys.some(key => key === \"touchDirection\") && this._enabled) {\n this._enableTouch(touchDirection);\n }\n }\n\n private _togglePinchInputByOption(touchDirection: YawPitchControlOptions[\"touchDirection\"], useZoom: boolean) {\n if (this._axesPinchInput) {\n // disconnect first\n this._axes.disconnect(this._axesPinchInput);\n\n // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll.\n if (\n useZoom &&\n touchDirection === TOUCH_DIRECTION_ALL &&\n // TODO: Get rid of using private property of axes instance.\n (this._axes as any)._inputs.indexOf(this._axesPinchInput) === -1\n ) {\n this._axes.connect([\"fov\"], this._axesPinchInput);\n }\n }\n }\n\n private _enableTouch(direction: YawPitchControlOptions[\"touchDirection\"]) {\n // Disconnect first\n if (this._axesPanInput) {\n this._axes.disconnect(this._axesPanInput);\n }\n\n const yawEnabled = direction & TOUCH_DIRECTION_YAW ? \"yaw\" : null;\n const pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? \"pitch\" : null;\n\n this._axes.connect([yawEnabled, pitchEnabled] as string[], this._axesPanInput);\n }\n\n private _initDeviceQuaternion() {\n this._deviceQuaternion = new DeviceQuaternion();\n this._deviceQuaternion.on(\"change\", e => {\n this._triggerChange(e);\n });\n }\n\n private _getValidYawRange(newYawRange: number[], newFov?: number, newAspectRatio?: number) {\n const ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1);\n const fov = newFov || this._axes.get().fov;\n const horizontalFov = fov * ratio;\n const isValid = newYawRange[1] - newYawRange[0] >= horizontalFov;\n\n if (isValid) {\n return newYawRange;\n } else {\n return this.options.yawRange || DEFAULT_YAW_RANGE;\n }\n }\n\n private _getValidPitchRange(newPitchRange: number[], newFov?: number) {\n const fov = newFov || this._axes.get().fov;\n const isValid = newPitchRange[1] - newPitchRange[0] >= fov;\n\n if (isValid) {\n return newPitchRange;\n } else {\n return this.options.pitchRange || DEFAULT_PITCH_RANGE;\n }\n }\n\n private _isCircular(range: number[]) {\n return range[1] - range[0] < 360 ? [false, false] : [true, true];\n }\n\n /**\n * Update yaw/pitch min/max by 5 factor\n *\n * 1. showPolePoint\n * 2. fov\n * 3. yawRange\n * 4. pitchRange\n * 5. aspectRatio\n *\n * If one of above is changed, call this function\n */\n private _updateControlScale(changeEvt?: any) { // TODO: Change type after Axes type inference update\n const opt = this.options;\n const fov = this._axes.get().fov;\n\n const pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint);\n const yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio);\n\n // TODO: If not changed!?\n const pos = this._axes.get();\n let y = pos.yaw;\n let p = pos.pitch;\n\n vec2.copy(this._axes.axis.yaw.range as any, yRange as any);\n vec2.copy(this._axes.axis.pitch.range as any, pRange as any);\n this._axes.axis.yaw.circular = this._isCircular(yRange);\n this._axes.axis.pitch.circular = this._isCircular(pRange);\n\n /**\n * update yaw/pitch by it's range.\n */\n if (y < yRange[0]) {\n y = yRange[0];\n } else if (y > yRange[1]) {\n y = yRange[1];\n }\n\n if (p < pRange[0]) {\n p = pRange[0];\n } else if (p > pRange[1]) {\n p = pRange[1];\n }\n\n if (changeEvt) {\n changeEvt.set({\n yaw: y,\n pitch: p\n });\n }\n\n this._axes.setTo({\n yaw: y,\n pitch: p\n }, 0);\n\n return this;\n }\n\n private _updatePitchRange(pitchRange: number[], fov: number, showPolePoint: boolean) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n // Circular pitch on VR\n return CIRCULAR_PITCH_RANGE;\n }\n\n const verticalAngle = pitchRange[1] - pitchRange[0];\n const halfFov = fov / 2;\n const isPanorama = verticalAngle < 180;\n\n if (showPolePoint && !isPanorama) {\n // Use full pinch range\n return pitchRange.concat();\n }\n\n // Round value as movableCood do.\n return [pitchRange[0] + halfFov, pitchRange[1] - halfFov];\n }\n\n private _updateYawRange(yawRange: number[], fov: number, aspectRatio: number) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n return DEFAULT_YAW_RANGE;\n }\n\n const horizontalAngle = yawRange[1] - yawRange[0];\n\n /**\n * Full 360 Mode\n */\n if (horizontalAngle >= 360) {\n // Don't limit yaw range on Full 360 mode.\n return yawRange.concat();\n }\n\n /**\n * Panorama mode\n */\n // Ref : https://github.com/naver/egjs-view360/issues/290\n const halfHorizontalFov =\n mathUtil.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))) as number;\n\n // Round value as movableCood do.\n return [\n yawRange[0] + halfHorizontalFov,\n yawRange[1] - halfHorizontalFov\n ];\n }\n\n // TODO: update param type after Axes event type inference update\n private _triggerChange(evt: any) {\n const pos = this._axes.get();\n const opt = this.options;\n const event: YawPitchControlEvents[\"change\"] extends ComponentEvent ? T : never = {\n targetElement: opt.element as HTMLElement,\n isTrusted: evt.isTrusted,\n yaw: pos.yaw,\n pitch: pos.pitch,\n fov: pos.fov,\n quaternion: null\n };\n\n if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) {\n event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw);\n }\n\n this.trigger(new ComponentEvent(\"change\", event));\n }\n\n // TODO: makes constant to be logic\n private _adjustAspectRatio(input: number) {\n const inputRange = [\n 0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670,\n 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19,\n 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26,\n 2.30, 2.60, 3.00, 5.00, 6.00\n ];\n const outputRange = [\n 0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710,\n 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15,\n 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72,\n 1.82, 1.92, 2.00, 2.24, 2.30\n ];\n\n let rangeIdx = -1;\n\n for (let i = 0; i < inputRange.length - 1; i++) {\n if (inputRange[i] <= input && inputRange[i + 1] >= input) {\n rangeIdx = i;\n break;\n }\n }\n\n if (rangeIdx === -1) {\n if (inputRange[0] > input) {\n return outputRange[0];\n } else {\n // FIXME: this looks definitely wrong\n return outputRange[(outputRange[0] as any).length - 1];\n }\n }\n\n const inputA = inputRange[rangeIdx];\n const inputB = inputRange[rangeIdx + 1];\n const outputA = outputRange[rangeIdx];\n const outputB = outputRange[rangeIdx + 1];\n\n return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA));\n }\n\n private _lerp(a: number, b: number, fraction: number) {\n return a + fraction * (b - a);\n }\n\n private _resetOrientation() {\n const opt = this.options;\n\n this._axes.setTo({\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }, 0);\n\n return this;\n }\n}\n\nexport default YawPitchControl;\n","import WebGLUtils from \"../WebGLUtils\";\nimport { STEREO_FORMAT } from \"../../PanoViewer/consts\";\nimport { ValueOf } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nconst latitudeBands = 60;\nconst longitudeBands = 60;\nconst radius = 2;\nconst ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\nlet latIdx: number;\nlet lngIdx: number;\n\nfor (latIdx = 0; latIdx <= latitudeBands; latIdx++) {\n const theta = (latIdx / latitudeBands - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / longitudeBands;\n const v = latIdx / latitudeBands;\n\n textureCoordData.push(u, v);\n vertexPositionData.push(radius * x, radius * y, radius * z);\n\n if (lngIdx !== longitudeBands && latIdx !== latitudeBands) {\n const a = latIdx * (longitudeBands + 1) + lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n}\n\nclass SphereRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n private _stereoFormat: ValueOf;\n\n public constructor(format: SphereRenderer[\"_stereoFormat\"]) {\n super();\n\n this._stereoFormat = format;\n }\n\n public render(ctx: Parameters[0]) {\n const {gl, shaderProgram} = ctx;\n\n let leftEyeScaleOffset: number[];\n let rightEyeScaleOffset: number[];\n\n switch (this._stereoFormat) {\n case STEREO_FORMAT.TOP_BOTTOM:\n leftEyeScaleOffset = [1, 0.5, 0, 0];\n rightEyeScaleOffset = [1, 0.5, 0, 0.5];\n break;\n case STEREO_FORMAT.LEFT_RIGHT:\n leftEyeScaleOffset = [0.5, 1, 0, 0];\n rightEyeScaleOffset = [0.5, 1, 0.5, 0];\n break;\n default:\n leftEyeScaleOffset = [1, 1, 0, 0];\n rightEyeScaleOffset = [1, 1, 0, 0];\n }\n\n const uTexScaleOffset = gl.getUniformLocation(shaderProgram, \"uTexScaleOffset\");\n\n gl.uniform4fv(uTexScaleOffset, [...leftEyeScaleOffset, ...rightEyeScaleOffset]);\n\n super.render(ctx);\n }\n\n public getVertexPositionData() {\n return SphereRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return SphereRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return SphereRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const { width, height } = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n}\n\nexport default SphereRenderer;\n","/**\n * Constant value for gyro mode.
(Reference {@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide})\n * @ko gyro 모드 대한 상수 값.
({@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide} 참고)\n * @namespace\n * @name GYRO_MODE\n * @memberof eg.view360.PanoViewer\n */\n/**\n * Disable gyro\n * @ko gyro 비활성화\n * @name NONE\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"none\"\n */\n/**\n * YawPitch Mode\n * @ko YawPitch Mode\n * @name YAWPITCH\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"yawPitch\"\n */\n/**\n * VR Mode\n * @ko VR Mode\n * @name VR\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"VR\"\n */\nimport { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\nimport { GYRO_MODE } from \"../YawPitchControl/consts\";\n\n/**\n * Constant value for errors\n * @ko 에러에 대한 상수 값\n * @namespace\n * @name ERROR_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst ERROR_TYPE = {\n /**\n * Unsupported device\n * @ko 미지원 기기\n * @name INVALID_DEVICE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 10\n */\n INVALID_DEVICE: 10,\n /**\n * Webgl not support\n * @ko WEBGL 미지원\n * @name NO_WEBGL\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 11\n */\n NO_WEBGL: 11,\n /**\n * Failed to load image\n * @ko 이미지 로드 실패\n * @name FAIL_IMAGE_LOAD\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 12\n */\n FAIL_IMAGE_LOAD: 12,\n /**\n * Failed to bind texture\n * @ko 텍스쳐 바인딩 실패\n * @name FAIL_BIND_TEXTURE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 13\n */\n FAIL_BIND_TEXTURE: 13,\n /**\n * Only one resource(image or video) should be specified\n * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함)\n * @name INVALID_RESOURCE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 14\n */\n INVALID_RESOURCE: 14,\n /**\n * WebGL context lost occurred\n * @ko WebGL context lost 발생\n * @name RENDERING_CONTEXT_LOST\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 15\n */\n RENDERING_CONTEXT_LOST: 15\n};\n\n/**\n * Constant value for events\n * @ko 이벤트에 대한 상수 값\n * @namespace\n * @name EVENTS\n * @memberof eg.view360.PanoViewer\n */\nconst PANOVIEWER_EVENTS: {\n READY: \"ready\";\n VIEW_CHANGE: \"viewChange\";\n ANIMATION_END: \"animationEnd\";\n ERROR: \"error\";\n} = {\n /**\n * Events that is fired when PanoViewer is ready to show image and handle user interaction.\n * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트\n * @name READY\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default ready\n */\n READY: \"ready\",\n /**\n * Events that is fired when direction or fov is changed.\n * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트\n * @name VIEW_CHANGE\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default viewChange\n */\n VIEW_CHANGE: \"viewChange\",\n /**\n * Events that is fired when animation which is triggered by inertia is ended.\n * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트\n * @name ANIMATION_END\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default animationEnd\n */\n ANIMATION_END: \"animationEnd\",\n /**\n * Events that is fired when error occurs\n * @ko 에러 발생 시 발생하는 이벤트\n * @name ERROR\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default error\n */\n ERROR: \"error\"\n};\n\n/**\n * Constant value for projection type\n * @ko 프로젝션 타입 대한 상수 값\n * @namespace\n * @name PROJECTION_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst PROJECTION_TYPE: {\n EQUIRECTANGULAR: \"equirectangular\";\n CUBEMAP: \"cubemap\";\n CUBESTRIP: \"cubestrip\";\n PANORAMA: \"panorama\";\n STEREOSCOPIC_EQUI: \"stereoequi\";\n} = {\n /**\n * Constant value for equirectangular type.\n * @ko equirectangular 에 대한 상수 값.\n * @name EQUIRECTANGULAR\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default equirectangular\n */\n EQUIRECTANGULAR: \"equirectangular\",\n /**\n * Constant value for cubemap type.\n * @ko cubemap 에 대한 상수 값.\n * @name CUBEMAP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubemap\n */\n CUBEMAP: \"cubemap\",\n /**\n * Constant value for cubestrip type.\n * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC.\n * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다.\n * @name CUBESTRIP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubestrip\n */\n CUBESTRIP: \"cubestrip\",\n /**\n * Constant value for PANORAMA type.\n *\n * PANORAMA is a format for a panorma image which is taken from smartphone.\n * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다.\n *\n * @name PANORAMA\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default panorama\n */\n PANORAMA: \"panorama\",\n /**\n * Constant value for EQUI_STEREOSCOPY type.\n *\n * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present.\n * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다.\n *\n * @name STEREOSCOPIC_EQUI\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default stereoequi\n */\n STEREOSCOPIC_EQUI: \"stereoequi\"\n};\n\n/**\n * A constant value for the format of the stereoscopic equirectangular projection type.\n * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값\n * @namespace\n * @name STEREO_FORMAT\n * @memberof eg.view360.PanoViewer\n */\nconst STEREO_FORMAT: {\n TOP_BOTTOM: \"3dv\";\n LEFT_RIGHT: \"3dh\";\n NONE: \"\";\n} = {\n /**\n * A constant value for format of top bottom stereoscopic 360 equirectangular projection.\n * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name TOP_BOTTOM\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dv\"\n */\n TOP_BOTTOM: \"3dv\",\n /**\n * A constant value for format of left right stereoscopic 360 equirectangular projection.\n * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name LEFT_RIGHT\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dh\"\n */\n LEFT_RIGHT: \"3dh\",\n /**\n * A constant value specifying media is not in stereoscopic format.\n * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"\"\n */\n NONE: \"\"\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst PANOVIEWER_OPTIONS: { [key in keyof PanoViewerOptions]: true } = {\n image: true,\n video: true,\n projectionType: true,\n cubemapConfig: true,\n stereoFormat: true,\n width: true,\n height: true,\n yaw: true,\n pitch: true,\n fov: true,\n showPolePoint: true,\n useZoom: true,\n useKeyboard: true,\n gyroMode: true,\n yawRange: true,\n pitchRange: true,\n fovRange: true,\n touchDirection: true,\n canvasClass: true\n};\n\nconst DEFAULT_CANVAS_CLASS = \"view360-canvas\";\n\nexport {\n GYRO_MODE,\n PANOVIEWER_EVENTS,\n ERROR_TYPE,\n PROJECTION_TYPE,\n STEREO_FORMAT,\n PANOVIEWER_OPTIONS,\n DEFAULT_CANVAS_CLASS\n};\n","import agent from \"@egjs/agent\";\n\nimport { TypedArray } from \"../types/internal\";\n\nconst WEBGL_ERROR_CODE = {\n \"0\": \"NO_ERROR\",\n \"1280\": \"INVALID_ENUM\",\n \"1281\": \"INVALID_VALUE\",\n \"1282\": \"INVALID_OPERATION\",\n \"1285\": \"OUT_OF_MEMORY\",\n \"1286\": \"INVALID_FRAMEBUFFER_OPERATION\",\n \"37442\": \"CONTEXT_LOST_WEBGL\"\n};\n\nlet webglAvailability: boolean | null = null;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet MAX_TEXTURE_SIZE_FOR_TEST: number | null = null;\n\nexport default class WebGLUtils {\n public static createShader(gl: WebGLRenderingContext, type: number, source: string) {\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (success) {\n return shader;\n }\n\n // eslint-disable-next-line\n console.error(gl.getShaderInfoLog(shader));\n\n return null;\n }\n\n public static createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = gl.createProgram()!;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (success) {\n return program;\n }\n\n gl.deleteProgram(program);\n return null;\n }\n\n public static initBuffer(gl: WebGLRenderingContext, target: number /* bind point */, data: TypedArray, itemSize: number, attr?: number) {\n const buffer = gl.createBuffer()!;\n\n gl.bindBuffer(target, buffer);\n gl.bufferData(target, data, gl.STATIC_DRAW);\n\n if (buffer) {\n (buffer as any).itemSize = itemSize;\n (buffer as any).numItems = data.length / itemSize;\n }\n\n if (attr !== undefined) {\n gl.enableVertexAttribArray(attr);\n gl.vertexAttribPointer(attr, (buffer as any).itemSize, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n }\n\n public static getWebglContext(canvas: HTMLCanvasElement, userContextAttributes?: WebGLContextAttributes) {\n const webglIdentifiers = [\"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n const contextAttributes = {\n ...{\n preserveDrawingBuffer: false,\n antialias: false\n }, ...userContextAttributes\n };\n\n const onWebglcontextcreationerror = e => e.statusMessage;\n\n canvas.addEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n return context;\n }\n\n public static createTexture(gl: WebGLRenderingContext, textureTarget: number) {\n const texture = gl.createTexture();\n\n gl.bindTexture(textureTarget, texture);\n gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(textureTarget, null);\n\n return texture;\n }\n\n /**\n * Returns the webgl availability of the current browser.\n * @method WebGLUtils#isWebGLAvailable\n * @retuen {Boolean} isWebGLAvailable\n */\n public static isWebGLAvailable(): boolean {\n if (webglAvailability === null) {\n const canvas = document.createElement(\"canvas\");\n const webglContext = WebGLUtils.getWebglContext(canvas);\n\n webglAvailability = !!webglContext;\n\n // webglContext Resource forced collection\n if (webglContext) {\n const loseContextExtension = webglContext.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n return !!webglAvailability;\n }\n\n /**\n * Returns whether webgl is stable in the current browser.\n * @method WebGLUtils#isStableWebGL\n * @retuen {Boolean} isStableWebGL\n */\n public static isStableWebGL() {\n const agentInfo = agent();\n let isStableWebgl = true;\n\n if (agentInfo.os.name === \"android\") {\n const version = parseFloat(agentInfo.os.version);\n\n if (version <= 4.3 && version >= 1) {\n isStableWebgl = false;\n } else if (version === 4.4) {\n if (agentInfo.browser.name !== \"chrome\") {\n isStableWebgl = false;\n }\n }\n }\n return isStableWebgl;\n }\n\n public static getErrorNameFromWebGLErrorCode(code: number | string) {\n if (!(code in WEBGL_ERROR_CODE)) {\n return \"UNKNOWN_ERROR\";\n }\n\n return WEBGL_ERROR_CODE[code];\n }\n\n\n /**\n * This function is wrapper for texImage2D to handle exceptions on texImage2D.\n * Purpose is to prevent service from being stopped by script error.\n */\n public static texImage2D(gl: WebGLRenderingContext, target: number, pixels: TexImageSource) {\n try {\n gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n } catch (error) {\n /* eslint-disable no-console */\n console.error(\"WebGLUtils.texImage2D error:\", error);\n /* eslint-enable no-console */\n }\n }\n\n public static getMaxTextureSize(gl: WebGLRenderingContext) {\n // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test\n return MAX_TEXTURE_SIZE_FOR_TEST || gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n}\n\n/**\n * This function should not be used in service code. It's provided only for test purpose.\n * It should be set to null or 0 when test is done.\n * @param {Number} size\n */\nconst setMaxTextureSizeForTestOnlyPurpose = (size: number) => {\n MAX_TEXTURE_SIZE_FOR_TEST = size;\n};\n\nexport {\n setMaxTextureSizeForTestOnlyPurpose\n};\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport agent from \"@egjs/agent\";\nimport { mat4 } from \"gl-matrix\";\n\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nconst agentInfo = agent();\nconst isIE11 = agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11;\n\nconst EVENTS: {\n ERROR: \"error\";\n} = {\n ERROR: \"error\"\n};\n\n/**\n *\n * Extends Component for firing errors occurs internally.\n */\nabstract class Renderer extends Component<{\n [EVENTS.ERROR]: {\n message: string;\n };\n}> {\n public static EVENTS = EVENTS;\n\n private _forceDimension: { width: number; height: number } | null;\n private _pixelCanvas: HTMLCanvasElement | null;\n private _pixelContext: CanvasRenderingContext2D | null;\n\n public constructor() {\n super();\n\n this._forceDimension = null;\n this._pixelCanvas = null;\n this._pixelContext = null;\n }\n\n public abstract getVertexPositionData(): number[];\n public abstract getIndexData(): number[];\n public abstract getTextureCoordData(textureData: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }): number[];\n\n public abstract getVertexShaderSource(): string;\n public abstract getFragmentShaderSource(): string;\n public abstract bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n public abstract updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n\n public render({ gl, shaderProgram, indexBuffer, mvMatrix, pMatrix }: {\n gl: WebGLRenderingContext;\n shaderProgram: WebGLProgram;\n indexBuffer: WebGLBuffer;\n mvMatrix: mat4;\n pMatrix: mat4;\n }) {\n gl.uniformMatrix4fv((shaderProgram as any).pMatrixUniform, false, pMatrix);\n gl.uniformMatrix4fv((shaderProgram as any).mvMatrixUniform, false, mvMatrix);\n\n if (indexBuffer) {\n gl.drawElements(gl.TRIANGLES, (indexBuffer as any).numItems, gl.UNSIGNED_SHORT, 0);\n }\n }\n\n // Define interface for Renderers\n /**\n * Following MUST BE DEFINED on Child of Renderer\n *\n * DATA\n *\n * - getVertexPositionData\n * - getIndexData\n * - getTextureCoordData\n *\n * SOURCE\n *\n * - getVertexShaderSource\n * - getFragmentShaderSource\n *\n * TEXTURE\n *\n * - bindTexture\n */\n public getDimension(pixelSource: HTMLImageElement | HTMLVideoElement) {\n const width = (pixelSource as HTMLImageElement).naturalWidth\n || (pixelSource as HTMLVideoElement).videoWidth;\n const height = (pixelSource as HTMLImageElement).naturalHeight\n || (pixelSource as HTMLVideoElement).videoHeight;\n\n return { width, height };\n }\n\n /**\n * Update data used by shader\n */\n public updateShaderData(param) { // eslint-disable-line @typescript-eslint/no-unused-vars\n /*\n * Update following data in implementation layer.\n * If the data is not changed, it does not need to implement this function.\n *\n * - _VERTEX_POSITION_DATA\n * - _TEXTURE_COORD_DATA\n * - _INDEX_DATA\n */\n }\n\n /**\n *\n * @param {HTMLImageElement | HTMLVideoElement} image\n * @param {Object = {width, height}} forceDimension Forced dimension to resize\n */\n protected _initPixelSource(image: HTMLImageElement | HTMLVideoElement, forceDimension: Renderer[\"_forceDimension\"] = null) {\n const isIE11Video = isIE11 && (image instanceof HTMLVideoElement);\n\n if (isIE11Video || forceDimension) {\n const {width, height} = forceDimension || this.getDimension(image);\n\n this._pixelCanvas = document.createElement(\"canvas\");\n this._pixelCanvas.width = width;\n this._pixelCanvas.height = height;\n this._pixelContext = this._pixelCanvas.getContext(\"2d\");\n }\n this._forceDimension = forceDimension;\n }\n\n protected _getPixelSource(image: HTMLImageElement | HTMLVideoElement) {\n if (!this._pixelCanvas) {\n return image;\n }\n\n /**\n * IE11 && Video\n * or\n * Dimension is forced (Image is larger than texture size.)\n */\n const contentDimension = this.getDimension(image);\n const textureDimension = this._forceDimension || contentDimension;\n\n if (this._pixelCanvas.width !== textureDimension.width) {\n this._pixelCanvas.width = textureDimension.width;\n }\n\n if (this._pixelCanvas.height !== textureDimension.height) {\n this._pixelCanvas.height = textureDimension.height;\n }\n\n if (this._forceDimension) {\n this._pixelContext!.drawImage(image,\n 0, 0, contentDimension.width, contentDimension.height,\n 0, 0, textureDimension.width, textureDimension.height);\n } else {\n this._pixelContext!.drawImage(image, 0, 0);\n }\n\n return this._pixelCanvas;\n }\n\n protected _extractTileConfig(imageConfig: CubemapConfig) {\n let tileConfig: TileConfig[] =\n Array.isArray(imageConfig.tileConfig) ?\n imageConfig.tileConfig : Array(...Array(6)).map(() => imageConfig.tileConfig) as TileConfig[];\n\n tileConfig = tileConfig.map(\n config => ({\n ...{\n flipHorizontal: false,\n rotation: 0\n }, ...config\n })\n );\n\n return tileConfig;\n }\n\n protected _triggerError(error) {\n /* eslint-disable no-console */\n console.error(\"Renderer Error:\", error);\n /* eslint-enable no-console */\n\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n message: typeof error === \"string\" ? error : error.message\n }));\n }\n}\n\nexport default Renderer;\n","import agent from \"@egjs/agent\";\n\nimport WebGLUtils from \"../WebGLUtils\";\nimport { util as mathUtil } from \"../../utils/math-util\";\nimport { CubemapConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nclass CubeRenderer extends Renderer {\n public static extractOrder(imageConfig: CubemapConfig) {\n return imageConfig.order || \"RLUDBF\";\n }\n\n private static _VERTEX_POSITION_DATA: number[] | null = null;\n private static _INDEX_DATA: number[] | null = null;\n\n public getVertexPositionData() {\n CubeRenderer._VERTEX_POSITION_DATA =\n CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // top\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // bottom\n 1, -1, -1,\n -1, -1, -1,\n -1, -1, 1,\n 1, -1, 1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n return CubeRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n if (CubeRenderer._INDEX_DATA) {\n return CubeRenderer._INDEX_DATA;\n }\n\n const indexData: number[] = [];\n const vertexPositionData = this.getVertexPositionData();\n\n for (let i = 0; i < (vertexPositionData.length / 3); i += 4) {\n indexData.push(\n i,\n i + 2,\n i + 1,\n i,\n i + 3,\n i + 2\n );\n }\n\n CubeRenderer._INDEX_DATA = indexData;\n return indexData;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n const vertexOrder = \"BFUDRL\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const base = this.getVertexPositionData();\n const tileConfig = this._extractTileConfig(imageConfig);\n const elemSize = 3;\n const vertexPerTile = 4;\n const { trim } = imageConfig;\n\n const texCoords = vertexOrder.split(\"\")\n .map(face => tileConfig[order.indexOf(face)])\n .map((config, i) => {\n const rotation = Math.floor(config.rotation / 90);\n const ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2];\n\n for (let r = 0; r < Math.abs(rotation); r++) {\n if ((config.flipHorizontal && rotation > 0) ||\n (!config.flipHorizontal && rotation < 0)) {\n ordermap.push(ordermap.shift()!);\n } else {\n ordermap.unshift(ordermap.pop()!);\n }\n }\n\n const elemPerTile = elemSize * vertexPerTile;\n const tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile);\n const tileTemp: number[][] = [];\n\n for (let j = 0; j < vertexPerTile; j++) {\n tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize);\n }\n return tileTemp;\n })\n .map(coord => this._shrinkCoord({ image, faceCoords: coord, trim }))\n .reduce((acc: number[], val: number[][]) => [\n ...acc,\n ...val.reduce((coords, coord) => [...coords, ...coord], [])\n ], []);\n\n return texCoords;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n const baseOrder = \"RLUDBF\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const orderMap = {};\n\n order.split(\"\").forEach((v, i) => {\n orderMap[v] = i;\n });\n\n try {\n if (image instanceof Array) {\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]);\n }\n } else {\n const maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image);\n\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n const tile = this.extractTileFromImage(\n image, tileIdx, maxCubeMapTextureSize\n );\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile);\n }\n }\n } catch (e) {\n this._triggerError(e);\n }\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n this.updateTexture(gl, image, imageConfig);\n }\n\n public getSourceTileSize(image: HTMLImageElement | HTMLVideoElement) {\n const {width, height} = this.getDimension(image);\n const aspectRatio = width / height;\n let inputTextureSize;\n\n if (aspectRatio === 1 / 6) {\n inputTextureSize = width;\n } else if (aspectRatio === 6) {\n inputTextureSize = height;\n } else if (aspectRatio === 2 / 3) {\n inputTextureSize = width / 2;\n } else {\n inputTextureSize = width / 3;\n }\n return inputTextureSize;\n }\n\n public extractTileFromImage(image: HTMLImageElement | HTMLVideoElement, tileIdx: number, outputTextureSize: number) {\n const {width} = this.getDimension(image);\n const inputTextureSize = this.getSourceTileSize(image);\n\n const canvas = document.createElement(\"canvas\");\n\n canvas.width = outputTextureSize;\n canvas.height = outputTextureSize;\n const context = canvas.getContext(\"2d\");\n const tilePerRow = width / inputTextureSize;\n\n const x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow);\n const y = Math.floor(tileIdx / tilePerRow) * (inputTextureSize);\n\n context!.drawImage(\n image, x, y,\n inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize\n );\n return canvas;\n }\n\n public getMaxCubeMapTextureSize(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n const agentInfo = agent();\n const maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n let imageWidth = this.getSourceTileSize(image);\n\n if (agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11) {\n if (!mathUtil.isPowerOfTwo(imageWidth)) {\n for (let i = 1; i < maxCubeMapTextureSize; i *= 2) {\n if (i < imageWidth) {\n continue;\n } else {\n imageWidth = i;\n break;\n }\n }\n }\n }\n if (agentInfo.os.name === \"ios\") {\n const majorVersion = agentInfo.os.majorVersion;\n\n // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다.\n if (majorVersion === 9) {\n imageWidth = 1024;\n }\n // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다.\n if (majorVersion === 8) {\n imageWidth = 512;\n }\n }\n // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수\n return Math.min(maxCubeMapTextureSize, imageWidth);\n }\n\n private _shrinkCoord(coordData: {\n image: HTMLImageElement | HTMLVideoElement;\n faceCoords: number[][];\n trim: number;\n }) {\n const { image, faceCoords, trim } = coordData;\n\n const inputTextureSize = Array.isArray(image)\n ? this.getDimension(image[0]).width\n : this.getSourceTileSize(image);\n\n // Shrink by \"trim\" px\n const SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize);\n\n const axisMultipliers = [0, 1, 2].map(axisIndex => {\n const axisDir = mathUtil.sign(faceCoords[0][axisIndex]);\n const notSameDir = faceCoords.some(coord => mathUtil.sign(coord[axisIndex]) !== axisDir);\n\n return notSameDir;\n }).map(notSameDir => notSameDir ? SHRINK_MULTIPLIER : 1);\n\n return faceCoords.map(coords => coords.map((coord, axisIndex) => coord * axisMultipliers[axisIndex]));\n }\n}\n\nexport default CubeRenderer;\n","\nimport WebGLUtils from \"../WebGLUtils\";\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nexport default class CubeStripRenderer extends Renderer {\n private _vertices: number[];\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}`;\n }\n\n public getVertexPositionData() {\n if (!this._vertices) {\n this._vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n }\n\n return this._vertices;\n }\n\n public getIndexData() {\n // TODO: 한번만 계산하도록 수정하기\n const indices = (() => {\n const indexData: number[] = [];\n\n for (let i = 0; i < (this._vertices.length / 3); i += 4) {\n indexData.push(\n i,\n i + 1,\n i + 2,\n i,\n i + 2,\n i + 3\n );\n }\n return indexData;\n })();\n\n return indices;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n // TODO: make it cols, rows as config.\n const cols = 3;\n const rows = 2;\n\n const textureSize = this.getDimension(image);\n const { trim } = imageConfig;\n\n const order = imageConfig.order || \"RLUDFB\";\n let coords: number[][] = [];\n\n // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다.\n for (let r = rows - 1; r >= 0; r--) {\n for (let c = 0; c < cols; c++) {\n const coord = [\n c / cols, r / rows,\n (c + 1) / cols, r / rows,\n (c + 1) / cols, (r + 1) / rows,\n c / cols, (r + 1) / rows\n ];\n\n coords.push(coord);\n }\n }\n\n const tileConfigs = this._extractTileConfig(imageConfig);\n\n // Transform Coord By Flip & Rotation\n coords = coords\n // shrink coord to avoid pixel bleeding\n .map(coord => this._shrinkCoord(coord, textureSize, trim))\n .map((coord, i) => this._transformCoord(coord, tileConfigs[i]));\n\n // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치\n return \"BFUDRL\".split(\"\")\n .map(face => order.indexOf(face))\n .map(index => coords[index])\n .reduce((acc, val) => acc.concat(val), []);\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n private _transformCoord(coord: number[], tileConfig: TileConfig) {\n let newCoord = coord.slice();\n\n if (tileConfig.flipHorizontal) {\n newCoord = this._flipHorizontalCoord(newCoord);\n }\n\n if (tileConfig.rotation) {\n newCoord = this._rotateCoord(newCoord, tileConfig.rotation);\n }\n\n return newCoord;\n }\n\n private _shrinkCoord(coord: number[], textureSize: { width: number; height: number }, trim: number) {\n const { width, height } = textureSize;\n\n // Shrink by \"trim\" px\n const SHRINK_Y = trim * (1 / height);\n const SHRINK_X = trim * (1 / width);\n\n return [\n coord[0] + SHRINK_X, coord[1] + SHRINK_Y,\n coord[2] - SHRINK_X, coord[3] + SHRINK_Y,\n coord[4] - SHRINK_X, coord[5] - SHRINK_Y,\n coord[6] + SHRINK_X, coord[7] - SHRINK_Y\n ];\n }\n\n private _rotateCoord(coord: number[], rotationAngle: number) {\n const SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord.\n const shiftCount = Math.floor(rotationAngle / 90) % 4;\n\n if (shiftCount === 0) {\n return coord;\n }\n\n let moved;\n let rotatedCoord: number[] = [];\n\n if (shiftCount > 0) {\n moved = coord.splice(0, shiftCount * SIZE);\n rotatedCoord = coord.concat(moved);\n } else {\n moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE);\n rotatedCoord = moved.concat(coord);\n }\n\n return rotatedCoord;\n }\n\n private _flipHorizontalCoord(coord: number[]) {\n return [\n coord[2], coord[3],\n coord[0], coord[1],\n coord[6], coord[7],\n coord[4], coord[5]\n ];\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport WebGLUtils from \"../WebGLUtils\";\n\nimport Renderer from \"./Renderer\";\n\n// const latitudeBands = 60;\nconst MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6;\nconst longitudeBands = 60;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\n\nclass CylinderRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n public getVertexPositionData() {\n return CylinderRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return CylinderRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return CylinderRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n let resizeDimension: { width: number; height: number } | undefined;\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device texture limit(${maxSize}))`);\n\n // Request resizing texture.\n /**\n * TODO: Is it need to apply on another projection type?\n */\n resizeDimension = width > height ?\n {width: maxSize, height: maxSize * height / width} :\n {width: maxSize * width / height, height: maxSize};\n }\n\n // Pixel Source for IE11 & Video or resizing needed\n this._initPixelSource(image, resizeDimension);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n public updateShaderData({ imageAspectRatio = MIN_ASPECT_RATIO_FOR_FULL_PANORAMA }) {\n let lngIdx: number;\n let cylinderMaxRadian: number;\n let halfCylinderY: number;\n let rotated: boolean;\n let aspectRatio: number;\n\n // Exception case: orientation is rotated.\n if (imageAspectRatio < 1) {\n /**\n * If rotated is true, we assume that image is rotated counter clockwise.\n * TODO: If there's other rotation, it is need to implement by each rotation.\n */\n rotated = true;\n aspectRatio = 1 / imageAspectRatio;\n } else {\n rotated = false;\n aspectRatio = imageAspectRatio;\n }\n\n if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) {\n const fov = 360 / aspectRatio;\n\n cylinderMaxRadian = 2 * Math.PI; // 360 deg\n halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2));\n } else {\n cylinderMaxRadian = aspectRatio;\n halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1.\n }\n\n // initialize shader data before update\n textureCoordData.length = 0;\n vertexPositionData.length = 0;\n indexData.length = 0;\n\n const CYLIDER_Y = [-halfCylinderY, halfCylinderY];\n const startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360)\n\n // console.log(\"cylinderMaxRadian:\", glMatrix.toDegree(cylinderMaxRadian), \"CYLIDER_Y\", CYLIDER_Y, \"start angle\", glMatrix.toDegree(startAngleForCenterAlign));\n for (let yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength/* bottom & top */; yIdx++) {\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const angle = startAngleForCenterAlign + (lngIdx / longitudeBands * cylinderMaxRadian);\n const x = Math.cos(angle);\n const y = CYLIDER_Y[yIdx];\n const z = Math.sin(angle);\n let u: number;\n let v: number;\n\n if (rotated) {\n // Rotated 90 degree (counter clock wise)\n u = 1 - yIdx; // yLength - yIdx;\n v = lngIdx / longitudeBands;\n } else {\n // \t// Normal case (Not rotated)\n u = lngIdx / longitudeBands;\n v = yIdx;\n }\n\n textureCoordData.push(u, v);\n vertexPositionData.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < longitudeBands) {\n const a = lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n }\n}\n\nexport default CylinderRenderer;\n","import Promise from \"promise-polyfill\";\nimport { mat4 } from \"gl-matrix\";\n\nconst VR_DISPLAY_PRESENT_CHANGE = \"vrdisplaypresentchange\";\nconst DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1];\nconst DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1];\nconst EYES = {\n LEFT: \"left\",\n RIGHT: \"right\"\n} as const;\n\nclass VRManager {\n private _vrDisplay: VRDisplay | null;\n private _frameData: VRFrameData;\n private _yawOffset: number;\n private _leftBounds: number[];\n private _rightBounds: number[];\n\n public constructor() {\n this._frameData = new window.VRFrameData();\n this._clear();\n }\n\n public get context() { return this._vrDisplay; }\n\n public destroy = () => {\n const vrDisplay = this._vrDisplay;\n\n this.removeEndCallback(this.destroy);\n\n if (vrDisplay && vrDisplay.isPresenting) {\n void vrDisplay.exitPresent();\n }\n\n this._clear();\n };\n\n public canRender() {\n return Boolean(this._vrDisplay);\n }\n\n public beforeRender(gl: WebGLRenderingContext) {\n // Render to the default backbuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public afterRender() {\n this._vrDisplay!.submitFrame();\n }\n\n public getEyeParams(gl: WebGLRenderingContext) {\n const display = this._vrDisplay!;\n const halfWidth = gl.drawingBufferWidth * 0.5;\n const height = gl.drawingBufferHeight;\n const frameData = this._frameData;\n\n display.getFrameData(frameData);\n\n const leftMVMatrix = frameData.leftViewMatrix;\n const rightMVMatrix = frameData.rightViewMatrix;\n\n mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset);\n mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset);\n\n return [\n {\n viewport: [0, 0, halfWidth, height],\n mvMatrix: leftMVMatrix,\n pMatrix: frameData.leftProjectionMatrix\n },\n {\n viewport: [halfWidth, 0, halfWidth, height],\n mvMatrix: rightMVMatrix,\n pMatrix: frameData.rightProjectionMatrix\n }\n ];\n }\n\n public isPresenting() {\n return Boolean(this._vrDisplay && this._vrDisplay.isPresenting);\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public requestPresent(canvas: HTMLCanvasElement) {\n return navigator.getVRDisplays().then(displays => {\n const vrDisplay = displays.length && displays[0];\n\n if (!vrDisplay) {\n return Promise.reject(new Error(\"No displays available.\"));\n }\n if (!vrDisplay.capabilities.canPresent) {\n return Promise.reject(new Error(\"Display lacking capability to present.\"));\n }\n\n return vrDisplay.requestPresent([{source: canvas}]).then(() => {\n const leftEye = vrDisplay.getEyeParameters(EYES.LEFT);\n const rightEye = vrDisplay.getEyeParameters(EYES.RIGHT);\n\n canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;\n canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);\n\n this._setDisplay(vrDisplay);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setDisplay(vrDisplay: VRDisplay) {\n this._vrDisplay = vrDisplay;\n\n const layers = vrDisplay.getLayers();\n\n if (layers.length) {\n const layer = layers[0];\n\n this._leftBounds = layer.leftBounds as number[];\n this._rightBounds = layer.rightBounds as number[];\n }\n\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._vrDisplay = null;\n this._leftBounds = DEFAULT_LEFT_BOUNDS;\n this._rightBounds = DEFAULT_RIGHT_BOUNDS;\n this._yawOffset = 0;\n }\n}\n\nexport default VRManager;\n","import { mat4, glMatrix } from \"gl-matrix\";\nimport { XRFrame, XRLayer, XRReferenceSpace, XRSession, XRSessionInit } from \"webxr\";\n\nimport { IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { merge } from \"../../utils/utils\";\n\nconst XR_REFERENCE_SPACE = \"local\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\nclass XRManager {\n private _xrSession: XRSession | null;\n private _xrLayer: XRLayer | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n private _yawOffset: number;\n private _presenting: boolean;\n\n public constructor(options: XRSessionOptions = {}) {\n this._clear();\n this._options = options;\n }\n\n public get context() { return this._xrSession; }\n\n public destroy = () => {\n const xrSession = this._xrSession;\n\n this.removeEndCallback(this.destroy);\n\n if (xrSession) {\n // Capture to avoid errors\n xrSession.end().then(() => void 0, () => void 0);\n }\n this._clear();\n };\n\n public canRender(frame: XRFrame) {\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n return Boolean(pose);\n }\n\n public beforeRender(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer!.framebuffer);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n public afterRender() {}\n\n public getEyeParams(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) {\n // Can't render\n return null;\n }\n\n const glLayer = session.renderState.baseLayer;\n\n return pose.views.map(view => {\n const viewport = glLayer!.getViewport(view);\n const mvMatrix = view.transform.inverse.matrix;\n\n if (IS_SAFARI_ON_DESKTOP) {\n mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180));\n }\n\n mat4.rotateY(mvMatrix, mvMatrix, this._yawOffset);\n\n return {\n viewport: [viewport.x, viewport.y, viewport.width, viewport.height],\n mvMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n public isPresenting() {\n return this._presenting;\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.addEventListener(\"end\", callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.removeEventListener(\"end\", callback);\n }\n\n public async requestPresent(canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {\n const options = merge({\n requiredFeatures: [XR_REFERENCE_SPACE]\n }, this._options);\n\n const attributes = gl.getContextAttributes();\n if (attributes && (attributes as any).xrCompatible !== true) {\n await (gl as any).makeXRCompatible();\n }\n\n return (navigator as any).xr.requestSession(\"immersive-vr\", options).then(session => {\n const xrLayer = new (window as any).XRWebGLLayer(session, gl);\n\n session.updateRenderState({baseLayer: xrLayer});\n return session.requestReferenceSpace(XR_REFERENCE_SPACE)\n .then(refSpace => {\n this._setSession(session, xrLayer, refSpace);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setSession(session: XRSession, xrLayer: XRLayer, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrLayer = xrLayer;\n this._xrRefSpace = refSpace;\n this._presenting = true;\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._xrSession = null;\n this._xrLayer = null;\n this._xrRefSpace = null;\n this._presenting = false;\n this._yawOffset = 0;\n this._options = {};\n }\n}\n\nexport default XRManager;\n","import { IS_SAFARI_ON_DESKTOP } from \"../utils/browser\";\n\nclass WebGLAnimator {\n private _callback: ((...args: any[]) => any) | null;\n private _context: any;\n private _rafId: number;\n private _rafTimer: number;\n\n public constructor() {\n this._callback = null;\n this._context = window;\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public setCallback(callback: (...args: any[]) => any) {\n this._callback = callback;\n }\n\n public setContext(context: any) {\n this._context = context;\n }\n\n public start() {\n const context = this._context;\n const callback = this._callback;\n\n // No context / callback set\n if (!context || !callback) return;\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n if (IS_SAFARI_ON_DESKTOP) {\n this._rafId = context.requestAnimationFrame(this._onLoopNextTick);\n } else {\n this._rafId = context.requestAnimationFrame(this._onLoop);\n }\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n /**\n * There can be more than 1 argument when we use XRSession's raf\n */\n private _onLoop = (...args: any[]) => {\n this._callback!(...args);\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n };\n\n /**\n * MacOS X Safari Bug Fix\n * This code guarantees that rendering should be occurred.\n *\n * In MacOS X(10.14.2), Safari (12.0.2)\n * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term\n * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms)\n * So browser cannot render the frame and may be freezing.\n */\n private _onLoopNextTick = (...args: any[]) => {\n const before = performance.now();\n\n this._callback!(...args);\n\n const diff = performance.now() - before;\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n this._rafTimer = -1;\n }\n\n /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */\n if (diff < 16) {\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n } else {\n /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */\n this._rafTimer = window.setTimeout(this._onLoop, 0);\n }\n };\n}\n\nexport default WebGLAnimator;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { XRFrame } from \"webxr\";\nimport Promise from \"promise-polyfill\";\nimport { glMatrix, vec3, mat3, mat4, quat } from \"gl-matrix\";\nimport ImReady, { OnReady } from \"@egjs/imready\";\n\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { devicePixelRatio, WEBXR_SUPPORTED } from \"../utils/browserFeature\";\nimport { PROJECTION_TYPE, STEREO_FORMAT } from \"../PanoViewer/consts\";\nimport { IS_IOS } from \"../utils/browser\";\nimport { CubemapConfig, ImageCandidate, ValueOf, VideoCandidate } from \"../types/internal\";\nimport YawPitchControl from \"../YawPitchControl/YawPitchControl\";\nimport { toImageElement, toVideoElement } from \"../utils/utils\";\n\nimport WebGLUtils from \"./WebGLUtils\";\nimport Renderer from \"./renderer/Renderer\";\nimport CubeRenderer from \"./renderer/CubeRenderer\";\nimport CubeStripRenderer from \"./renderer/CubeStripRenderer\";\nimport SphereRenderer from \"./renderer/SphereRenderer\";\nimport CylinderRenderer from \"./renderer/CylinderRenderer\";\nimport VRManager from \"./vr/VRManager\";\nimport XRManager from \"./vr/XRManager\";\nimport WebGLAnimator from \"./WebGLAnimator\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ImageType = PROJECTION_TYPE;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet DEVICE_PIXEL_RATIO = devicePixelRatio || 1;\n\n// DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다.\nif (DEVICE_PIXEL_RATIO > 2) {\n DEVICE_PIXEL_RATIO = 2;\n}\n\n// define custom events name\n/**\n * TODO: how to manage events/errortype with PanoViewer\n *\n * I think renderer events should be seperated from viewer events although it has same name.\n */\nconst EVENTS: {\n BIND_TEXTURE: \"bindTexture\";\n IMAGE_LOADED: \"imageLoaded\";\n ERROR: \"error\";\n RENDERING_CONTEXT_LOST: \"renderingContextLost\";\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\";\n} = {\n BIND_TEXTURE: \"bindTexture\",\n IMAGE_LOADED: \"imageLoaded\",\n ERROR: \"error\",\n RENDERING_CONTEXT_LOST: \"renderingContextLost\",\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\"\n};\n\nconst ERROR_TYPE = {\n INVALID_DEVICE: 10,\n NO_WEBGL: 11,\n FAIL_IMAGE_LOAD: 12,\n RENDERER_ERROR: 13\n};\n\nclass PanoImageRenderer extends Component<{\n [EVENTS.ERROR]: {\n type: number;\n message: string;\n };\n [EVENTS.IMAGE_LOADED]: {\n content: HTMLElement;\n isVideo: boolean;\n projectionType: ValueOf;\n };\n [EVENTS.BIND_TEXTURE]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_LOST]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_RESTORE]: ComponentEvent;\n}> {\n public static EVENTS = EVENTS;\n public static ERROR_TYPE = ERROR_TYPE;\n\n public sphericalConfig: {\n initialYaw: number;\n initialPitch: number;\n fieldOfView: number;\n imageType: ValueOf;\n stereoFormat: ValueOf;\n cubemapConfig: Partial;\n };\n\n public fieldOfView: number;\n public width: number;\n public height: number;\n\n public canvas: HTMLCanvasElement;\n public context: WebGLRenderingContext;\n public shaderProgram: WebGLProgram | null;\n public texture: WebGLTexture;\n\n public pMatrix: mat4;\n public mvMatrix: mat4;\n\n public textureCoordBuffer: WebGLBuffer | null = null;\n public vertexBuffer: WebGLBuffer | null = null;\n public indexBuffer: WebGLBuffer | null = null;\n\n private _wrapper: HTMLElement | null;\n private _wrapperOrigStyle: string | null;\n private _lastQuaternion: quat | null;\n private _lastYaw: number | null;\n private _lastPitch: number | null;\n private _lastFieldOfView: number | null;\n private _renderingContextAttributes?: WebGLContextAttributes;\n\n private _renderer: Renderer;\n private _contentLoader: ImReady | null;\n private _image: HTMLImageElement | HTMLImageElement[] | HTMLVideoElement | null;\n private _imageConfig: CubemapConfig | null;\n private _imageType: ValueOf;\n private _imageIsReady: boolean;\n private _isVideo: boolean;\n private _isCubeMap: boolean;\n private _shouldForceDraw: boolean;\n private _keepUpdate: boolean;\n private _hasExternalCanvas: boolean;\n\n private _yawPitchControl: YawPitchControl;\n private _animator: WebGLAnimator;\n private _vr: VRManager | XRManager | null;\n\n public constructor(\n image: ImageCandidate | VideoCandidate,\n width: number,\n height: number,\n isVideo: boolean,\n container: HTMLElement,\n canvasClass: string,\n sphericalConfig: PanoImageRenderer[\"sphericalConfig\"],\n renderingContextAttributes?: WebGLContextAttributes\n ) {\n // Super constructor\n super();\n\n this.sphericalConfig = sphericalConfig;\n this.fieldOfView = sphericalConfig.fieldOfView;\n\n this.width = width;\n this.height = height;\n\n this._lastQuaternion = null;\n this._lastYaw = null;\n this._lastPitch = null;\n this._lastFieldOfView = null;\n\n this.pMatrix = mat4.create();\n this.mvMatrix = mat4.create();\n\n // initialzie pMatrix\n mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), width / height, 0.1, 100);\n\n this.textureCoordBuffer = null;\n this.vertexBuffer = null;\n this.indexBuffer = null;\n\n this.canvas = this._initCanvas(container, canvasClass, width, height);\n\n this._setDefaultCanvasStyle();\n this._wrapper = null; // canvas wrapper\n this._wrapperOrigStyle = null;\n\n this._renderingContextAttributes = renderingContextAttributes;\n this._image = null;\n this._imageConfig = null;\n this._imageIsReady = false;\n this._shouldForceDraw = false;\n this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still.\n\n this._onContentLoad = this._onContentLoad.bind(this);\n this._onContentError = \tthis._onContentError.bind(this);\n\n this._animator = new WebGLAnimator();\n\n // VR/XR manager\n this._vr = null;\n\n if (image) {\n this.setImage({\n image,\n imageType: sphericalConfig.imageType,\n isVideo,\n cubemapConfig: sphericalConfig.cubemapConfig\n });\n }\n }\n\n // FIXME: Please refactor me to have more loose connection to yawpitchcontrol\n public setYawPitchControl(yawPitchControl: YawPitchControl) {\n this._yawPitchControl = yawPitchControl;\n }\n\n public getContent() {\n return this._image;\n }\n\n public setImage({\n image,\n imageType,\n isVideo = false,\n cubemapConfig\n }: {\n image: ImageCandidate | VideoCandidate;\n imageType: PanoImageRenderer[\"_imageType\"];\n isVideo: boolean;\n cubemapConfig: Partial;\n }) {\n this._imageIsReady = false;\n this._isVideo = isVideo;\n this._imageConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only */\n order: (imageType === ImageType.CUBEMAP) ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n },\n ...cubemapConfig\n };\n this._setImageType(imageType);\n\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._contentLoader = new ImReady()\n .on(\"ready\", this._onContentLoad)\n .on(\"error\", this._onContentError);\n\n if (isVideo) {\n this._image = toVideoElement(image as VideoCandidate);\n this._contentLoader.check([this._image]);\n this._keepUpdate = true;\n } else {\n this._image = toImageElement(image as ImageCandidate);\n this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n this._keepUpdate = false;\n }\n }\n\n public isImageLoaded() {\n return !!this._image && this._imageIsReady &&\n (!this._isVideo || (this._image as HTMLVideoElement).readyState >= 2 /* HAVE_CURRENT_DATA */);\n }\n\n public bindTexture() {\n return new Promise((res, rej) => {\n const contentLoader = this._contentLoader;\n\n if (!this._image) {\n return rej(\"Image is not defined\");\n }\n\n if (!contentLoader) {\n return rej(\"ImageLoader is not initialized\");\n }\n\n if (contentLoader.isReady()) {\n this._bindTexture();\n res();\n } else {\n contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n contentLoader.once(\"ready\", e => {\n if (e.errorCount > 0) {\n rej(\"Failed to load images.\");\n } else {\n this._bindTexture();\n res();\n }\n });\n }\n });\n }\n\n // 부모 엘리먼트에 canvas 를 붙임\n public attachTo(parentElement) {\n if (!this._hasExternalCanvas) {\n this.detach();\n parentElement.appendChild(this.canvas);\n }\n this._wrapper = parentElement;\n }\n\n public forceContextLoss() {\n if (this.hasRenderingContext()) {\n const loseContextExtension = this.context.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n\n // 부모 엘리먼트에서 canvas 를 제거\n public detach() {\n if (!this._hasExternalCanvas && this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n\n public destroy() {\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._animator.stop();\n this.detach();\n this.forceContextLoss();\n\n this.off();\n\n this.canvas.removeEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n this.canvas.removeEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n }\n\n public hasRenderingContext() {\n const ctx = this.context;\n if (\n !ctx\n || ctx.isContextLost()\n || !ctx.getProgramParameter(this.shaderProgram!, ctx.LINK_STATUS)) {\n return false;\n }\n return true;\n }\n\n public updateFieldOfView(fieldOfView) {\n this.fieldOfView = fieldOfView;\n this._updateViewport();\n }\n\n public updateViewportDimensions(width, height) {\n let viewPortChanged = false;\n\n this.width = width;\n this.height = height;\n\n const w = width * DEVICE_PIXEL_RATIO;\n const h = height * DEVICE_PIXEL_RATIO;\n\n if (w !== this.canvas.width) {\n this.canvas.width = w;\n viewPortChanged = true;\n }\n\n if (h !== this.canvas.height) {\n this.canvas.height = h;\n viewPortChanged = true;\n }\n\n if (!viewPortChanged) {\n return;\n }\n\n this._updateViewport();\n this._shouldForceDraw = true;\n }\n\n public keepUpdate(doUpdate) {\n if (doUpdate && this.isImageLoaded() === false) {\n // Force to draw a frame after image is loaded on render()\n this._shouldForceDraw = true;\n }\n\n this._keepUpdate = doUpdate;\n }\n\n public startRender() {\n this._animator.setCallback(this._render.bind(this));\n this._animator.start();\n }\n\n public stopRender() {\n this._animator.stop();\n }\n\n public renderWithQuaternion(quaternion, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // updatefieldOfView only if fieldOfView is changed.\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion);\n\n this._draw();\n\n this._lastQuaternion = quat.clone(quaternion);\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n public renderWithYawPitch(yaw, pitch, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastYaw !== null && this._lastYaw === yaw &&\n this._lastPitch !== null && this._lastPitch === pitch &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n mat4.identity(this.mvMatrix);\n mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch));\n mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw));\n\n this._draw();\n\n this._lastYaw = yaw;\n this._lastPitch = pitch;\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n /**\n * Returns projection renderer by each type\n */\n public getProjectionRenderer() {\n return this._renderer;\n }\n\n /**\n * @return Promise\n */\n public enterVR(options) {\n const vr = this._vr;\n\n if (!WEBXR_SUPPORTED && !(navigator as any).getVRDisplays) {\n return Promise.reject(\"VR is not available on this browser.\");\n }\n if (vr && vr.isPresenting()) {\n return Promise.resolve(\"VR already enabled.\");\n }\n\n return this._requestPresent(options);\n }\n\n public exitVR = () => {\n const vr = this._vr;\n const gl = this.context;\n const animator = this._animator;\n\n if (!vr) return;\n\n vr.removeEndCallback(this.exitVR);\n vr.destroy();\n this._vr = null;\n\n // Restore canvas & context on iOS\n if (IS_IOS) {\n this._restoreStyle();\n }\n this.updateViewportDimensions(this.width, this.height);\n this._updateViewport();\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._bindBuffers();\n this._shouldForceDraw = true;\n\n animator.stop();\n animator.setContext(window);\n animator.setCallback(this._render.bind(this));\n animator.start();\n };\n\n private _setImageType(imageType) {\n if (!imageType || this._imageType === imageType) {\n return;\n }\n\n this._imageType = imageType;\n this._isCubeMap = imageType === ImageType.CUBEMAP;\n\n if (this._renderer) {\n this._renderer.off();\n }\n\n switch (imageType) {\n case ImageType.CUBEMAP:\n this._renderer = new CubeRenderer();\n break;\n case ImageType.CUBESTRIP:\n this._renderer = new CubeStripRenderer();\n break;\n case ImageType.PANORAMA:\n this._renderer = new CylinderRenderer();\n break;\n case ImageType.STEREOSCOPIC_EQUI:\n this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat);\n break;\n default:\n this._renderer = new SphereRenderer(STEREO_FORMAT.NONE);\n break;\n }\n\n this._renderer.on(Renderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERER_ERROR,\n message: e.message\n }));\n });\n\n this._initWebGL();\n }\n\n private _initCanvas(container: HTMLElement, canvasClass: string, width: number, height: number) {\n const canvasInContainer = container.querySelector(`.${canvasClass}`);\n const canvas = canvasInContainer || this._createCanvas(canvasClass);\n\n this._hasExternalCanvas = !!canvasInContainer;\n\n canvas.width = width;\n canvas.height = height;\n\n this._onWebglcontextlost = this._onWebglcontextlost.bind(this);\n this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this);\n\n canvas.addEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n canvas.addEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n\n return canvas;\n }\n\n private _createCanvas(className: string) {\n const canvas = document.createElement(\"canvas\");\n\n canvas.className = className;\n\n return canvas;\n }\n\n private _setDefaultCanvasStyle() {\n const canvas = this.canvas;\n\n canvas.style.bottom = \"0\";\n canvas.style.left = \"0\";\n canvas.style.right = \"0\";\n canvas.style.top = \"0\";\n canvas.style.margin = \"auto\";\n canvas.style.maxHeight = \"100%\";\n canvas.style.maxWidth = \"100%\";\n canvas.style.outline = \"none\";\n canvas.style.position = \"absolute\";\n }\n\n private _onContentError() {\n this._imageIsReady = false;\n this._image = null;\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_IMAGE_LOAD,\n message: \"failed to load image\"\n }));\n\n return false;\n }\n\n private _triggerContentLoad() {\n this.trigger(new ComponentEvent(EVENTS.IMAGE_LOADED, {\n content: this._image as HTMLElement,\n isVideo: this._isVideo,\n projectionType: this._imageType\n }));\n }\n\n private _onContentLoad(e: OnReady) {\n if (e.errorCount > 0) return;\n\n this._imageIsReady = true;\n\n this._triggerContentLoad();\n }\n\n private _initShaderProgram() {\n const gl = this.context;\n\n if (this.shaderProgram) {\n gl.deleteProgram(this.shaderProgram);\n this.shaderProgram = null;\n }\n\n const renderer = this._renderer;\n\n const vsSource = renderer.getVertexShaderSource();\n const fsSource = renderer.getFragmentShaderSource();\n\n const vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource)!;\n const fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource)!;\n\n const shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader);\n\n if (!shaderProgram) {\n throw new Error(`Failed to initialize shaders: ${WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())}`);\n }\n\n gl.useProgram(shaderProgram);\n (shaderProgram as any).vertexPositionAttribute = gl.getAttribLocation(shaderProgram, \"aVertexPosition\");\n (shaderProgram as any).pMatrixUniform = gl.getUniformLocation(shaderProgram, \"uPMatrix\");\n (shaderProgram as any).mvMatrixUniform = gl.getUniformLocation(shaderProgram, \"uMVMatrix\");\n (shaderProgram as any).samplerUniform = gl.getUniformLocation(shaderProgram, \"uSampler\");\n (shaderProgram as any).textureCoordAttribute = gl.getAttribLocation(shaderProgram, \"aTextureCoord\");\n (shaderProgram as any).uEye = gl.getUniformLocation(shaderProgram, \"uEye\");\n\n gl.enableVertexAttribArray((shaderProgram as any).vertexPositionAttribute);\n gl.enableVertexAttribArray((shaderProgram as any).textureCoordAttribute);\n\n // clear buffer\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\n // Use TEXTURE0\n gl.uniform1i((shaderProgram as any).samplerUniform, 0);\n\n this.shaderProgram = shaderProgram;\n }\n\n private _onWebglcontextlost(e) {\n e.preventDefault();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_LOST));\n }\n\n private _onWebglcontextrestored() {\n this._initWebGL();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_RESTORE));\n }\n\n private _updateViewport() {\n mat4.perspective(\n this.pMatrix,\n glMatrix.toRadian(this.fieldOfView),\n this.canvas.width / this.canvas.height,\n 0.1,\n 100);\n\n this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight);\n }\n\n private _initWebGL() {\n let gl: WebGLRenderingContext;\n\n // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed.\n try {\n this._initRenderingContext();\n gl = this.context;\n\n this.updateViewportDimensions(this.width, this.height);\n this._initShaderProgram();\n } catch (e) {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n this.destroy();\n console.error(e); // eslint-disable-line no-console\n return;\n }\n // 캔버스를 투명으로 채운다.\n gl.clearColor(0, 0, 0, 0);\n const textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\n\n if (this.texture) {\n gl.deleteTexture(this.texture);\n }\n\n this.texture = WebGLUtils.createTexture(gl, textureTarget)!;\n\n if (this._imageType === ImageType.CUBESTRIP) {\n // TODO: Apply following options on other projection type.\n gl.enable(gl.CULL_FACE);\n // gl.enable(gl.DEPTH_TEST);\n }\n }\n\n private _initRenderingContext() {\n if (this.hasRenderingContext()) {\n return;\n }\n\n if (!window.WebGLRenderingContext) {\n throw new Error(\"WebGLRenderingContext not available.\");\n }\n\n this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes)!;\n\n if (!this.context) {\n throw new Error(\"Failed to acquire 3D rendering context\");\n }\n }\n\n private _initBuffers() {\n const image = this._image as HTMLImageElement | HTMLVideoElement;\n\n const vertexPositionData = this._renderer.getVertexPositionData();\n const indexData = this._renderer.getIndexData();\n const textureCoordData = this._renderer.getTextureCoordData({\n image,\n imageConfig: this._imageConfig!\n });\n const gl = this.context;\n\n this.vertexBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3,\n (this.shaderProgram as any).vertexPositionAttribute);\n\n this.indexBuffer = WebGLUtils.initBuffer(\n gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1);\n\n this.textureCoordBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2,\n (this.shaderProgram as any).textureCoordAttribute);\n\n this._bindBuffers();\n }\n\n private _bindTexture() {\n // Detect if it is EAC Format while CUBESTRIP mode.\n // We assume it is EAC if image is not 3/2 ratio.\n if (this._imageType === ImageType.CUBESTRIP) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const isEAC = width && height && width / height !== 1.5 ? 1 : 0;\n\n this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram!, \"uIsEAC\"), isEAC);\n } else if (this._imageType === ImageType.PANORAMA) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const imageAspectRatio = width && height && width / height;\n\n this._renderer.updateShaderData({imageAspectRatio});\n }\n\n // initialize shader buffers after image is loaded.(by updateShaderData)\n // because buffer may be differ by image size.(eg. CylinderRenderer)\n this._initBuffers();\n\n this._renderer.bindTexture(\n this.context,\n this.texture,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n this._shouldForceDraw = true;\n\n this.trigger(new ComponentEvent(EVENTS.BIND_TEXTURE));\n }\n\n private _updateTexture() {\n this._renderer.updateTexture(\n this.context,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n }\n\n private _render() {\n const yawPitchControl = this._yawPitchControl;\n const fov = yawPitchControl.getFov();\n\n if (yawPitchControl.shouldRenderWithQuaternion()) {\n const quaternion = yawPitchControl.getQuaternion();\n\n this.renderWithQuaternion(quaternion, fov);\n } else {\n const yawPitch = yawPitchControl.getYawPitch();\n\n this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov);\n }\n }\n\n private _renderStereo = (time: number, frame: XRFrame) => {\n const vr = this._vr;\n const gl = this.context;\n\n const eyeParams = vr!.getEyeParams(gl, frame);\n\n if (!eyeParams) return;\n\n vr!.beforeRender(gl, frame);\n\n // Render both eyes\n for (const eyeIndex of [0, 1]) {\n const eyeParam = eyeParams[eyeIndex];\n\n this.mvMatrix = eyeParam.mvMatrix;\n this.pMatrix = eyeParam.pMatrix;\n\n gl.viewport(...eyeParam.viewport as [number, number, number, number]);\n gl.uniform1f((this.shaderProgram as any).uEye, eyeIndex);\n\n this._bindBuffers();\n this._draw();\n }\n\n vr!.afterRender();\n };\n\n private _bindBuffers() {\n const gl = this.context;\n const program = this.shaderProgram;\n\n const vertexBuffer = this.vertexBuffer;\n const textureCoordBuffer = this.textureCoordBuffer;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray((program as any).vertexPositionAttribute);\n gl.vertexAttribPointer(\n (program as any).vertexPositionAttribute, (vertexBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);\n gl.enableVertexAttribArray((program as any).textureCoordAttribute);\n gl.vertexAttribPointer(\n (program as any).textureCoordAttribute, (textureCoordBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n }\n\n private _draw() {\n if (this._isVideo && this._keepUpdate) {\n this._updateTexture();\n }\n\n this._renderer.render({\n gl: this.context,\n shaderProgram: this.shaderProgram!,\n indexBuffer: this.indexBuffer!,\n mvMatrix: this.mvMatrix,\n pMatrix: this.pMatrix\n });\n }\n\n private _requestPresent(options) {\n const gl = this.context;\n const canvas = this.canvas;\n const animator = this._animator;\n\n this._vr = WEBXR_SUPPORTED ?\n new XRManager(options) :\n new VRManager();\n\n const vr = this._vr;\n\n animator.stop();\n return new Promise((resolve, reject) => {\n vr.requestPresent(canvas, gl)\n .then(() => {\n vr.addEndCallback(this.exitVR);\n animator.setContext(vr.context);\n animator.setCallback(this._onFirstVRFrame);\n\n if (IS_IOS) {\n this._setWrapperFullscreen();\n }\n\n this._shouldForceDraw = true;\n animator.start();\n\n resolve(\"success\");\n })\n .catch(e => {\n vr.destroy();\n this._vr = null;\n animator.start();\n\n reject(e);\n });\n });\n }\n\n private _onFirstVRFrame = (time, frame) => {\n const vr = this._vr!;\n const gl = this.context;\n const animator = this._animator;\n\n // If rendering is not ready, wait for next frame\n if (!vr.canRender(frame)) return;\n\n const minusZDir = vec3.fromValues(0, 0, -1);\n const eyeParam = vr.getEyeParams(gl, frame)![0];\n // Extract only rotation\n const mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix);\n const pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix);\n\n const mvInv = mat3.invert(mat3.create(), mvMatrix);\n const pInv = mat3.invert(mat3.create(), pMatrix);\n const viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv);\n\n vec3.transformMat3(viewDir, viewDir, mvInv);\n\n const yawOffset = mathUtil.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1));\n\n if (yawOffset === 0) {\n // If the yawOffset is exactly 0, then device sensor is not ready\n // So read it again until it has any value in it\n return;\n }\n\n vr.setYawOffset(yawOffset);\n animator.setCallback(this._renderStereo);\n };\n\n private _setWrapperFullscreen() {\n const wrapper = this._wrapper;\n\n if (!wrapper) return;\n\n this._wrapperOrigStyle = wrapper.getAttribute(\"style\");\n const wrapperStyle = wrapper.style;\n\n wrapperStyle.width = \"100vw\";\n wrapperStyle.height = \"100vh\";\n wrapperStyle.position = \"fixed\";\n wrapperStyle.left = \"0\";\n wrapperStyle.top = \"0\";\n wrapperStyle.zIndex = \"9999\";\n }\n\n private _restoreStyle() {\n const wrapper = this._wrapper;\n const canvas = this.canvas;\n\n if (!wrapper) return;\n\n if (this._wrapperOrigStyle) {\n wrapper.setAttribute(\"style\", this._wrapperOrigStyle);\n } else {\n wrapper.removeAttribute(\"style\");\n }\n\n this._wrapperOrigStyle = null;\n\n // Restore canvas style\n canvas.removeAttribute(\"style\");\n this._setDefaultCanvasStyle();\n }\n}\n\nexport default PanoImageRenderer;\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { VERSION } from \"../version\";\nimport { merge } from \"../utils/utils\";\n\nimport PanoViewer from \"./PanoViewer\";\nimport * as Constants from \"./consts\";\n\nconst PanoViewerModule = {\n PanoViewer,\n VERSION\n};\n\nmerge(PanoViewerModule, Constants);\n\nexport default PanoViewerModule;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Promise from \"promise-polyfill\";\nimport { quat } from \"gl-matrix\";\n\nimport { DeviceMotionEvent, checkXRSupport } from \"../utils/browserFeature\";\nimport YawPitchControl, { YawPitchControlOptions } from \"../YawPitchControl/YawPitchControl\";\nimport PanoImageRenderer from \"../PanoImageRenderer/PanoImageRenderer\";\nimport WebGLUtils from \"../PanoImageRenderer/WebGLUtils\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { CubemapConfig, ValueOf } from \"../types/internal\";\nimport { AnimationEndEvent, ReadyEvent, ViewChangeEvent, ErrorEvent } from \"../types/event\";\n\nimport { ERROR_TYPE, PANOVIEWER_EVENTS as EVENTS, GYRO_MODE, PROJECTION_TYPE, STEREO_FORMAT, DEFAULT_CANVAS_CLASS } from \"./consts\";\n\nexport interface PanoViewerOptions {\n image: string | HTMLElement;\n video: string | HTMLElement;\n projectionType: ValueOf;\n cubemapConfig: Partial;\n stereoFormat: ValueOf;\n width: number;\n height: number;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n touchDirection: ValueOf;\n canvasClass: string;\n}\n\nexport interface PanoViewerEvent {\n ready: ReadyEvent;\n viewChange: ViewChangeEvent;\n animationEnd: AnimationEndEvent;\n error: ErrorEvent;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * PanoViewer\n */\nclass PanoViewer extends Component {\n /**\n * Check whether the current environment can execute PanoViewer\n * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다.\n * @return PanoViewer executable PanoViewer 실행가능 여부\n */\n public static isSupported(): boolean {\n return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL();\n }\n\n /**\n * Check whether the current environment supports the WebGL\n * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다.\n * @return WebGL support WebGL 지원여부\n */\n public static isWebGLAvailable(): boolean {\n return WebGLUtils.isWebGLAvailable();\n }\n\n /**\n * Check whether the current environment supports the gyro sensor.\n * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다.\n * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수\n */\n public static isGyroSensorAvailable(callback: (isAvailable: boolean) => any) {\n if (!DeviceMotionEvent && callback) {\n callback(false);\n return;\n }\n\n let onDeviceMotionChange;\n\n const checkGyro = () => new Promise(res => {\n onDeviceMotionChange = deviceMotion => {\n const isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null);\n\n res(isGyroSensorAvailable);\n };\n\n window.addEventListener(\"devicemotion\", onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n Promise.race([checkGyro(), timeout()]).then((isGyroSensorAvailable: boolean) => {\n window.removeEventListener(\"devicemotion\", onDeviceMotionChange);\n\n if (callback) {\n callback(isGyroSensorAvailable);\n }\n\n PanoViewer.isGyroSensorAvailable = fb => {\n if (fb) {\n fb(isGyroSensorAvailable);\n }\n return isGyroSensorAvailable;\n };\n });\n }\n\n private static _isValidTouchDirection(direction) {\n return direction === PanoViewer.TOUCH_DIRECTION.NONE ||\n direction === PanoViewer.TOUCH_DIRECTION.YAW ||\n direction === PanoViewer.TOUCH_DIRECTION.PITCH ||\n direction === PanoViewer.TOUCH_DIRECTION.ALL;\n }\n\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @name VERSION\n * @static\n * @type {String}\n * @example\n * eg.view360.PanoViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.PanoViewer\n */\n public static VERSION = VERSION;\n public static ERROR_TYPE = ERROR_TYPE;\n public static EVENTS = EVENTS;\n public static PROJECTION_TYPE = PROJECTION_TYPE;\n public static GYRO_MODE = GYRO_MODE;\n // This should be deprecated!\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static ProjectionType = PROJECTION_TYPE;\n public static STEREO_FORMAT = STEREO_FORMAT;\n\n /**\n * Constant value for touch directions\n * @ko 터치 방향에 대한 상수 값.\n * @namespace\n * @name TOUCH_DIRECTION\n */\n public static TOUCH_DIRECTION = {\n /**\n * Constant value for none direction.\n * @ko none 방향에 대한 상수 값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 1\n */\n NONE: YawPitchControl.TOUCH_DIRECTION_NONE,\n /**\n * Constant value for horizontal(yaw) direction.\n * @ko horizontal(yaw) 방향에 대한 상수 값.\n * @name YAW\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 6\n */\n YAW: YawPitchControl.TOUCH_DIRECTION_YAW,\n /**\n * Constant value for vertical direction.\n * @ko vertical(pitch) 방향에 대한 상수 값.\n * @name PITCH\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 24\n */\n PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH,\n /**\n * Constant value for all direction.\n * @ko all 방향에 대한 상수 값.\n * @name ALL\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 30\n */\n ALL: YawPitchControl.TOUCH_DIRECTION_ALL\n };\n\n private _container: HTMLElement;\n // Options\n private _image: ConstructorParameters[0];\n private _isVideo: boolean;\n private _projectionType: ValueOf;\n private _cubemapConfig: Partial;\n private _stereoFormat: ValueOf;\n private _width: number;\n private _height: number;\n private _yaw: number;\n private _pitch: number;\n private _fov: number;\n private _gyroMode: ValueOf;\n private _quaternion: quat | null;\n private _aspectRatio: number;\n private _isReady: boolean;\n private _canvasClass: string;\n\n // Internal Values\n private _photoSphereRenderer: PanoImageRenderer | null;\n private _yawPitchControl: YawPitchControl | null;\n\n /**\n * @classdesc 360 media viewer\n * @ko 360 미디어 뷰어\n *\n * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트\n * @param options\n *\n * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
\n * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다.\n * @param {Object} [options.cubemapConfig.order = \"RLUDBF\"(ProjectionType === CUBEMAP) | \"RLUDFB\" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서\n * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다.\n * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다.\n * @param {String} [options.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
\n * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위)\n * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위)\n * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위)\n * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위)\n * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위)\n * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다\n * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다.\n * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키\n * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE}
\n * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위\n * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위\n * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위\n * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
\n * @param {String} [options.canvasClass=\"view360-canvas\"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n *\n * @example\n * ```\n * // PanoViewer Creation\n * // create PanoViewer with option\n * var PanoViewer = eg.view360.PanoViewer;\n * // Area where the image will be displayed(HTMLElement)\n * var container = document.getElementById(\"myPanoViewer\");\n *\n * var panoViewer = new PanoViewer(container, {\n * // If projectionType is not specified, the default is \"equirectangular\".\n * // Specifies an image of the \"equirectangular\" type.\n * image: \"/path/to/image/image.jpg\"\n * });\n * ```\n *\n * @example\n * ```\n * // Cubemap Config Setting Example\n * // For support Youtube EAC projection, You should set cubemapConfig as follows.\n * cubemapConfig: {\n * order: \"LFRDBU\",\n * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}]\n * }\n * ```\n */\n public constructor(container: HTMLElement, options: Partial = {}) {\n super();\n\n // Raises the error event if webgl is not supported.\n if (!WebGLUtils.isWebGLAvailable()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n }, 0);\n return this;\n }\n\n if (!WebGLUtils.isStableWebGL()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_DEVICE,\n message: \"blacklisted browser\"\n }));\n }, 0);\n\n return this;\n }\n\n if (!!options.image && !!options.video) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_RESOURCE,\n message: \"Specifying multi resouces(both image and video) is not valid.\"\n }));\n }, 0);\n return this;\n }\n\n // Check XR support at not when imported, but when created.\n // This is intended to make polyfills easier to use.\n checkXRSupport();\n\n this._container = container;\n this._image = options.image! as HTMLImageElement || options.video! as HTMLVideoElement;\n this._isVideo = !!options.video;\n this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/\n order: this._projectionType === PROJECTION_TYPE.CUBEMAP ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...options.cubemapConfig\n };\n this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n\n // If the width and height are not provided, will use the size of the container.\n this._width = options.width || parseInt(window.getComputedStyle(container).width, 10);\n this._height = options.height || parseInt(window.getComputedStyle(container).height, 10);\n\n /**\n * Cache the direction for the performance in renderLoop\n *\n * This value should be updated by \"change\" event of YawPitchControl.\n */\n this._yaw = options.yaw || 0;\n this._pitch = options.pitch || 0;\n this._fov = options.fov || 65;\n\n this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH;\n this._quaternion = null;\n\n this._aspectRatio = this._height !== 0 ? this._width / this._height : 1;\n\n this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS;\n\n const fovRange = options.fovRange || [30, 110];\n const touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ?\n options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL;\n const yawPitchConfig = {\n ...options,\n ...{\n element: container,\n yaw: this._yaw,\n pitch: this._pitch,\n fov: this._fov,\n gyroMode: this._gyroMode,\n fovRange,\n aspectRatio: this._aspectRatio,\n touchDirection\n }\n };\n\n this._isReady = false;\n\n this._initYawPitchControl(yawPitchConfig);\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n /**\n * Get the video element that the viewer is currently playing. You can use this for playback.\n * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다.\n * @return HTMLVideoElementHTMLVideoElement\n * @example\n * ```\n * var videoTag = panoViewer.getVideo();\n * videoTag.play(); // play the video!\n * ```\n */\n public getVideo() {\n if (!this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent() as HTMLVideoElement;\n }\n\n /**\n * Set the video information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정)\n * @param {object} param\n * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}(\"equirectangular\")] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setVideo(\"/path/to/video/video.mp4\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR\n * });\n * ```\n */\n public setVideo(video: string | HTMLElement | { type: string; src: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n }> = {}) {\n if (video) {\n this.setImage(video, {\n projectionType: param.projectionType,\n isVideo: true,\n cubemapConfig: param.cubemapConfig,\n stereoFormat: param.stereoFormat\n });\n }\n\n return this;\n }\n\n /**\n * Get the image information that the viewer is currently using.\n * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다.\n * @return Image Object이미지 객체\n * @example\n * var imageObj = panoViewer.getImage();\n */\n public getImage() {\n if (this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent();\n }\n\n /**\n * Set the image information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.)\n * @param {object} param Additional information이미지 추가 정보\n * @param {string} [param.projectionType=\"equirectangular\"] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setImage(\"/path/to/image/image.png\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP\n * });\n * ```\n */\n public setImage(image: string | HTMLElement | { src: string; type: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n isVideo: boolean;\n }> = {}) {\n const cubemapConfig = {\n ...{\n order: \"RLUDBF\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...param.cubemapConfig\n };\n const stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n const isVideo = !!(param.isVideo);\n\n if (this._image && this._isVideo !== isVideo) {\n /* eslint-disable no-console */\n console.warn(\"PanoViewer is not currently supporting content type changes. (Image <--> Video)\");\n /* eslint-enable no-console */\n return this;\n }\n\n if (image) {\n this._deactivate();\n\n this._image = image as HTMLImageElement;\n this._isVideo = isVideo;\n this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = cubemapConfig;\n this._stereoFormat = stereoFormat;\n\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n return this;\n }\n\n /**\n * Set whether the renderer always updates the texture and renders.\n * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다.\n * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public keepUpdate(doUpdate: boolean) {\n this._photoSphereRenderer!.keepUpdate(doUpdate);\n return this;\n }\n\n /**\n * Get the current projection type (equirectangular/cube)\n * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다.\n * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE}\n */\n public getProjectionType() {\n return this._projectionType;\n }\n\n /**\n * Activate the device's motion sensor, and return the Promise whether the sensor is enabled\n * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element.\n * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다.\n * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다.\n */\n public enableSensor() {\n return new Promise((resolve, reject) => {\n if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\") {\n DeviceMotionEvent.requestPermission().then(permissionState => {\n if (permissionState === \"granted\") {\n resolve();\n } else {\n reject(new Error(\"permission denied\"));\n }\n }).catch(e => {\n // This can happen when this method wasn't triggered by user interaction\n reject(e);\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Disable the device's motion sensor.\n * @ko 디바이스의 모션 센서를 비활성화합니다.\n * @deprecated\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public disableSensor() {\n return this;\n }\n\n /**\n * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred).\n * This method must be used in the context of user interaction, like onclick callback on the button element.\n * It can be rejected when an enabling device sensor fails or image/video is still loading(\"ready\" event not triggered).\n * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다)\n * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우(\"ready\"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다.\n * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요.\n * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error)\n */\n public enterVR(options: {\n requiredFeatures?: any[];\n optionalFeatures?: any[];\n [key: string]: any;\n } = {}): globalThis.Promise {\n if (!this._isReady) {\n return Promise.reject(new Error(\"PanoViewer is not ready to show image.\")) as any;\n }\n\n return new Promise((resolve, reject) => {\n this.enableSensor()\n .then(() => this._photoSphereRenderer!.enterVR(options))\n .then((res: string) => resolve(res))\n .catch(e => reject(e));\n }) as any;\n }\n\n /**\n * Exit VR stereo rendering mode.\n * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public exitVR() {\n this._photoSphereRenderer!.exitVR();\n return this;\n }\n\n /**\n * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}.\n * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다.\n * @param useZoom\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseZoom(useZoom: boolean): this {\n if (typeof useZoom === \"boolean\") {\n this._yawPitchControl!.option(\"useZoom\", useZoom);\n }\n\n return this;\n }\n\n /**\n * When true, enables the keyboard move key control: awsd, arrow keys\n * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키)\n * @param useKeyboard\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseKeyboard(useKeyboard: boolean): this {\n this._yawPitchControl!.option(\"useKeyboard\", useKeyboard);\n return this;\n }\n\n /**\n * Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")\n * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")\n * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE}\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setGyroMode(\"yawPitch\");\n * //equivalent\n * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH);\n * ```\n */\n public setGyroMode(gyroMode: PanoViewer[\"_gyroMode\"]) {\n this._yawPitchControl!.option(\"gyroMode\", gyroMode);\n return this;\n }\n\n /**\n * Set the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 설정합니다.\n * @param range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setFovRange([50, 90]);\n */\n public setFovRange(range: number[]) {\n this._yawPitchControl!.option(\"fovRange\", range);\n return this;\n }\n\n /**\n * Get the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 반환합니다.\n * @return FOV range\n * @example\n * var range = panoViewer.getFovRange(); // [50, 90]\n */\n public getFovRange(): [number, number] {\n return this._yawPitchControl!.option(\"fovRange\") as [number, number];\n }\n\n /**\n * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size.\n * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다.\n * @param {object} [size]\n * @param {number} [size.width=width of the container]\n * @param {number} [size.height=height of the container]\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public updateViewportDimensions(size: Partial<{\n width: number;\n height: number;\n }> = {}): this {\n if (!this._isReady) {\n return this;\n }\n\n let containerSize;\n\n if (size.width === undefined || size.height === undefined) {\n containerSize = window.getComputedStyle(this._container);\n }\n\n const width = size.width || parseInt(containerSize.width, 10);\n const height = size.height || parseInt(containerSize.height, 10);\n\n // Skip if viewport is not changed.\n if (width === this._width && height === this._height) {\n return this;\n }\n\n this._width = width;\n this._height = height;\n\n this._aspectRatio = width / height;\n this._photoSphereRenderer!.updateViewportDimensions(width, height);\n this._yawPitchControl!.option(\"aspectRatio\", this._aspectRatio);\n this._yawPitchControl!.updatePanScale({height});\n\n this.lookAt({}, 0);\n return this;\n }\n\n /**\n * Get the current field of view(FOV)\n * @ko 현재 field of view(FOV) 값을 반환합니다.\n */\n public getFov(): number {\n return this._fov;\n }\n\n /**\n * Get current yaw value\n * @ko 현재 yaw 값을 반환합니다.\n */\n public getYaw() {\n return this._yaw;\n }\n\n /**\n * Get current pitch value\n * @ko 현재 pitch 값을 반환합니다.\n */\n public getPitch() {\n return this._pitch;\n }\n\n /**\n * Get the range of controllable Yaw values\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n */\n public getYawRange(): [number, number] {\n return this._yawPitchControl!.option(\"yawRange\") as [number, number];\n }\n\n /**\n * Get the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다.\n */\n public getPitchRange(): [number, number] {\n return this._yawPitchControl!.option(\"pitchRange\") as [number, number];\n }\n\n /**\n * Set the range of controllable yaw\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setYawRange([-90, 90]);\n */\n public setYawRange(yawRange: number[]) {\n this._yawPitchControl!.option(\"yawRange\", yawRange);\n return this;\n }\n\n /**\n * Set the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 설정합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setPitchRange([-40, 40]);\n */\n public setPitchRange(pitchRange: number[]) {\n this._yawPitchControl!.option(\"pitchRange\", pitchRange);\n return this;\n }\n\n /**\n * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed.\n * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다.\n * @param showPolePoint\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setShowPolePoint(showPolePoint: boolean) {\n this._yawPitchControl!.option(\"showPolePoint\", showPolePoint);\n return this;\n }\n\n /**\n * Set a new view by setting camera configuration. Any parameters not specified remain the same.\n * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다.\n * @param {object} orientation\n * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위)\n * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위)\n * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위)\n * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초)\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * // Change the yaw angle (absolute angle) to 30 degrees for one second.\n * panoViewer.lookAt({yaw: 30}, 1000);\n * ```\n */\n public lookAt(orientation: Partial<{\n yaw: number;\n pitch: number;\n fov: number;\n }>, duration: number = 0) {\n if (!this._isReady) {\n return this;\n }\n\n const yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw;\n const pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch;\n const pitchRange = this._yawPitchControl!.option(\"pitchRange\");\n const verticalAngleOfImage = pitchRange[1] - pitchRange[0];\n let fov = orientation.fov !== undefined ? orientation.fov : this._fov;\n\n if (verticalAngleOfImage < fov) {\n fov = verticalAngleOfImage;\n }\n\n this._yawPitchControl!.lookAt({yaw, pitch, fov}, duration);\n\n if (duration === 0) {\n this._photoSphereRenderer!.renderWithYawPitch(yaw, pitch, fov);\n }\n return this;\n }\n\n /**\n * Set touch direction by which user can control.\n * @ko 사용자가 조작가능한 터치 방향을 지정합니다.\n * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @return PanoViewer instance\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Limit the touch direction to the yaw direction only.\n * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW);\n * ```\n */\n public setTouchDirection(direction: number): this {\n if (PanoViewer._isValidTouchDirection(direction)) {\n this._yawPitchControl!.option(\"touchDirection\", direction);\n }\n\n return this;\n }\n\n /**\n * Returns touch direction by which user can control\n * @ko 사용자가 조작가능한 터치 방향을 반환한다.\n * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Returns the current touch direction.\n * var dir = panoViewer.getTouchDirection();\n * ```\n */\n public getTouchDirection(): number {\n return this._yawPitchControl!.option(\"touchDirection\") ;\n }\n\n /**\n * Destroy viewer. Remove all registered event listeners and remove viewer canvas.\n * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public destroy(): this {\n this._deactivate();\n\n if (this._yawPitchControl) {\n this._yawPitchControl.destroy();\n this._yawPitchControl = null;\n }\n\n return this;\n }\n\n // TODO: Remove parameters as they're just using private values\n private _initRenderer(\n yaw: number,\n pitch: number,\n fov: number,\n projectionType: PanoViewer[\"_projectionType\"],\n cubemapConfig: PanoViewer[\"_cubemapConfig\"]\n ) {\n this._photoSphereRenderer = new PanoImageRenderer(\n this._image,\n this._width,\n this._height,\n this._isVideo,\n this._container,\n this._canvasClass,\n {\n initialYaw: yaw,\n initialPitch: pitch,\n fieldOfView: fov,\n imageType: projectionType,\n cubemapConfig,\n stereoFormat: this._stereoFormat\n },\n );\n this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl!);\n\n this._bindRendererHandler();\n\n this._photoSphereRenderer\n .bindTexture()\n .then(() => this._activate())\n .catch(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_BIND_TEXTURE,\n message: \"failed to bind texture\"\n }));\n });\n }\n\n /**\n * @private\n * update values of YawPitchControl if needed.\n * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image.\n *\n * This function should be called after isReady status is true.\n */\n private _updateYawPitchIfNeeded() {\n if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) {\n // update fov by aspect ratio\n const image = this._photoSphereRenderer!.getContent()! as HTMLImageElement;\n let imageAspectRatio = image.naturalWidth / image.naturalHeight;\n let yawSize;\n let maxFov;\n\n // If height is larger than width, then we assume it's rotated by 90 degree.\n if (imageAspectRatio < 1) {\n // So inverse the aspect ratio.\n imageAspectRatio = 1 / imageAspectRatio;\n }\n\n if (imageAspectRatio < 6) {\n yawSize = mathUtil.toDegree(imageAspectRatio);\n // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5\n maxFov = mathUtil.toDegree(Math.atan(0.5)) * 2;\n } else {\n yawSize = 360;\n maxFov = (360 / imageAspectRatio); // Make it 5 fixed as axes does.\n }\n\n // console.log(\"_updateYawPitchIfNeeded\", maxFov, \"aspectRatio\", image.naturalWidth, image.naturalHeight, \"yawSize\", yawSize);\n const minFov = (this._yawPitchControl!.option(\"fovRange\"))[0];\n\n // this option should be called after fov is set.\n this._yawPitchControl!.option({\n \"fov\": maxFov, /* parameter for internal validation for pitchrange */\n \"yawRange\": [-yawSize / 2, yawSize / 2],\n \"pitchRange\": [-maxFov / 2, maxFov / 2],\n \"fovRange\": [minFov, maxFov]\n });\n this.lookAt({fov: maxFov});\n }\n }\n\n private\t_bindRendererHandler() {\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, e));\n });\n\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, () => {\n this._deactivate();\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERING_CONTEXT_LOST,\n message: \"webgl rendering context lost\"\n }));\n });\n }\n\n private _initYawPitchControl(yawPitchConfig: Partial) {\n this._yawPitchControl = new YawPitchControl(yawPitchConfig);\n\n this._yawPitchControl.on(EVENTS.ANIMATION_END, e => {\n this.trigger(new ComponentEvent(EVENTS.ANIMATION_END, e));\n });\n\n this._yawPitchControl.on(\"change\", e => {\n this._yaw = e.yaw;\n this._pitch = e.pitch;\n this._fov = e.fov;\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(EVENTS.VIEW_CHANGE, {\n yaw: e.yaw,\n pitch: e.pitch,\n fov: e.fov,\n quaternion: e.quaternion,\n isTrusted: e.isTrusted\n }));\n });\n }\n\n private _activate() {\n this._photoSphereRenderer!.attachTo(this._container);\n this._yawPitchControl!.enable();\n\n this.updateViewportDimensions();\n\n this._isReady = true;\n\n // update yawPitchControl after isReady status is true.\n this._updateYawPitchIfNeeded();\n\n this.trigger(new ComponentEvent(EVENTS.READY));\n this._photoSphereRenderer!.startRender();\n }\n\n /**\n * Destroy webgl context and block user interaction and stop rendering\n */\n private _deactivate() {\n // Turn off the video if it has one\n const video = this.getVideo();\n if (video) {\n video.pause();\n }\n\n if (this._isReady) {\n this._photoSphereRenderer!.stopRender();\n this._yawPitchControl!.disable();\n this._isReady = false;\n }\n\n if (this._photoSphereRenderer) {\n this._photoSphereRenderer.destroy();\n this._photoSphereRenderer = null;\n }\n }\n}\n\nexport default PanoViewer;\n\n"],"names":["VERSION","merge","target","_i","srcs","forEach","source","Object","keys","key","value","Array","isArray","appendSourceElement","video","videoUrl","videoSrc","videoType","src","type","sourceElement","document","createElement","appendChild","win","window","Math","self","Function","doc","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","IS_IOS","IS_SAFARI_ON_DESKTOP","Float32Array","getComputedStyle","userAgent","SUPPORT_TOUCH","SUPPORT_DEVICEMOTION","DeviceMotionEvent","devicePixelRatio","WEBXR_SUPPORTED","docStyle","documentElement","style","i","len","length","CSS","supports","checkXRSupport","xr","isSessionSupported","then","res","catch","supportsSession","toDegree","a","PI","util","n","extractPitchFromQuat","quaternion","baseV","vec3","atan2","sqrt","pow","hypot","x","y","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","angleBetweenVec2","v1","v2","det","yawOffsetBetween","viewDir","targetDir","viewDirXZ","vec2","targetDirXZ","sign","Number","getRotationDelta","prevQ","curQ","rotateKind","prevQuaternion","quat","curQuaternion","prevPoint","curPoint","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","distance","abs","projectedPrevPoint","trigonometricRatio","theta","acos","crossVec","thetaDirection","version","branch","build","match","exec","parseInt","r","CHROME_VERSION","IS_CHROME_WITHOUT_DEVICE_MOTION","IS_ANDROID","test","MC_BIND_SCALE","GYRO_MODE","NONE","YAWPITCH","VR","MathUtil","degToRad","radToDeg","Vector2","prototype","constructor","set","this","copy","v","subVectors","b","Vector3","z","normalize","scalar","invScalar","multiplyScalar","applyQuaternion","q","qx","qy","qz","qw","w","ix","iy","iz","iw","dot","crossVectors","ax","ay","az","bx","by","bz","Quaternion","undefined","setFromEulerXYZ","c1","cos","c2","c3","s1","sin","s2","s3","setFromEulerYXZ","setFromAxisAngle","axis","angle","halfAngle","s","multiply","multiplyQuaternions","qax","qay","qaz","qaw","qbx","qby","qbz","qbw","inverse","l","slerp","qb","t","cosHalfTheta","halfTheta","sinHalfTheta","ratioA","ratioB","setFromUnitVectors","vFrom","vTo","isIOS","isWebViewAndroid","isSafari","isFirefoxAndroid","isR7","piOver180","rad45","defaultOrientation","defaultPosition","Util","updateEyeMatrices","projection","view","pose","parameters","vrDisplay","out","fov","fieldOfView","near","depthNear","far","depthFar","upTan","tan","upDegrees","downTan","downDegrees","leftTan","leftDegrees","rightTan","rightDegrees","xScale","yScale","a00","a01","a03","a10","a11","a12","a13","a20","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b07","b08","b09","b10","b11","orientation","position","xx","x2","xy","y2","xz","z2","yy","yz","zz","wx","wy","wz","offset","a02","a21","b06","MIN_TIMESTEP","MAX_TIMESTEP","base64","mimeType","clamp","min","max","lerp","platform","indexOf","isLandscapeMode","rtn","isTimestampDeltaValid","timestampDeltaS","isNaN","getScreenWidth","screen","width","height","getScreenHeight","requestFullscreen","element","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","exitFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","getFullscreenElement","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","linkProgram","gl","vertexSource","fragmentSource","attribLocationMap","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","attribName","program","createProgram","attachShader","bindAttribLocation","deleteShader","getProgramUniforms","uniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","uniformName","getActiveUniform","replace","getUniformLocation","orthoMatrix","left","right","bottom","top","lr","bt","nf","copyArray","dest","isMobile","check","vendor","opera","substr","extend","hasOwnProperty","safariCssSizeWorkaround","canvas","width_1","height_1","setTimeout","isDebug","getQueryParameter","results","RegExp","location","search","decodeURIComponent","frameDataFromPose","frameData","timestamp","leftProjectionMatrix","leftViewMatrix","getEyeParameters","rightProjectionMatrix","rightViewMatrix","isInsideCrossDomainIFrame","isFramed","refDomain","getDomainFromUrl","referrer","thisDomain","href","url","domain","split","predictionTimeS","previousQ","previousTimestampS","deltaQ","outQ","currentQ","gyro","timestampS","angularSpeed","console","log","toFixed","predictAngle","_super","_this","_onDeviceMotion","bind","_onDeviceOrientation","_onChromeWithoutDeviceMotion","isWithoutDeviceMotion","isAndroid","stillGyroVec","rawGyroVec","adjustedGyroVec","_timer","lastDevicemotionTimestamp","_isEnabled","enable","__extends","addEventListener","removeEventListener","e","alpha","beta","gamma","trigger","ComponentEvent","inputEvent","deviceorientation","clearTimeout","Date","getTime","devicemotionEvent","isGyroSensorAvailable","rotationRate","isGravitySensorAvailable","accelerationIncludingGravity","interval","__assign","timeStamp","acceleration","adjustedRotationRate","Component","sample","sensorSample","kFilter","vector","currentGyroMeasurement","deltaT","previousGyroMeasurement","run_","currentAccelMeasurement","SensorSample","filterQ","previousFilterQ","accelQ","isOrientationInitialized","estimatedGravity","measuredGravity","gyroIntegralQ","accelToQuaternion_","gyroDeltaQ","gyroToQuaternionDelta_","invFilterQ","getQuaternionAngle","targetQ","accel","normAccel","dt","ComplementaryFilter","isFilterQuaternionInitialized","getOrientation","deviceMotion","DeviceMotion","accelerometer","gyroscope","_onDeviceMotionChange","_onScreenOrientationChange","filter","posePredictor","PosePredictor","filterToWorldQ","isChromeUsingDegrees","inverseWorldToScreenQ","worldToScreenQ","originalPoseAdjustQ","_setScreenTransform","resetQ","on","isEnabled","disable","_deviceOrientationQ","deviceOrientationFixQ","_alpha","outQuat","_convertFusionToPredicted","_prevOrientation","predictedQ","getPrediction","_a","accGravity","rotRate","_triggerChange","addAccelMeasurement","addGyroMeasurement","el","options","_prevQuaternion","_quaternion","fusionPoseSensor","scale","threshold","_onPoseChange","axes","observer","FusionPoseSensor","_attachEvent","_dettachEvent","destroy","disconnect","event","prvQ","change","yawDeltaByYaw","reduce","acc","off","screenRotationAngleInst","refCount","_onOrientationChange","_spinR","_screenOrientationAngle","glMatrix","betaR","gammaR","_useRotation","_screenRotationAngle","setUseRotation","useRotation","_userDirection","Axes","DIRECTION_ALL","unref","ScreenRotationAngle","_direction","DIRECTION_HORIZONTAL","connect","properties","useDirection","_getOffset","newOffset","getRadian","cosTheta","sinTheta","DIRECTION_VERTICAL","PanInput","Y_AXIS_VECTOR","_fusionPoseSensor","isTrusted","yaw","yawQ","conj","DEFAULT_YAW_RANGE","DEFAULT_PITCH_RANGE","CIRCULAR_PITCH_RANGE","opt","pitch","showPolePoint","useZoom","useKeyboard","gyroMode","touchDirection","TOUCH_DIRECTION_YAW","yawRange","pitchRange","fovRange","aspectRatio","_element","_initialFov","_enabled","_isAnimating","_deviceQuaternion","_initAxes","option","param","_axes","get","areaHeight","_axesPanInput","deceleration","newValue","_getOptions","newOptions","changedKeyList","push","_setOptions","_getValidatedOptions","_applyOptions","updatePanScale","persistOrientation","_resetOrientation","duration","pos","p","f","maximumDuration","Infinity","setBy","yawPitch","getCombinedQuaternion","_axesWheelInput","_axesTiltMotionInput","_axesPinchInput","_axesMoveKeyInput","yRange","_updateYawRange","pRange","_updatePitchRange","RotationPanInput","WheelInput","PinchInput","MoveKeyInput","range","circular","_isCircular","bounce","hold","evt","delta","_updateControlScale","release","animationEnd","_getValidYawRange","_getValidPitchRange","arguments","prevFov","nextFov","isVR","isYawPitch","some","setTo","_initDeviceQuaternion","TiltMotionInput","_togglePinchInputByOption","_enableTouch","_inputs","direction","yawEnabled","pitchEnabled","DeviceQuaternion","newYawRange","newFov","newAspectRatio","ratio","_adjustAspectRatio","horizontalFov","newPitchRange","changeEvt","verticalAngle","halfFov","concat","halfHorizontalFov","mathUtil","targetElement","input","inputRange","outputRange","rangeIdx","inputA","inputB","outputA","outputB","_lerp","fraction","YawPitchControl","ERROR_TYPE","INVALID_DEVICE","NO_WEBGL","FAIL_IMAGE_LOAD","FAIL_BIND_TEXTURE","INVALID_RESOURCE","RENDERING_CONTEXT_LOST","PANOVIEWER_EVENTS","READY","VIEW_CHANGE","ANIMATION_END","ERROR","PROJECTION_TYPE","EQUIRECTANGULAR","CUBEMAP","CUBESTRIP","PANORAMA","STEREOSCOPIC_EQUI","STEREO_FORMAT","TOP_BOTTOM","LEFT_RIGHT","DEFAULT_CANVAS_CLASS","image","projectionType","cubemapConfig","stereoFormat","canvasClass","WEBGL_ERROR_CODE","webglAvailability","WebGLUtils","shader","getShaderParameter","COMPILE_STATUS","error","getShaderInfoLog","LINK_STATUS","deleteProgram","data","itemSize","attr","buffer","createBuffer","bindBuffer","bufferData","STATIC_DRAW","numItems","enableVertexAttribArray","vertexAttribPointer","FLOAT","userContextAttributes","context","contextAttributes","preserveDrawingBuffer","antialias","onWebglcontextcreationerror","statusMessage","webglIdentifiers_1","__values","identifier","getContext","textureTarget","texture","createTexture","bindTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","loseContextExtension","webglContext","getWebglContext","getExtension","loseContext","agentInfo","isStableWebgl","parseFloat","code","pixels","texImage2D","RGBA","UNSIGNED_BYTE","getParameter","MAX_TEXTURE_SIZE","isIE11","majorVersion","EVENTS","_forceDimension","_pixelCanvas","_pixelContext","shaderProgram","indexBuffer","mvMatrix","pMatrix","uniformMatrix4fv","pMatrixUniform","mvMatrixUniform","drawElements","TRIANGLES","UNSIGNED_SHORT","pixelSource","naturalWidth","videoWidth","naturalHeight","videoHeight","forceDimension","HTMLVideoElement","getDimension","contentDimension","textureDimension","drawImage","imageConfig","tileConfig","map","config","flipHorizontal","rotation","message","Renderer","CubeRenderer","order","_VERTEX_POSITION_DATA","_INDEX_DATA","indexData","vertexPositionData","getVertexPositionData","extractOrder","base","_extractTileConfig","trim","face","floor","ordermap","shift","unshift","pop","tileVertex","slice","elemSize","tileTemp","j","splice","coord","_shrinkCoord","faceCoords","val","coords","orderMap","surfaceIdx","tileIdx","TEXTURE_CUBE_MAP_POSITIVE_X","maxCubeMapTextureSize","getMaxCubeMapTextureSize","tile","extractTileFromImage","_triggerError","TEXTURE_CUBE_MAP","updateTexture","inputTextureSize","outputTextureSize","getSourceTileSize","tilePerRow","MAX_CUBE_MAP_TEXTURE_SIZE","imageWidth","isPowerOfTwo","coordData","SHRINK_MULTIPLIER","axisMultipliers","axisIndex","axisDir","notSameDir","_vertices","textureSize","rows","c","tileConfigs","_transformCoord","index","TEXTURE_2D","_getPixelSource","size","maxSize","getMaxTextureSize","_initPixelSource","activeTexture","TEXTURE0","pixelStorei","UNPACK_FLIP_Y_WEBGL","newCoord","_flipHorizontalCoord","_rotateCoord","SHRINK_Y","SHRINK_X","rotationAngle","moved","shiftCount","ANGLE_CORRECTION_FOR_CENTER_ALIGN","textureCoordData","latIdx","lngIdx","phi","sinPhi","u","format","_stereoFormat","ctx","leftEyeScaleOffset","rightEyeScaleOffset","uTexScaleOffset","uniform4fv","render","SphereRenderer","_TEXTURE_COORD_DATA","CylinderRenderer","resizeDimension","rotated","cylinderMaxRadian","_b","imageAspectRatio","halfCylinderY","CYLIDER_Y","startAngleForCenterAlign","yIdx","yLength","VR_DISPLAY_PRESENT_CHANGE","DEFAULT_LEFT_BOUNDS","DEFAULT_RIGHT_BOUNDS","EYES","_vrDisplay","removeEndCallback","isPresenting","exitPresent","_clear","_frameData","VRFrameData","Boolean","bindFramebuffer","FRAMEBUFFER","submitFrame","display","halfWidth","drawingBufferWidth","drawingBufferHeight","getFrameData","leftMVMatrix","rightMVMatrix","mat4","_yawOffset","viewport","callback","getVRDisplays","displays","capabilities","canPresent","requestPresent","leftEye","rightEye","renderWidth","renderHeight","_setDisplay","Promise","reject","Error","layers","getLayers","layer","_leftBounds","leftBounds","_rightBounds","rightBounds","addEndCallback","xrSession","_xrSession","end","_options","frame","getViewerPose","_xrRefSpace","baseLayer","session","renderState","framebuffer","glLayer","views","getViewport","transform","matrix","projectionMatrix","_presenting","requiredFeatures","attributes","getContextAttributes","xrCompatible","makeXRCompatible","requestSession","xrLayer","XRWebGLLayer","updateRenderState","requestReferenceSpace","refSpace","_setSession","_xrLayer","args","_callback","_rafId","_context","requestAnimationFrame","_onLoop","before","performance","now","diff","_rafTimer","_onLoopNextTick","cancelAnimationFrame","ImageType","DEVICE_PIXEL_RATIO","BIND_TEXTURE","IMAGE_LOADED","RENDERING_CONTEXT_RESTORE","RENDERER_ERROR","isVideo","container","sphericalConfig","renderingContextAttributes","vr","_vr","animator","_animator","exitVR","_restoreStyle","updateViewportDimensions","_updateViewport","_bindBuffers","_shouldForceDraw","stop","setContext","setCallback","_render","start","time","eyeParams","getEyeParams","beforeRender","eyeIndex","eyeParam","uniform1f","uEye","_draw","afterRender","minusZDir","canRender","mat3","mvInv","pInv","yawOffset","setYawOffset","_renderStereo","_lastQuaternion","_lastYaw","_lastPitch","_lastFieldOfView","textureCoordBuffer","vertexBuffer","_initCanvas","_setDefaultCanvasStyle","_wrapper","_wrapperOrigStyle","_renderingContextAttributes","_image","_imageConfig","_imageIsReady","_keepUpdate","_onContentLoad","_onContentError","WebGLAnimator","setImage","imageType","yawPitchControl","_yawPitchControl","_isVideo","_setImageType","_contentLoader","ImReady","videoCandidate","video_1","setAttribute","querySelectorAll","readyState","load","toVideoElement","parsedImages","img","imgEl","Image","crossOrigin","toImageElement","rej","contentLoader","isReady","_bindTexture","once","errorCount","parentElement","_hasExternalCanvas","detach","hasRenderingContext","removeChild","forceContextLoss","_onWebglcontextlost","_onWebglcontextrestored","isContextLost","viewPortChanged","h","doUpdate","isImageLoaded","updateFieldOfView","_renderer","resolve","_requestPresent","_imageType","_isCubeMap","CubeStripRenderer","_initWebGL","canvasInContainer","querySelector","_createCanvas","className","margin","maxHeight","maxWidth","outline","content","_triggerContentLoad","renderer","vsSource","getVertexShaderSource","fsSource","getFragmentShaderSource","getErrorNameFromWebGLErrorCode","getError","useProgram","vertexPositionAttribute","getAttribLocation","samplerUniform","textureCoordAttribute","clear","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","STENCIL_BUFFER_BIT","uniform1i","preventDefault","_initRenderingContext","_initShaderProgram","clearColor","deleteTexture","CULL_FACE","WebGLRenderingContext","getIndexData","getTextureCoordData","initBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","Uint16Array","isEAC","updateShaderData","_initBuffers","getFov","shouldRenderWithQuaternion","getQuaternion","renderWithQuaternion","getYawPitch","renderWithYawPitch","_updateTexture","XRManager","VRManager","_onFirstVRFrame","_setWrapperFullscreen","wrapper","getAttribute","wrapperStyle","zIndex","removeAttribute","PanoImageRenderer","PanoViewerModule","PanoViewer","isWebGLAvailable","isStableWebGL","_container","_projectionType","_cubemapConfig","_width","_height","_yaw","_pitch","_fov","_gyroMode","_aspectRatio","_canvasClass","_isValidTouchDirection","TOUCH_DIRECTION_ALL","yawPitchConfig","_isReady","_initYawPitchControl","_initRenderer","onDeviceMotionChange","race","fb","TOUCH_DIRECTION","YAW","PITCH","ALL","_photoSphereRenderer","getContent","warn","_deactivate","keepUpdate","requestPermission","permissionState","enableSensor","enterVR","containerSize","lookAt","verticalAngleOfImage","initialYaw","initialPitch","setYawPitchControl","_bindRendererHandler","_activate","yawSize","maxFov","minFov","ProjectionType","atan","attachTo","_updateYawPitchIfNeeded","startRender","getVideo","pause","stopRender","TOUCH_DIRECTION_NONE","TOUCH_DIRECTION_PITCH","Constants"],"mappings":"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"} \ No newline at end of file diff --git a/dist/SpinViewer/view360.spinviewer.js b/dist/SpinViewer/view360.spinviewer.js new file mode 100644 index 000000000..e409ac0c8 --- /dev/null +++ b/dist/SpinViewer/view360.spinviewer.js @@ -0,0 +1,768 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@egjs/component'), require('@egjs/axes'), require('@egjs/agent')) : + typeof define === 'function' && define.amd ? define(['@egjs/component', '@egjs/axes', '@egjs/agent'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.eg = global.eg || {}, global.eg.view360 = factory(global.eg.Component, global.eg.Axes, global.eg.agent))); +}(this, (function (Component, Axes, getAgent) { 'use strict'; + + var VERSION = "3.6.3"; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); + }; + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + + return ar; + } + + var merge = function (target) { + var srcs = []; + + for (var _i = 1; _i < arguments.length; _i++) { + srcs[_i - 1] = arguments[_i]; + } + + srcs.forEach(function (source) { + Object.keys(source).forEach(function (key) { + var value = source[key]; + + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = __spread(target[key], value); + } else { + target[key] = value; + } + }); + }); + return target; + }; + + /* eslint-disable @typescript-eslint/no-implied-eval */ + /* eslint-disable no-new-func, no-nested-ternary */ + + var win = typeof window !== "undefined" && window.Math === Math ? window : typeof self !== "undefined" && self.Math === Math ? self : Function("return this")(); + /* eslint-enable no-new-func, no-nested-ternary */ + + var doc = win.document; + var nav = win.navigator; + var agent = getAgent(); + var osName = agent.os.name; + var browserName = agent.browser.name; + + /* eslint-disable @typescript-eslint/naming-convention */ + win.Float32Array = typeof win.Float32Array !== "undefined" ? win.Float32Array : win.Array; + var Float32Array = win.Float32Array; + var getComputedStyle = win.getComputedStyle; + var userAgent = win.navigator && win.navigator.userAgent; + var DeviceMotionEvent = win.DeviceMotionEvent; + var devicePixelRatio = win.devicePixelRatio; + + var TRANSFORM = function () { + var _a; + + var docStyle = (_a = doc === null || doc === void 0 ? void 0 : doc.documentElement.style) !== null && _a !== void 0 ? _a : {}; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in docStyle) { + return target[i]; + } + } + + return ""; + }(); // check for will-change support + + + var SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports && win.CSS.supports("will-change", "transform"); + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + var SPINVIEWER_OPTIONS = { + imageUrl: true, + rowCount: true, + colCount: true, + width: true, + height: true, + autoHeight: true, + colRow: true, + scale: true, + frameIndex: true, + wrapperClass: true, + imageClass: true + }; + var SPINVIEWER_EVENTS = { + LOAD: "load", + IMAGE_ERROR: "imageError", + CHANGE: "change", + ANIMATION_END: "animationEnd" + }; + var DEFAULT_WRAPPER_CLASS = "view360-wrapper"; + var DEFAULT_IMAGE_CLASS = "view360-image"; + + var Constants = { + __proto__: null, + SPINVIEWER_OPTIONS: SPINVIEWER_OPTIONS, + SPINVIEWER_EVENTS: SPINVIEWER_EVENTS, + DEFAULT_WRAPPER_CLASS: DEFAULT_WRAPPER_CLASS, + DEFAULT_IMAGE_CLASS: DEFAULT_IMAGE_CLASS + }; + + /** + * @memberof eg.view360 + * @extends eg.Component + * SpriteImage + */ + + var SpriteImage = + /*#__PURE__*/ + function (_super) { + __extends(SpriteImage, _super); + /** + * @class eg.view360.SpriteImage + * @classdesc A module that displays a single or continuous image of any one of the "sprite images". SpinViewer internally uses SpriteImage to show each frame of the sprite image. + * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다. + * @extends eg.Component + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the "Sprite image". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
+ * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * + * // Initialize SpriteImage + * + * var el = document.getElementById("image-div"); + * var sprites = new eg.view360.SpriteImage(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 + * }); + */ + + + function SpriteImage(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + var opt = options || {}; + _this._el = element; + _this._rowCount = opt.rowCount || 1; + _this._colCount = opt.colCount || 1; + _this._totalCount = _this._rowCount * _this._colCount; // total frames + + _this._width = opt.width || "auto"; + _this._height = opt.height || "auto"; + _this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten. + + _this._colRow = [0, 0]; + + if (opt.colRow) { + _this._colRow = opt.colRow; + } else if (opt.frameIndex) { + _this.setFrameIndex(opt.frameIndex); + } + + _this._el.style.width = SpriteImage._getSizeString(_this._width); + _this._el.style.height = SpriteImage._getSizeString(_this._height); + var wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS; + var imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS; + + if (!opt.imageUrl) { + setTimeout(function () { + _this.trigger(new Component.ComponentEvent("imageError", { + imageUrl: opt.imageUrl + })); + }, 0); + return _this; + } + + var imageInContainer = element.querySelector("." + imageClass); + var wrapperInContainer = element.querySelector("." + wrapperClass); + + if (wrapperInContainer && imageInContainer) { + // Set it to invisible to prevent wrapper being resized + imageInContainer.style.display = "none"; + } + + _this._image = imageInContainer || new Image(); + /** + * Event + */ + + var image = _this._image; + + image.onload = function () { + if (wrapperInContainer && imageInContainer) { + imageInContainer.style.display = ""; + } + + _this._bg = SpriteImage._createBgDiv(wrapperInContainer, image, _this._rowCount, _this._colCount, _this._autoHeight); + + _this._el.appendChild(_this._bg); + + _this.setColRow(_this._colRow[0], _this._colRow[1]); + + _this.trigger(new Component.ComponentEvent("load", { + target: _this._el, + bgElement: _this._bg + })); + + if (_this._autoPlayReservedInfo) { + _this.play(_this._autoPlayReservedInfo); + + _this._autoPlayReservedInfo = null; + } + }; + + image.onerror = function () { + _this.trigger(new Component.ComponentEvent("imageError", { + imageUrl: opt.imageUrl + })); + }; + + image.src = opt.imageUrl; + return _this; + } + + var __proto = SpriteImage.prototype; + + SpriteImage._createBgDiv = function (wrapperInContainer, img, rowCount, colCount, autoHeight) { + var el = wrapperInContainer || document.createElement("div"); + el.style.position = "relative"; + el.style.overflow = "hidden"; + img.style.position = "absolute"; + img.style.width = colCount * 100 + "%"; + img.style.height = rowCount * 100 + "%"; + /** Prevent image from being dragged on IE10, IE11, Safari especially */ + + img.ondragstart = function () { + return false; + }; // img.style.pointerEvents = "none"; + // Use hardware accelerator if available + + + if (SUPPORT_WILLCHANGE) { + img.style.willChange = "transform"; + } + + el.appendChild(img); + var unitWidth = img.naturalWidth / colCount; + var unitHeight = img.naturalHeight / rowCount; + + if (autoHeight) { + var r = unitHeight / unitWidth; + el.style.paddingBottom = r * 100 + "%"; + } else { + el.style.height = "100%"; + } + + return el; + }; + + SpriteImage._getSizeString = function (size) { + if (typeof size === "number") { + return size + "px"; + } + + return size; + }; + /** + * Specifies the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정 + * @method eg.view360.SpriteImage#setFrameIndex + * @param {Number} frameIndex frame index of a frame프레임의 인덱스 + * + * @example + * + * sprites.setFrameIndex(0, 1);// col = 0, row = 1 + */ + + + __proto.setFrameIndex = function (index) { + var colRow = this.toColRow(index); + this.setColRow(colRow[0], colRow[1]); + }; + /** + * Returns the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환 + * @method eg.view360.SpriteImage#getFrameIndex + * @return {Number} frame index frame 인덱스 + * + * @example + * + * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1 + * + */ + + + __proto.getFrameIndex = function () { + return this._colRow[1] * this._colCount + this._colRow[0]; + }; + /** + * Specifies the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정 + * @method eg.view360.SpriteImage#setColRow + * @param {Number} col Column number of a frame프레임의 행값 + * @param {Number} row Row number of a frame프레임의 열값 + * + * @example + * + * sprites.setlColRow(1, 2); // col = 1, row = 2 + */ + + + __proto.setColRow = function (col, row) { + if (row > this._rowCount - 1 || col > this._colCount - 1) { + return; + } + + if (this._image && TRANSFORM) { + // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser? + this._image.style[TRANSFORM] = "translate(" + -(col / this._colCount * 100) + "%, " + -(row / this._rowCount * 100) + "%)"; + } + + this._colRow = [col, row]; + }; + /** + * Returns the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환 + * @method eg.view360.SpriteImage#gelColRow + * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열 + * + * @example + * + * var colRow = sprites.getlColRow(); + * // colRow = [1, 2] - index of col is 1, index of row is 2 + * + */ + + + __proto.getColRow = function () { + return this._colRow; + }; + /** + * Stop playing + * @ko play 되고 있던 프레임 재생을 중지합니다. + * @method eg.view360.SpriteImage#stop + * + * @example + * + * viewer.stop(); + * + */ + + + __proto.stop = function () { + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + }; + /** + * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'. + * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다. + * @method eg.view360.SpriteImage#play + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위 + * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복 + * + * @example + * + * viewer.play({angle: 16, playCount: 1}); + * + */ + + + __proto.play = function (_a) { + var _this = this; + + var _b = _a === void 0 ? { + interval: 1000 / this._totalCount, + playCount: 0 + } : _a, + interval = _b.interval, + playCount = _b.playCount; + + if (!this._bg) { + this._autoPlayReservedInfo = { + interval: interval, + playCount: playCount + }; + return; + } + + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + + var frameIndex = this.getFrameIndex(); + var count = 0; + var frameCount = 0; // for checking 1 cycle + + this._autoPlayTimer = window.setInterval(function () { + frameIndex %= _this._totalCount; + + var colRow = _this.toColRow(frameIndex); + + _this.setColRow(colRow[0], colRow[1]); + + frameIndex++; // Done 1 Cycle? + + if (++frameCount === _this._totalCount) { + frameCount = 0; + count++; + } + + if (playCount > 0 && count === playCount) { + clearInterval(_this._autoPlayTimer); + } + }, interval); + }; + + __proto.toColRow = function (frameIndex) { + var colCount = this._colCount; + var rowCount = this._rowCount; + + if (frameIndex < 0) { + return [0, 0]; + } else if (frameIndex >= this._totalCount) { + return [colCount - 1, rowCount - 1]; + } + + var col = frameIndex % colCount; + var row = Math.floor(frameIndex / colCount); // console.log(frameIndex, col, row); + + return [col, row]; + }; + + SpriteImage.VERSION = VERSION; + return SpriteImage; + }(Component); + + var DEFAULT_PAN_SCALE = 0.21; + /** + * @memberof eg.view360 + * @extends eg.Component + * SpinViewer + */ + + var SpinViewer = + /*#__PURE__*/ + function (_super) { + __extends(SpinViewer, _super); + /** + * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object. + * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다. + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값 + * @param {String} [options.wrapperClass="view360-wrapper"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @param {String} [options.imageClass="view360-image"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * ``` + * // Initialize SpinViewer + * var el = document.getElementById("product-360"); + * var viewer = new eg.view360.SpinViewer(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 //required + * }); + * ``` + */ + + + function SpinViewer(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this._el = element; + + var opt = __assign({}, options); + + var colCount = opt.colCount || 1; + var rowCount = opt.rowCount || 1; + _this._scale = opt.scale || 1; + _this._panScale = _this._scale * DEFAULT_PAN_SCALE; + _this._frameCount = colCount * rowCount; // Init SpriteImage + + _this._sprites = new SpriteImage(element, opt).on({ + "load": function (evt) { + _this.trigger(new Component.ComponentEvent("load", evt)); + }, + "imageError": function (evt) { + _this.trigger(new Component.ComponentEvent("imageError", { + imageUrl: evt.imageUrl + })); + } + }); // Init Axes + + _this._panInput = new Axes.PanInput(_this._el, { + scale: [_this._panScale, _this._panScale] + }); + _this._axes = new Axes({ + angle: { + range: [0, 359], + circular: true + } + }).on({ + "change": function (evt) { + var curr = Math.floor(evt.pos.angle / (360 / _this._frameCount)); + var frameIndex = _this._frameCount - curr - 1; + + _this._sprites.setFrameIndex(frameIndex); + + _this.trigger(new Component.ComponentEvent("change", { + frameIndex: frameIndex, + colRow: _this._sprites.getColRow(), + angle: evt.pos.angle + })); + }, + "animationEnd": function (evt) { + _this.trigger(new Component.ComponentEvent("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + + _this._axes.connect("angle", _this._panInput); + + return _this; + } + /** + * Set spin scale + * @ko scale 을 조정할 수 있는 함수 + * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.setScale(2);// It moves twice as much. + */ + + + var __proto = SpinViewer.prototype; + + __proto.setScale = function (scale) { + if (isNaN(scale) || scale < 0) { + return this; + } + + this._scale = scale; + this._panScale = scale * DEFAULT_PAN_SCALE; + this._panInput.options.scale = [this._panScale, this._panScale]; + return this; + }; + /** + * Get spin scale + * @ko scale 값을 반환한다. + * + * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @example + * viewer.getScale();// It returns number + */ + + + __proto.getScale = function () { + return this._scale; + }; + /** + * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle. + * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle상대적 회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinBy(720, {duration: 500}); + */ + + + __proto.spinBy = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setBy({ + angle: angle + }, param.duration); + + return this; + }; + /** + * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle). + * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinTo(30, {duration:100}); + */ + + + __proto.spinTo = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setTo({ + angle: angle + }, param.duration); + + return this; + }; + /** + * Returns current angles + * @ko 현재 각도를 반환한다. + * + * @return {Number} Current angle 현재 각도 + */ + + + __proto.getAngle = function () { + return this._axes.get().angle || 0; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @static + * @example + * eg.view360.SpinViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.SpinViewer + */ + + + SpinViewer.VERSION = VERSION; + return SpinViewer; + }(Component); + + /* eslint-disable @typescript-eslint/naming-convention */ + var SpinViewerModule = { + SpinViewer: SpinViewer, + SpriteImage: SpriteImage, + VERSION: VERSION + }; + merge(SpinViewerModule, Constants); + + return SpinViewerModule; + +}))); +//# sourceMappingURL=view360.spinviewer.js.map diff --git a/dist/SpinViewer/view360.spinviewer.js.map b/dist/SpinViewer/view360.spinviewer.js.map new file mode 100644 index 000000000..090b32a44 --- /dev/null +++ b/dist/SpinViewer/view360.spinviewer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.spinviewer.js","sources":["../../src/version.ts","../../src/utils/utils.ts","../../src/utils/browser.ts","../../src/utils/browserFeature.ts","../../src/SpinViewer/consts.ts","../../src/SpinViewer/SpriteImage.ts","../../src/SpinViewer/SpinViewer.ts","../../src/SpinViewer/index.umd.ts"],"sourcesContent":["const VERSION = \"#__VERSION__#\";\n\nexport {\n VERSION\n};\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","import { SpinViewerOptions, SpinViewerEvent } from \"./SpinViewer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const SPINVIEWER_OPTIONS: { [key in keyof SpinViewerOptions]: true } = {\n imageUrl: true,\n rowCount: true,\n colCount: true,\n width: true,\n height: true,\n autoHeight: true,\n colRow: true,\n scale: true,\n frameIndex: true,\n wrapperClass: true,\n imageClass: true\n};\n\nexport const SPINVIEWER_EVENTS: {\n [key: string]: keyof SpinViewerEvent;\n} = {\n LOAD: \"load\",\n IMAGE_ERROR: \"imageError\",\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n};\n\nexport const DEFAULT_WRAPPER_CLASS = \"view360-wrapper\";\nexport const DEFAULT_IMAGE_CLASS = \"view360-image\";\n","import Component, { ComponentEvent } from \"@egjs/component\";\n\nimport { TRANSFORM, SUPPORT_WILLCHANGE } from \"../utils/browserFeature\";\nimport { VERSION } from \"../version\";\n\nimport { SpinViewerOptions } from \"./SpinViewer\";\nimport { DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS } from \"./consts\";\n\nexport interface SpriteImageEvent {\n /**\n * Events that occur when component loading is complete\n * @ko 컴포넌트 로딩이 완료되면 발생하는 이벤트\n * @name eg.view360.SpriteImage#load\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {HTMLElement} param.target The target element for which to display the image 이미지를 보여줄 대상 엘리먼트\n * @param {HTMLElement} param.bgElement Generated background image element 생성된 background 이미지 엘리먼트\n *\n * @example\n *\n * sprites.on({\n * \"load\" : function(evt) {\n * console.log(\"load event fired - e.target\", e.target, \"e.bgElement\", e.bgElement);\n * }\n * });\n */\n load: {\n target: HTMLElement;\n bgElement: HTMLDivElement;\n };\n /**\n * An event that occurs when the image index is changed by the user's left / right panning\n * @ko 사용자의 좌우 Panning 에 의해 이미지 인덱스가 변경되었을때 발생하는 이벤트\n * @name eg.view360.SpriteImage#imageError\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {String} param.imageUrl User-specified image URL 사용자가 지정한 이미지 URL\n *\n * @example\n *\n * sprites.on({\n * \"imageError\" : function(evt) {\n * // Error handling\n * console.log(e.imageUrl);\n * }\n * });\n */\n imageError: {\n imageUrl?: string;\n };\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpriteImage\n */\nclass SpriteImage extends Component {\n private static _createBgDiv(wrapperInContainer: HTMLDivElement | null, img: HTMLImageElement, rowCount: number, colCount: number, autoHeight: boolean) {\n const el = wrapperInContainer || document.createElement(\"div\");\n\n el.style.position = \"relative\";\n el.style.overflow = \"hidden\";\n\n img.style.position = \"absolute\";\n img.style.width = `${colCount * 100}%`;\n img.style.height = `${rowCount * 100}%`;\n\n /** Prevent image from being dragged on IE10, IE11, Safari especially */\n img.ondragstart = () => (false); // img.style.pointerEvents = \"none\";\n // Use hardware accelerator if available\n if (SUPPORT_WILLCHANGE) {\n (img.style.willChange = \"transform\");\n }\n\n el.appendChild(img);\n\n const unitWidth = img.naturalWidth / colCount;\n const unitHeight = img.naturalHeight / rowCount;\n\n if (autoHeight) {\n const r = unitHeight / unitWidth;\n\n el.style.paddingBottom = `${r * 100}%`;\n } else {\n el.style.height = \"100%\";\n }\n\n return el;\n }\n\n private static _getSizeString(size) {\n if (typeof size === \"number\") {\n return `${size}px`;\n }\n\n return size;\n }\n\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _rowCount: number;\n private _colCount: number;\n private _totalCount: number;\n private _width: number | string;\n private _height: number | string;\n private _autoHeight: boolean;\n private _colRow: number[];\n private _image: HTMLImageElement;\n private _bg: HTMLDivElement;\n private _autoPlayReservedInfo: { interval: number; playCount: number } | null;\n private _autoPlayTimer: number;\n\n /**\n * @class eg.view360.SpriteImage\n * @classdesc A module that displays a single or continuous image of any one of the \"sprite images\". SpinViewer internally uses SpriteImage to show each frame of the sprite image.\n * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다.\n * @extends eg.Component\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the \"Sprite image\". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n *\n * // Initialize SpriteImage\n *\n * var el = document.getElementById(\"image-div\");\n * var sprites = new eg.view360.SpriteImage(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24\n * });\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n const opt = options || {};\n\n this._el = element;\n this._rowCount = opt.rowCount || 1;\n this._colCount = opt.colCount || 1;\n this._totalCount = this._rowCount * this._colCount; // total frames\n this._width = opt.width || \"auto\";\n this._height = opt.height || \"auto\";\n this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten.\n this._colRow = [0, 0];\n\n if (opt.colRow) {\n this._colRow = opt.colRow;\n } else if (opt.frameIndex) {\n this.setFrameIndex(opt.frameIndex);\n }\n\n this._el.style.width = SpriteImage._getSizeString(this._width);\n this._el.style.height = SpriteImage._getSizeString(this._height);\n\n const wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS;\n const imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS;\n\n if (!opt.imageUrl) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n }, 0);\n return;\n }\n\n const imageInContainer = element.querySelector(`.${imageClass}`);\n const wrapperInContainer = element.querySelector(`.${wrapperClass}`);\n\n if (wrapperInContainer && imageInContainer) {\n // Set it to invisible to prevent wrapper being resized\n imageInContainer.style.display = \"none\";\n }\n\n this._image = imageInContainer || new Image();\n /**\n * Event\n */\n\n const image = this._image;\n\n image.onload = () => {\n if (wrapperInContainer && imageInContainer) {\n imageInContainer.style.display = \"\";\n }\n\n this._bg = SpriteImage._createBgDiv(\n wrapperInContainer,\n image,\n this._rowCount,\n this._colCount,\n this._autoHeight\n );\n this._el.appendChild(this._bg);\n this.setColRow(this._colRow[0], this._colRow[1]);\n\n this.trigger(new ComponentEvent(\"load\", {\n target: this._el,\n bgElement: this._bg\n }));\n\n if (this._autoPlayReservedInfo) {\n this.play(this._autoPlayReservedInfo);\n this._autoPlayReservedInfo = null;\n }\n };\n\n image.onerror = () => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n };\n\n image.src = opt.imageUrl;\n }\n\n /**\n * Specifies the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정\n * @method eg.view360.SpriteImage#setFrameIndex\n * @param {Number} frameIndex frame index of a frame프레임의 인덱스\n *\n * @example\n *\n * sprites.setFrameIndex(0, 1);// col = 0, row = 1\n */\n public setFrameIndex(index: number) {\n const colRow = this.toColRow(index);\n\n this.setColRow(colRow[0], colRow[1]);\n }\n\n /**\n * Returns the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환\n * @method eg.view360.SpriteImage#getFrameIndex\n * @return {Number} frame index frame 인덱스\n *\n * @example\n *\n * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1\n *\n */\n public getFrameIndex() {\n return this._colRow[1] * this._colCount + this._colRow[0];\n }\n\n /**\n * Specifies the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정\n * @method eg.view360.SpriteImage#setColRow\n * @param {Number} col Column number of a frame프레임의 행값\n * @param {Number} row Row number of a frame프레임의 열값\n *\n * @example\n *\n * sprites.setlColRow(1, 2); // col = 1, row = 2\n */\n public setColRow(col: number, row: number) {\n if (row > this._rowCount - 1 || col > this._colCount - 1) {\n return;\n }\n\n if (this._image && TRANSFORM) {\n // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser?\n this._image.style[TRANSFORM] = `translate(${-(col / this._colCount * 100)}%, ${-(row / this._rowCount * 100)}%)`;\n }\n\n this._colRow = [col, row];\n }\n\n /**\n * Returns the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환\n * @method eg.view360.SpriteImage#gelColRow\n * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열\n *\n * @example\n *\n * var colRow = sprites.getlColRow();\n * // colRow = [1, 2] - index of col is 1, index of row is 2\n *\n */\n public getColRow() {\n return this._colRow;\n }\n\n /**\n * Stop playing\n * @ko play 되고 있던 프레임 재생을 중지합니다.\n * @method eg.view360.SpriteImage#stop\n *\n * @example\n *\n * viewer.stop();\n *\n */\n public stop() {\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n }\n\n /**\n * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'.\n * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다.\n * @method eg.view360.SpriteImage#play\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위\n * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복\n *\n * @example\n *\n * viewer.play({angle: 16, playCount: 1});\n *\n */\n public play({ interval, playCount } = { interval: 1000 / this._totalCount, playCount: 0 }) {\n if (!this._bg) {\n this._autoPlayReservedInfo = {interval, playCount};\n return;\n }\n\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n\n let frameIndex = this.getFrameIndex();\n let count = 0;\n let frameCount = 0; // for checking 1 cycle\n\n this._autoPlayTimer = window.setInterval(() => {\n frameIndex %= this._totalCount;\n const colRow = this.toColRow(frameIndex);\n\n this.setColRow(colRow[0], colRow[1]);\n frameIndex++;\n\n // Done 1 Cycle?\n if (++frameCount === this._totalCount) {\n frameCount = 0;\n count++;\n }\n\n if (playCount > 0 && count === playCount) {\n clearInterval(this._autoPlayTimer);\n }\n }, interval);\n }\n\n public toColRow(frameIndex: number) {\n const colCount = this._colCount;\n const rowCount = this._rowCount;\n\n if (frameIndex < 0) {\n return [0, 0];\n } else if (frameIndex >= this._totalCount) {\n return [colCount - 1, rowCount - 1];\n }\n\n const col = frameIndex % colCount;\n const row = Math.floor(frameIndex / colCount);\n\n // console.log(frameIndex, col, row);\n return [col, row];\n }\n}\n\nexport default SpriteImage;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport { VERSION } from \"../version\";\nimport { AnimationEndEvent, ChangeEvent, ImageErrorEvent, LoadEvent } from \"../types/event\";\n\nimport SpriteImage from \"./SpriteImage\";\n\nconst DEFAULT_PAN_SCALE = 0.21;\n\nexport interface SpinViewerEvent {\n load: LoadEvent;\n imageError: ImageErrorEvent;\n change: ChangeEvent;\n animationEnd: AnimationEndEvent;\n}\n\nexport interface SpinViewerOptions {\n imageUrl: string;\n rowCount: number;\n colCount: number;\n width: number | string;\n height: number | string;\n autoHeight: boolean;\n colRow: number[];\n scale: number;\n frameIndex: number;\n wrapperClass: string;\n imageClass: string;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpinViewer\n */\nclass SpinViewer extends Component {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @static\n * @example\n * eg.view360.SpinViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.SpinViewer\n */\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _sprites: SpriteImage;\n private _axes: Axes;\n private _panInput: PanInput;\n\n private _scale: number;\n private _panScale: number;\n private _frameCount: number;\n\n /**\n * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object.\n * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다.\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값\n * @param {String} [options.wrapperClass=\"view360-wrapper\"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @param {String} [options.imageClass=\"view360-image\"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n * ```\n * // Initialize SpinViewer\n * var el = document.getElementById(\"product-360\");\n * var viewer = new eg.view360.SpinViewer(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24 //required\n * });\n * ```\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n\n this._el = element;\n\n const opt = {...options};\n const colCount = opt.colCount || 1;\n const rowCount = opt.rowCount || 1;\n\n this._scale = (opt.scale || 1);\n this._panScale = this._scale * DEFAULT_PAN_SCALE;\n\n this._frameCount = colCount * rowCount;\n\n // Init SpriteImage\n this._sprites = new SpriteImage(element, opt).on({\n \"load\": evt => {\n this.trigger(new ComponentEvent(\"load\", evt));\n },\n \"imageError\": evt => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: evt.imageUrl\n }));\n }\n });\n\n // Init Axes\n this._panInput = new PanInput(this._el, {\n scale: [this._panScale, this._panScale]\n });\n this._axes = new Axes({\n angle: {\n range: [0, 359],\n circular: true\n }\n }).on({\n \"change\": evt => {\n const curr = Math.floor(evt.pos.angle / (360 / this._frameCount));\n const frameIndex = this._frameCount - curr - 1;\n\n this._sprites.setFrameIndex(frameIndex);\n\n this.trigger(new ComponentEvent(\"change\", {\n frameIndex,\n colRow: this._sprites.getColRow(),\n angle: evt.pos.angle\n }));\n },\n \"animationEnd\": evt => {\n this.trigger(new ComponentEvent(\"animationEnd\", {\n isTrusted: evt.isTrusted\n }));\n }\n });\n\n this._axes.connect(\"angle\", this._panInput);\n }\n\n /**\n * Set spin scale\n * @ko scale 을 조정할 수 있는 함수\n * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.setScale(2);// It moves twice as much.\n */\n public setScale(scale: number) {\n if (isNaN(scale) || scale < 0) {\n return this;\n }\n\n this._scale = scale;\n this._panScale = scale * DEFAULT_PAN_SCALE;\n this._panInput.options.scale = [this._panScale, this._panScale];\n\n return this;\n }\n\n /**\n * Get spin scale\n * @ko scale 값을 반환한다.\n *\n * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @example\n * viewer.getScale();// It returns number\n */\n public getScale() {\n return this._scale;\n }\n\n /**\n * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle.\n * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle상대적 회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinBy(720, {duration: 500});\n */\n public spinBy(angle = 0, param = {duration: 0}) {\n this._axes.setBy({angle}, param.duration);\n return this;\n }\n\n /**\n * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle).\n * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinTo(30, {duration:100});\n */\n public spinTo(angle = 0, param = {duration: 0}) {\n this._axes.setTo({angle}, param.duration);\n return this;\n }\n\n /**\n * Returns current angles\n * @ko 현재 각도를 반환한다.\n *\n * @return {Number} Current angle 현재 각도\n */\n public getAngle() {\n return this._axes.get().angle || 0;\n }\n}\n\nexport default SpinViewer;\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { VERSION } from \"../version\";\nimport { merge } from \"../utils/utils\";\n\nimport SpinViewer from \"./SpinViewer\";\nimport SpriteImage from \"./SpriteImage\";\nimport * as Constants from \"./consts\";\n\nconst SpinViewerModule = {\n SpinViewer,\n SpriteImage,\n VERSION\n};\n\nmerge(SpinViewerModule, Constants);\n\nexport default SpinViewerModule;\n"],"names":["VERSION","merge","target","_i","srcs","forEach","source","Object","keys","key","value","Array","isArray","win","window","Math","self","Function","doc","document","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","Float32Array","getComputedStyle","userAgent","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","i","len","length","SUPPORT_WILLCHANGE","CSS","supports","SPINVIEWER_OPTIONS","imageUrl","rowCount","colCount","width","height","autoHeight","colRow","scale","frameIndex","wrapperClass","imageClass","SPINVIEWER_EVENTS","LOAD","IMAGE_ERROR","CHANGE","ANIMATION_END","DEFAULT_WRAPPER_CLASS","DEFAULT_IMAGE_CLASS","__extends","element","options","_super","opt","_this","_el","_rowCount","_colCount","_totalCount","_width","_height","_autoHeight","_colRow","setFrameIndex","SpriteImage","_getSizeString","setTimeout","trigger","ComponentEvent","imageInContainer","querySelector","wrapperInContainer","display","_image","Image","image","onload","_bg","_createBgDiv","appendChild","setColRow","bgElement","_autoPlayReservedInfo","play","onerror","src","img","el","createElement","position","overflow","ondragstart","willChange","unitWidth","naturalWidth","unitHeight","naturalHeight","r","paddingBottom","size","index","toColRow","col","row","_autoPlayTimer","clearInterval","_a","_b","interval","playCount","getFrameIndex","count","frameCount","setInterval","floor","Component","DEFAULT_PAN_SCALE","_scale","_panScale","_frameCount","_sprites","on","evt","_panInput","PanInput","_axes","Axes","angle","range","circular","curr","pos","getColRow","isTrusted","connect","isNaN","param","duration","setBy","setTo","get","SpinViewer","SpinViewerModule","Constants"],"mappings":";;;;;;;;;;;;;;EAAA,IAAMA,OAAO,GAAG,OAAhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECIO,IAAMC,KAAK,GAAG,UAAyCC,MAAzC;EAAuD,eAAA;;SAAA,YAAAC,uBAAAA;EAAAC,IAAAA,YAAA,gBAAA;;;EAC1EA,EAAAA,IAAI,CAACC,OAAL,CAAa,UAAAC,MAAA;EACZC,IAAAA,MAAM,CAACC,IAAP,CAAYF,MAAZ,EAAoBD,OAApB,CAA4B,UAAAI,GAAA;EACzB,UAAMC,KAAK,GAAGJ,MAAM,CAACG,GAAD,CAApB;;EACA,UAAIE,KAAK,CAACC,OAAN,CAAcV,MAAM,CAACO,GAAD,CAApB,KAA8BE,KAAK,CAACC,OAAN,CAAcF,KAAd,CAAlC,EAAwD;EACtDR,QAAAA,MAAM,CAACO,GAAD,CAAN,YAAkBP,MAAM,CAACO,GAAD,GAAUC,MAAlC;EACD,OAFD,MAEO;EACLR,QAAAA,MAAM,CAACO,GAAD,CAAN,GAAcC,KAAd;EACD;EACH,KAPD;EAQA,GATD;EAWA,SAAOR,MAAP;EACD,CAbM;;ECJP;EAOA;;EACA,IAAMW,GAAG,GAAG,OAAOC,MAAP,KAAkB,WAAlB,IAAiCA,MAAM,CAACC,IAAP,KAAgBA,IAAjD,GACRD,MADQ,GAER,OAAOE,IAAP,KAAgB,WAAhB,IAA+BA,IAAI,CAACD,IAAL,KAAcA,IAA7C,GACEC,IADF,GAEEC,QAAQ,CAAC,aAAD,CAAR,EAJN;EAKA;;EAEA,IAAMC,GAAG,GAAGL,GAAG,CAACM,QAAhB;EACA,IAAMC,GAAG,GAAGP,GAAG,CAACQ,SAAhB;EACA,IAAMC,KAAK,GAAGC,QAAQ,EAAtB;EACA,IAAMC,MAAM,GAAGF,KAAK,CAACG,EAAN,CAASC,IAAxB;EACA,IAAMC,WAAW,GAAGL,KAAK,CAACM,OAAN,CAAcF,IAAlC;;ECnBA;EAOAb,GAAG,CAACgB,YAAJ,GAAoB,OAAOhB,GAAG,CAACgB,YAAX,KAA4B,WAA7B,GAA4ChB,GAAG,CAACgB,YAAhD,GAA+DhB,GAAG,CAACF,KAAtF;EAEA,IAAMkB,YAAY,GAAGhB,GAAG,CAACgB,YAAzB;EACA,IAAMC,gBAAgB,GAAGjB,GAAG,CAACiB,gBAA7B;EACA,IAAMC,SAAS,GAAGlB,GAAG,CAACQ,SAAJ,IAAiBR,GAAG,CAACQ,SAAJ,CAAcU,SAAjD;EAGA,IAAMC,iBAAiB,GAAGnB,GAAG,CAACmB,iBAA9B;EACA,IAAMC,gBAAgB,GAAGpB,GAAG,CAACoB,gBAA7B;;EAEA,IAAMC,SAAS,GAAI;;;EACjB,MAAMC,QAAQ,SAAGjB,GAAG,SAAH,IAAAA,GAAG,WAAH,SAAA,GAAAA,GAAG,CAAEkB,eAAL,CAAqBC,wCAAS,EAA/C;EACA,MAAMnC,MAAM,GAAG,CAAC,WAAD,EAAc,iBAAd,EAAiC,aAAjC,EAAgD,cAAhD,CAAf;;EAEA,OAAK,IAAIoC,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAGrC,MAAM,CAACsC,MAA7B,EAAqCF,CAAC,GAAGC,GAAzC,EAA8CD,CAAC,EAA/C,EAAmD;EACjD,QAAIpC,MAAM,CAACoC,CAAD,CAAN,IAAaH,QAAjB,EAA2B;EACzB,aAAOjC,MAAM,CAACoC,CAAD,CAAb;EACD;EACF;;EACD,SAAO,EAAP;EACD,CAViB,EAAlB;;;EAaA,IAAMG,kBAAkB,GAAG5B,GAAG,CAAC6B,GAAJ,IAAW7B,GAAG,CAAC6B,GAAJ,CAAQC,QAAnB,IAC1B9B,GAAG,CAAC6B,GAAJ,CAAQC,QAAR,CAAiB,aAAjB,EAAgC,WAAhC,CADD;;EC5BA;EACO,IAAMC,kBAAkB,GAA+C;EAC5EC,EAAAA,QAAQ,EAAE,IADkE;EAE5EC,EAAAA,QAAQ,EAAE,IAFkE;EAG5EC,EAAAA,QAAQ,EAAE,IAHkE;EAI5EC,EAAAA,KAAK,EAAE,IAJqE;EAK5EC,EAAAA,MAAM,EAAE,IALoE;EAM5EC,EAAAA,UAAU,EAAE,IANgE;EAO5EC,EAAAA,MAAM,EAAE,IAPoE;EAQ5EC,EAAAA,KAAK,EAAE,IARqE;EAS5EC,EAAAA,UAAU,EAAE,IATgE;EAU5EC,EAAAA,YAAY,EAAE,IAV8D;EAW5EC,EAAAA,UAAU,EAAE;EAXgE,CAAvE;EAcA,IAAMC,iBAAiB,GAE1B;EACFC,EAAAA,IAAI,EAAE,MADJ;EAEFC,EAAAA,WAAW,EAAE,YAFX;EAGFC,EAAAA,MAAM,EAAE,QAHN;EAIFC,EAAAA,aAAa,EAAE;EAJb,CAFG;EASA,IAAMC,qBAAqB,GAAG,iBAA9B;EACA,IAAMC,mBAAmB,GAAG,eAA5B;;;;;;;;;;ECyBP;;;;;;EAKA;;;EAA0BC,EAAAA,8BAAA;EAyDxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA,sBAAA,CAAmBC,OAAnB,EAAyCC,OAAzC;EAAyC,0BAAA,EAAA;EAAAA,MAAAA,YAAA;;;EAAzC,gBACEC,WAAA,KAAA,SADF;;EAEE,QAAMC,GAAG,GAAGF,OAAO,IAAI,EAAvB;EAEAG,IAAAA,KAAI,CAACC,GAAL,GAAWL,OAAX;EACAI,IAAAA,KAAI,CAACE,SAAL,GAAiBH,GAAG,CAACrB,QAAJ,IAAgB,CAAjC;EACAsB,IAAAA,KAAI,CAACG,SAAL,GAAiBJ,GAAG,CAACpB,QAAJ,IAAgB,CAAjC;EACAqB,IAAAA,KAAI,CAACI,WAAL,GAAmBJ,KAAI,CAACE,SAAL,GAAiBF,KAAI,CAACG,SAAzC;;EACAH,IAAAA,KAAI,CAACK,MAAL,GAAcN,GAAG,CAACnB,KAAJ,IAAa,MAA3B;EACAoB,IAAAA,KAAI,CAACM,OAAL,GAAeP,GAAG,CAAClB,MAAJ,IAAc,MAA7B;EACAmB,IAAAA,KAAI,CAACO,WAAL,GAAmBR,GAAG,CAACjB,UAAJ,IAAkB,IAAlB,GAAyBiB,GAAG,CAACjB,UAA7B,GAA0C,IAA7D;;EACAkB,IAAAA,KAAI,CAACQ,OAAL,GAAe,CAAC,CAAD,EAAI,CAAJ,CAAf;;EAEA,QAAIT,GAAG,CAAChB,MAAR,EAAgB;EACdiB,MAAAA,KAAI,CAACQ,OAAL,GAAeT,GAAG,CAAChB,MAAnB;EACD,KAFD,MAEO,IAAIgB,GAAG,CAACd,UAAR,EAAoB;EACzBe,MAAAA,KAAI,CAACS,aAAL,CAAmBV,GAAG,CAACd,UAAvB;EACD;;EAEDe,IAAAA,KAAI,CAACC,GAAL,CAAShC,KAAT,CAAeW,KAAf,GAAuB8B,WAAW,CAACC,cAAZ,CAA2BX,KAAI,CAACK,MAAhC,CAAvB;EACAL,IAAAA,KAAI,CAACC,GAAL,CAAShC,KAAT,CAAeY,MAAf,GAAwB6B,WAAW,CAACC,cAAZ,CAA2BX,KAAI,CAACM,OAAhC,CAAxB;EAEA,QAAMpB,YAAY,GAAGa,GAAG,CAACb,YAAJ,IAAoBO,qBAAzC;EACA,QAAMN,UAAU,GAAGY,GAAG,CAACZ,UAAJ,IAAkBO,mBAArC;;EAEA,QAAI,CAACK,GAAG,CAACtB,QAAT,EAAmB;EACjBmC,MAAAA,UAAU,CAAC;EACTZ,QAAAA,KAAI,CAACa,OAAL,CAAa,IAAIC,wBAAJ,CAAmB,YAAnB,EAAiC;EAC5CrC,UAAAA,QAAQ,EAAEsB,GAAG,CAACtB;EAD8B,SAAjC,CAAb;EAGD,OAJS,EAIP,CAJO,CAAV;;EAMD;;EAED,QAAMsC,gBAAgB,GAAGnB,OAAO,CAACoB,aAAR,CAAwC,MAAI7B,UAA5C,CAAzB;EACA,QAAM8B,kBAAkB,GAAGrB,OAAO,CAACoB,aAAR,CAAsC,MAAI9B,YAA1C,CAA3B;;EAEA,QAAI+B,kBAAkB,IAAIF,gBAA1B,EAA4C;EAC1C;EACAA,MAAAA,gBAAgB,CAAC9C,KAAjB,CAAuBiD,OAAvB,GAAiC,MAAjC;EACD;;EAEDlB,IAAAA,KAAI,CAACmB,MAAL,GAAcJ,gBAAgB,IAAI,IAAIK,KAAJ,EAAlC;EACA;;;;EAIA,QAAMC,KAAK,GAAGrB,KAAI,CAACmB,MAAnB;;EAEAE,IAAAA,KAAK,CAACC,MAAN,GAAe;EACb,UAAIL,kBAAkB,IAAIF,gBAA1B,EAA4C;EAC1CA,QAAAA,gBAAgB,CAAC9C,KAAjB,CAAuBiD,OAAvB,GAAiC,EAAjC;EACD;;EAEDlB,MAAAA,KAAI,CAACuB,GAAL,GAAWb,WAAW,CAACc,YAAZ,CACTP,kBADS,EAETI,KAFS,EAGTrB,KAAI,CAACE,SAHI,EAITF,KAAI,CAACG,SAJI,EAKTH,KAAI,CAACO,WALI,CAAX;;EAOAP,MAAAA,KAAI,CAACC,GAAL,CAASwB,WAAT,CAAqBzB,KAAI,CAACuB,GAA1B;;EACAvB,MAAAA,KAAI,CAAC0B,SAAL,CAAe1B,KAAI,CAACQ,OAAL,CAAa,CAAb,CAAf,EAAgCR,KAAI,CAACQ,OAAL,CAAa,CAAb,CAAhC;;EAEAR,MAAAA,KAAI,CAACa,OAAL,CAAa,IAAIC,wBAAJ,CAAmB,MAAnB,EAA2B;EACtChF,QAAAA,MAAM,EAAEkE,KAAI,CAACC,GADyB;EAEtC0B,QAAAA,SAAS,EAAE3B,KAAI,CAACuB;EAFsB,OAA3B,CAAb;;EAKA,UAAIvB,KAAI,CAAC4B,qBAAT,EAAgC;EAC9B5B,QAAAA,KAAI,CAAC6B,IAAL,CAAU7B,KAAI,CAAC4B,qBAAf;;EACA5B,QAAAA,KAAI,CAAC4B,qBAAL,GAA6B,IAA7B;EACD;EACF,KAxBD;;EA0BAP,IAAAA,KAAK,CAACS,OAAN,GAAgB;EACd9B,MAAAA,KAAI,CAACa,OAAL,CAAa,IAAIC,wBAAJ,CAAmB,YAAnB,EAAiC;EAC5CrC,QAAAA,QAAQ,EAAEsB,GAAG,CAACtB;EAD8B,OAAjC,CAAb;EAGD,KAJD;;EAMA4C,IAAAA,KAAK,CAACU,GAAN,GAAYhC,GAAG,CAACtB,QAAhB;;EACD;;;;EAvKciC,EAAAA,wBAAA,GAAf,UAA4BO,kBAA5B,EAAuEe,GAAvE,EAA8FtD,QAA9F,EAAgHC,QAAhH,EAAkIG,UAAlI;EACE,QAAMmD,EAAE,GAAGhB,kBAAkB,IAAIlE,QAAQ,CAACmF,aAAT,CAAuB,KAAvB,CAAjC;EAEAD,IAAAA,EAAE,CAAChE,KAAH,CAASkE,QAAT,GAAoB,UAApB;EACAF,IAAAA,EAAE,CAAChE,KAAH,CAASmE,QAAT,GAAoB,QAApB;EAEAJ,IAAAA,GAAG,CAAC/D,KAAJ,CAAUkE,QAAV,GAAqB,UAArB;EACAH,IAAAA,GAAG,CAAC/D,KAAJ,CAAUW,KAAV,GAAqBD,QAAQ,GAAG,GAAX,MAArB;EACAqD,IAAAA,GAAG,CAAC/D,KAAJ,CAAUY,MAAV,GAAsBH,QAAQ,GAAG,GAAX,MAAtB;EAEA;;EACAsD,IAAAA,GAAG,CAACK,WAAJ,GAAkB;EAAM,aAAC,KAAD;EAAO,KAA/B;EACA;;;EACA,QAAIhE,kBAAJ,EAAwB;EACrB2D,MAAAA,GAAG,CAAC/D,KAAJ,CAAUqE,UAAV,GAAuB,WAAxB;EACD;;EAEDL,IAAAA,EAAE,CAACR,WAAH,CAAeO,GAAf;EAEA,QAAMO,SAAS,GAAGP,GAAG,CAACQ,YAAJ,GAAmB7D,QAArC;EACA,QAAM8D,UAAU,GAAGT,GAAG,CAACU,aAAJ,GAAoBhE,QAAvC;;EAEA,QAAII,UAAJ,EAAgB;EACd,UAAM6D,CAAC,GAAGF,UAAU,GAAGF,SAAvB;EAEAN,MAAAA,EAAE,CAAChE,KAAH,CAAS2E,aAAT,GAA4BD,CAAC,GAAG,GAAJ,MAA5B;EACD,KAJD,MAIO;EACLV,MAAAA,EAAE,CAAChE,KAAH,CAASY,MAAT,GAAkB,MAAlB;EACD;;EAED,WAAOoD,EAAP;EACD,GA/Bc;;EAiCAvB,EAAAA,0BAAA,GAAf,UAA8BmC,IAA9B;EACE,QAAI,OAAOA,IAAP,KAAgB,QAApB,EAA8B;EAC5B,aAAUA,IAAI,OAAd;EACD;;EAED,WAAOA,IAAP;EACD,GANc;EAwIf;;;;;;;;;;;;EAUO,uBAAA,GAAP,UAAqBC,KAArB;EACE,QAAM/D,MAAM,GAAG,KAAKgE,QAAL,CAAcD,KAAd,CAAf;EAEA,SAAKpB,SAAL,CAAe3C,MAAM,CAAC,CAAD,CAArB,EAA0BA,MAAM,CAAC,CAAD,CAAhC;EACD,GAJM;EAMP;;;;;;;;;;;;;EAWO,uBAAA,GAAP;EACE,WAAO,KAAKyB,OAAL,CAAa,CAAb,IAAkB,KAAKL,SAAvB,GAAmC,KAAKK,OAAL,CAAa,CAAb,CAA1C;EACD,GAFM;EAIP;;;;;;;;;;;;;EAWO,mBAAA,GAAP,UAAiBwC,GAAjB,EAA8BC,GAA9B;EACE,QAAIA,GAAG,GAAG,KAAK/C,SAAL,GAAiB,CAAvB,IAA4B8C,GAAG,GAAG,KAAK7C,SAAL,GAAiB,CAAvD,EAA0D;EACxD;EACD;;EAED,QAAI,KAAKgB,MAAL,IAAerD,SAAnB,EAA8B;EAC5B;EACA,WAAKqD,MAAL,CAAYlD,KAAZ,CAAkBH,SAAlB,IAA+B,eAAa,EAAEkF,GAAG,GAAG,KAAK7C,SAAX,GAAuB,GAAzB,CAAb,QAAA,GAAgD,EAAE8C,GAAG,GAAG,KAAK/C,SAAX,GAAuB,GAAzB,CAAhD,OAA/B;EACD;;EAED,SAAKM,OAAL,GAAe,CAACwC,GAAD,EAAMC,GAAN,CAAf;EACD,GAXM;EAaP;;;;;;;;;;;;;;EAYO,mBAAA,GAAP;EACE,WAAO,KAAKzC,OAAZ;EACD,GAFM;EAIP;;;;;;;;;;;;EAUO,cAAA,GAAP;EACE,QAAI,KAAK0C,cAAT,EAAyB;EACvBC,MAAAA,aAAa,CAAC,KAAKD,cAAN,CAAb;EACA,WAAKA,cAAL,GAAsB,CAAC,CAAvB;EACD;EACF,GALM;EAOP;;;;;;;;;;;;;;;EAaO,cAAA,GAAP,UAAYE,EAAZ;EAAA,oBAAA;;UAAYC,qBAA0B;EAAEC,MAAAA,QAAQ,EAAE,OAAO,KAAKlD,WAAxB;EAAqCmD,MAAAA,SAAS,EAAE;EAAhD;UAAxBD,QAAQ;UAAEC,SAAS;;EAC/B,QAAI,CAAC,KAAKhC,GAAV,EAAe;EACb,WAAKK,qBAAL,GAA6B;EAAC0B,QAAAA,QAAQ,UAAT;EAAWC,QAAAA,SAAS;EAApB,OAA7B;EACA;EACD;;EAED,QAAI,KAAKL,cAAT,EAAyB;EACvBC,MAAAA,aAAa,CAAC,KAAKD,cAAN,CAAb;EACA,WAAKA,cAAL,GAAsB,CAAC,CAAvB;EACD;;EAED,QAAIjE,UAAU,GAAG,KAAKuE,aAAL,EAAjB;EACA,QAAIC,KAAK,GAAG,CAAZ;EACA,QAAIC,UAAU,GAAG,CAAjB;;EAEA,SAAKR,cAAL,GAAsBxG,MAAM,CAACiH,WAAP,CAAmB;EACvC1E,MAAAA,UAAU,IAAIe,KAAI,CAACI,WAAnB;;EACA,UAAMrB,MAAM,GAAGiB,KAAI,CAAC+C,QAAL,CAAc9D,UAAd,CAAf;;EAEAe,MAAAA,KAAI,CAAC0B,SAAL,CAAe3C,MAAM,CAAC,CAAD,CAArB,EAA0BA,MAAM,CAAC,CAAD,CAAhC;;EACAE,MAAAA,UAAU;;EAGV,UAAI,EAAEyE,UAAF,KAAiB1D,KAAI,CAACI,WAA1B,EAAuC;EACrCsD,QAAAA,UAAU,GAAG,CAAb;EACAD,QAAAA,KAAK;EACN;;EAED,UAAIF,SAAS,GAAG,CAAZ,IAAiBE,KAAK,KAAKF,SAA/B,EAA0C;EACxCJ,QAAAA,aAAa,CAACnD,KAAI,CAACkD,cAAN,CAAb;EACD;EACF,KAhBqB,EAgBnBI,QAhBmB,CAAtB;EAiBD,GAhCM;;EAkCA,kBAAA,GAAP,UAAgBrE,UAAhB;EACE,QAAMN,QAAQ,GAAG,KAAKwB,SAAtB;EACA,QAAMzB,QAAQ,GAAG,KAAKwB,SAAtB;;EAEA,QAAIjB,UAAU,GAAG,CAAjB,EAAoB;EAClB,aAAO,CAAC,CAAD,EAAI,CAAJ,CAAP;EACD,KAFD,MAEO,IAAIA,UAAU,IAAI,KAAKmB,WAAvB,EAAoC;EACzC,aAAO,CAACzB,QAAQ,GAAG,CAAZ,EAAeD,QAAQ,GAAG,CAA1B,CAAP;EACD;;EAED,QAAMsE,GAAG,GAAG/D,UAAU,GAAGN,QAAzB;EACA,QAAMsE,GAAG,GAAGtG,IAAI,CAACiH,KAAL,CAAW3E,UAAU,GAAGN,QAAxB,CAAZ;;EAGA,WAAO,CAACqE,GAAD,EAAMC,GAAN,CAAP;EACD,GAfM;;EAvQOvC,EAAAA,mBAAA,GAAU9E,OAAV;EAuRhB,oBAAA;EAAC,EAjUyBiI,UAA1B;;ECjDA,IAAMC,iBAAiB,GAAG,IAA1B;EAuBA;;;;;;EAKA;;;EAAyBnE,EAAAA,6BAAA;EAoBvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BA,qBAAA,CAAmBC,OAAnB,EAAyCC,OAAzC;EAAyC,0BAAA,EAAA;EAAAA,MAAAA,YAAA;;;EAAzC,gBACEC,WAAA,KAAA,SADF;;EAGEE,IAAAA,KAAI,CAACC,GAAL,GAAWL,OAAX;;EAEA,QAAMG,GAAG,gBAAOF,QAAhB;;EACA,QAAMlB,QAAQ,GAAGoB,GAAG,CAACpB,QAAJ,IAAgB,CAAjC;EACA,QAAMD,QAAQ,GAAGqB,GAAG,CAACrB,QAAJ,IAAgB,CAAjC;EAEAsB,IAAAA,KAAI,CAAC+D,MAAL,GAAehE,GAAG,CAACf,KAAJ,IAAa,CAA5B;EACAgB,IAAAA,KAAI,CAACgE,SAAL,GAAiBhE,KAAI,CAAC+D,MAAL,GAAcD,iBAA/B;EAEA9D,IAAAA,KAAI,CAACiE,WAAL,GAAmBtF,QAAQ,GAAGD,QAA9B;;EAGAsB,IAAAA,KAAI,CAACkE,QAAL,GAAgB,IAAIxD,WAAJ,CAAgBd,OAAhB,EAAyBG,GAAzB,EAA8BoE,EAA9B,CAAiC;EAC/C,cAAQ,UAAAC,GAAA;EACNpE,QAAAA,KAAI,CAACa,OAAL,CAAa,IAAIC,wBAAJ,CAAmB,MAAnB,EAA2BsD,GAA3B,CAAb;EACD,OAH8C;EAI/C,oBAAc,UAAAA,GAAA;EACZpE,QAAAA,KAAI,CAACa,OAAL,CAAa,IAAIC,wBAAJ,CAAmB,YAAnB,EAAiC;EAC5CrC,UAAAA,QAAQ,EAAE2F,GAAG,CAAC3F;EAD8B,SAAjC,CAAb;EAGD;EAR8C,KAAjC,CAAhB;;EAYAuB,IAAAA,KAAI,CAACqE,SAAL,GAAiB,IAAIC,aAAJ,CAAatE,KAAI,CAACC,GAAlB,EAAuB;EACtCjB,MAAAA,KAAK,EAAE,CAACgB,KAAI,CAACgE,SAAN,EAAiBhE,KAAI,CAACgE,SAAtB;EAD+B,KAAvB,CAAjB;EAGAhE,IAAAA,KAAI,CAACuE,KAAL,GAAa,IAAIC,IAAJ,CAAS;EACpBC,MAAAA,KAAK,EAAE;EACLC,QAAAA,KAAK,EAAE,CAAC,CAAD,EAAI,GAAJ,CADF;EAELC,QAAAA,QAAQ,EAAE;EAFL;EADa,KAAT,EAKVR,EALU,CAKP;EACJ,gBAAU,UAAAC,GAAA;EACR,YAAMQ,IAAI,GAAGjI,IAAI,CAACiH,KAAL,CAAWQ,GAAG,CAACS,GAAJ,CAAQJ,KAAR,IAAiB,MAAMzE,KAAI,CAACiE,WAA5B,CAAX,CAAb;EACA,YAAMhF,UAAU,GAAGe,KAAI,CAACiE,WAAL,GAAmBW,IAAnB,GAA0B,CAA7C;;EAEA5E,QAAAA,KAAI,CAACkE,QAAL,CAAczD,aAAd,CAA4BxB,UAA5B;;EAEAe,QAAAA,KAAI,CAACa,OAAL,CAAa,IAAIC,wBAAJ,CAAmB,QAAnB,EAA6B;EACxC7B,UAAAA,UAAU,YAD8B;EAExCF,UAAAA,MAAM,EAAEiB,KAAI,CAACkE,QAAL,CAAcY,SAAd,EAFgC;EAGxCL,UAAAA,KAAK,EAAEL,GAAG,CAACS,GAAJ,CAAQJ;EAHyB,SAA7B,CAAb;EAKD,OAZG;EAaJ,sBAAgB,UAAAL,GAAA;EACdpE,QAAAA,KAAI,CAACa,OAAL,CAAa,IAAIC,wBAAJ,CAAmB,cAAnB,EAAmC;EAC9CiE,UAAAA,SAAS,EAAEX,GAAG,CAACW;EAD+B,SAAnC,CAAb;EAGD;EAjBG,KALO,CAAb;;EAyBA/E,IAAAA,KAAI,CAACuE,KAAL,CAAWS,OAAX,CAAmB,OAAnB,EAA4BhF,KAAI,CAACqE,SAAjC;;;EACD;EAED;;;;;;;;;;;;;;EAUO,kBAAA,GAAP,UAAgBrF,KAAhB;EACE,QAAIiG,KAAK,CAACjG,KAAD,CAAL,IAAgBA,KAAK,GAAG,CAA5B,EAA+B;EAC7B,aAAO,IAAP;EACD;;EAED,SAAK+E,MAAL,GAAc/E,KAAd;EACA,SAAKgF,SAAL,GAAiBhF,KAAK,GAAG8E,iBAAzB;EACA,SAAKO,SAAL,CAAexE,OAAf,CAAuBb,KAAvB,GAA+B,CAAC,KAAKgF,SAAN,EAAiB,KAAKA,SAAtB,CAA/B;EAEA,WAAO,IAAP;EACD,GAVM;EAYP;;;;;;;;;;;EASO,kBAAA,GAAP;EACE,WAAO,KAAKD,MAAZ;EACD,GAFM;EAIP;;;;;;;;;;;;;;EAYO,gBAAA,GAAP,UAAcU,KAAd,EAAyBS,KAAzB;EAAc,wBAAA,EAAA;EAAAT,MAAAA,SAAA;;;EAAW,wBAAA,EAAA;EAAAS,MAAAA;EAASC,QAAAA,QAAQ,EAAE;SAAnB;;;EACvB,SAAKZ,KAAL,CAAWa,KAAX,CAAiB;EAACX,MAAAA,KAAK;EAAN,KAAjB,EAA0BS,KAAK,CAACC,QAAhC;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;;;;;;;EAYO,gBAAA,GAAP,UAAcV,KAAd,EAAyBS,KAAzB;EAAc,wBAAA,EAAA;EAAAT,MAAAA,SAAA;;;EAAW,wBAAA,EAAA;EAAAS,MAAAA;EAASC,QAAAA,QAAQ,EAAE;SAAnB;;;EACvB,SAAKZ,KAAL,CAAWc,KAAX,CAAiB;EAACZ,MAAAA,KAAK;EAAN,KAAjB,EAA0BS,KAAK,CAACC,QAAhC;;EACA,WAAO,IAAP;EACD,GAHM;EAKP;;;;;;;;EAMO,kBAAA,GAAP;EACE,WAAO,KAAKZ,KAAL,CAAWe,GAAX,GAAiBb,KAAjB,IAA0B,CAAjC;EACD,GAFM;EApLP;;;;;;;;;;EAQcc,EAAAA,kBAAA,GAAU3J,OAAV;EA+KhB,mBAAA;EAAC,EAxLwBiI,UAAzB;;ECpCA;MAQM2B,gBAAgB,GAAG;EACvBD,EAAAA,UAAU,YADa;EAEvB7E,EAAAA,WAAW,aAFY;EAGvB9E,EAAAA,OAAO;EAHgB;EAMzBC,KAAK,CAAC2J,gBAAD,EAAmBC,SAAnB,CAAL;;;;;;;;"} \ No newline at end of file diff --git a/dist/SpinViewer/view360.spinviewer.min.js b/dist/SpinViewer/view360.spinviewer.min.js new file mode 100644 index 000000000..d1860b0e7 --- /dev/null +++ b/dist/SpinViewer/view360.spinviewer.min.js @@ -0,0 +1,10 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@egjs/component"),require("@egjs/axes"),require("@egjs/agent")):"function"==typeof define&&define.amd?define(["@egjs/component","@egjs/axes","@egjs/agent"],e):((t="undefined"!=typeof globalThis?globalThis:t||self).eg=t.eg||{},t.eg.view360=e(t.eg.Component,t.eg.Axes,t.eg.agent))}(this,function(c,i,t){"use strict";var n="3.6.3",o=function(t,e){return(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)};function r(t,e){function n(){this.constructor=t}o(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var l=function(){return(l=Object.assign||function(t){for(var e,n=1,o=arguments.length;nthis._rowCount-1||t>this._colCount-1||(this._image&&g&&(this._image.style[g]="translate("+-(t/this._colCount)*100+"%, "+-(e/this._rowCount)*100+"%)"),this._colRow=[t,e])},t.getColRow=function(){return this._colRow},t.stop=function(){this._autoPlayTimer&&(clearInterval(this._autoPlayTimer),this._autoPlayTimer=-1)},t.play=function(t){var e,n,o,r=this,a=void 0===t?{interval:1e3/this._totalCount,playCount:0}:t,t=a.interval,i=a.playCount;this._bg?(this._autoPlayTimer&&(clearInterval(this._autoPlayTimer),this._autoPlayTimer=-1),e=this.getFrameIndex(),o=n=0,this._autoPlayTimer=window.setInterval(function(){e%=r._totalCount;var t=r.toColRow(e);r.setColRow(t[0],t[1]),e++,++o===r._totalCount&&(o=0,n++),0=this._totalCount?[e-1,n-1]:[t%e,Math.floor(t/e)]},u.VERSION=n,u}(c),e={SpinViewer:function(a){function t(t,e){void 0===e&&(e={});var n=a.call(this)||this;n._el=t;var o=l({},e),r=o.colCount||1,e=o.rowCount||1;return n._scale=o.scale||1,n._panScale=.21*n._scale,n._frameCount=r*e,n._sprites=new u(t,o).on({load:function(t){n.trigger(new c.ComponentEvent("load",t))},imageError:function(t){n.trigger(new c.ComponentEvent("imageError",{imageUrl:t.imageUrl}))}}),n._panInput=new i.PanInput(n._el,{scale:[n._panScale,n._panScale]}),n._axes=new i({angle:{range:[0,359],circular:!0}}).on({change:function(t){var e=Math.floor(t.pos.angle/(360/n._frameCount)),e=n._frameCount-e-1;n._sprites.setFrameIndex(e),n.trigger(new c.ComponentEvent("change",{frameIndex:e,colRow:n._sprites.getColRow(),angle:t.pos.angle}))},animationEnd:function(t){n.trigger(new c.ComponentEvent("animationEnd",{isTrusted:t.isTrusted}))}}),n._axes.connect("angle",n._panInput),n}r(t,a);var e=t.prototype;return e.setScale=function(t){return isNaN(t)||t<0||(this._scale=t,this._panScale=.21*t,this._panInput.options.scale=[this._panScale,this._panScale]),this},e.getScale=function(){return this._scale},e.spinBy=function(t,e){return void 0===t&&(t=0),void 0===e&&(e={duration:0}),this._axes.setBy({angle:t},e.duration),this},e.spinTo=function(t,e){return void 0===t&&(t=0),void 0===e&&(e={duration:0}),this._axes.setTo({angle:t},e.duration),this},e.getAngle=function(){return this._axes.get().angle||0},t.VERSION=n,t}(c),SpriteImage:u,VERSION:n};return function(o){for(var t=[],e=1;e(target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","import { SpinViewerOptions, SpinViewerEvent } from \"./SpinViewer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const SPINVIEWER_OPTIONS: { [key in keyof SpinViewerOptions]: true } = {\n imageUrl: true,\n rowCount: true,\n colCount: true,\n width: true,\n height: true,\n autoHeight: true,\n colRow: true,\n scale: true,\n frameIndex: true,\n wrapperClass: true,\n imageClass: true\n};\n\nexport const SPINVIEWER_EVENTS: {\n [key: string]: keyof SpinViewerEvent;\n} = {\n LOAD: \"load\",\n IMAGE_ERROR: \"imageError\",\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n};\n\nexport const DEFAULT_WRAPPER_CLASS = \"view360-wrapper\";\nexport const DEFAULT_IMAGE_CLASS = \"view360-image\";\n","import Component, { ComponentEvent } from \"@egjs/component\";\n\nimport { TRANSFORM, SUPPORT_WILLCHANGE } from \"../utils/browserFeature\";\nimport { VERSION } from \"../version\";\n\nimport { SpinViewerOptions } from \"./SpinViewer\";\nimport { DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS } from \"./consts\";\n\nexport interface SpriteImageEvent {\n /**\n * Events that occur when component loading is complete\n * @ko 컴포넌트 로딩이 완료되면 발생하는 이벤트\n * @name eg.view360.SpriteImage#load\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {HTMLElement} param.target The target element for which to display the image 이미지를 보여줄 대상 엘리먼트\n * @param {HTMLElement} param.bgElement Generated background image element 생성된 background 이미지 엘리먼트\n *\n * @example\n *\n * sprites.on({\n * \"load\" : function(evt) {\n * console.log(\"load event fired - e.target\", e.target, \"e.bgElement\", e.bgElement);\n * }\n * });\n */\n load: {\n target: HTMLElement;\n bgElement: HTMLDivElement;\n };\n /**\n * An event that occurs when the image index is changed by the user's left / right panning\n * @ko 사용자의 좌우 Panning 에 의해 이미지 인덱스가 변경되었을때 발생하는 이벤트\n * @name eg.view360.SpriteImage#imageError\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {String} param.imageUrl User-specified image URL 사용자가 지정한 이미지 URL\n *\n * @example\n *\n * sprites.on({\n * \"imageError\" : function(evt) {\n * // Error handling\n * console.log(e.imageUrl);\n * }\n * });\n */\n imageError: {\n imageUrl?: string;\n };\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpriteImage\n */\nclass SpriteImage extends Component {\n private static _createBgDiv(wrapperInContainer: HTMLDivElement | null, img: HTMLImageElement, rowCount: number, colCount: number, autoHeight: boolean) {\n const el = wrapperInContainer || document.createElement(\"div\");\n\n el.style.position = \"relative\";\n el.style.overflow = \"hidden\";\n\n img.style.position = \"absolute\";\n img.style.width = `${colCount * 100}%`;\n img.style.height = `${rowCount * 100}%`;\n\n /** Prevent image from being dragged on IE10, IE11, Safari especially */\n img.ondragstart = () => (false); // img.style.pointerEvents = \"none\";\n // Use hardware accelerator if available\n if (SUPPORT_WILLCHANGE) {\n (img.style.willChange = \"transform\");\n }\n\n el.appendChild(img);\n\n const unitWidth = img.naturalWidth / colCount;\n const unitHeight = img.naturalHeight / rowCount;\n\n if (autoHeight) {\n const r = unitHeight / unitWidth;\n\n el.style.paddingBottom = `${r * 100}%`;\n } else {\n el.style.height = \"100%\";\n }\n\n return el;\n }\n\n private static _getSizeString(size) {\n if (typeof size === \"number\") {\n return `${size}px`;\n }\n\n return size;\n }\n\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _rowCount: number;\n private _colCount: number;\n private _totalCount: number;\n private _width: number | string;\n private _height: number | string;\n private _autoHeight: boolean;\n private _colRow: number[];\n private _image: HTMLImageElement;\n private _bg: HTMLDivElement;\n private _autoPlayReservedInfo: { interval: number; playCount: number } | null;\n private _autoPlayTimer: number;\n\n /**\n * @class eg.view360.SpriteImage\n * @classdesc A module that displays a single or continuous image of any one of the \"sprite images\". SpinViewer internally uses SpriteImage to show each frame of the sprite image.\n * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다.\n * @extends eg.Component\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the \"Sprite image\". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n *\n * // Initialize SpriteImage\n *\n * var el = document.getElementById(\"image-div\");\n * var sprites = new eg.view360.SpriteImage(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24\n * });\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n const opt = options || {};\n\n this._el = element;\n this._rowCount = opt.rowCount || 1;\n this._colCount = opt.colCount || 1;\n this._totalCount = this._rowCount * this._colCount; // total frames\n this._width = opt.width || \"auto\";\n this._height = opt.height || \"auto\";\n this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten.\n this._colRow = [0, 0];\n\n if (opt.colRow) {\n this._colRow = opt.colRow;\n } else if (opt.frameIndex) {\n this.setFrameIndex(opt.frameIndex);\n }\n\n this._el.style.width = SpriteImage._getSizeString(this._width);\n this._el.style.height = SpriteImage._getSizeString(this._height);\n\n const wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS;\n const imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS;\n\n if (!opt.imageUrl) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n }, 0);\n return;\n }\n\n const imageInContainer = element.querySelector(`.${imageClass}`);\n const wrapperInContainer = element.querySelector(`.${wrapperClass}`);\n\n if (wrapperInContainer && imageInContainer) {\n // Set it to invisible to prevent wrapper being resized\n imageInContainer.style.display = \"none\";\n }\n\n this._image = imageInContainer || new Image();\n /**\n * Event\n */\n\n const image = this._image;\n\n image.onload = () => {\n if (wrapperInContainer && imageInContainer) {\n imageInContainer.style.display = \"\";\n }\n\n this._bg = SpriteImage._createBgDiv(\n wrapperInContainer,\n image,\n this._rowCount,\n this._colCount,\n this._autoHeight\n );\n this._el.appendChild(this._bg);\n this.setColRow(this._colRow[0], this._colRow[1]);\n\n this.trigger(new ComponentEvent(\"load\", {\n target: this._el,\n bgElement: this._bg\n }));\n\n if (this._autoPlayReservedInfo) {\n this.play(this._autoPlayReservedInfo);\n this._autoPlayReservedInfo = null;\n }\n };\n\n image.onerror = () => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n };\n\n image.src = opt.imageUrl;\n }\n\n /**\n * Specifies the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정\n * @method eg.view360.SpriteImage#setFrameIndex\n * @param {Number} frameIndex frame index of a frame프레임의 인덱스\n *\n * @example\n *\n * sprites.setFrameIndex(0, 1);// col = 0, row = 1\n */\n public setFrameIndex(index: number) {\n const colRow = this.toColRow(index);\n\n this.setColRow(colRow[0], colRow[1]);\n }\n\n /**\n * Returns the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환\n * @method eg.view360.SpriteImage#getFrameIndex\n * @return {Number} frame index frame 인덱스\n *\n * @example\n *\n * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1\n *\n */\n public getFrameIndex() {\n return this._colRow[1] * this._colCount + this._colRow[0];\n }\n\n /**\n * Specifies the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정\n * @method eg.view360.SpriteImage#setColRow\n * @param {Number} col Column number of a frame프레임의 행값\n * @param {Number} row Row number of a frame프레임의 열값\n *\n * @example\n *\n * sprites.setlColRow(1, 2); // col = 1, row = 2\n */\n public setColRow(col: number, row: number) {\n if (row > this._rowCount - 1 || col > this._colCount - 1) {\n return;\n }\n\n if (this._image && TRANSFORM) {\n // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser?\n this._image.style[TRANSFORM] = `translate(${-(col / this._colCount * 100)}%, ${-(row / this._rowCount * 100)}%)`;\n }\n\n this._colRow = [col, row];\n }\n\n /**\n * Returns the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환\n * @method eg.view360.SpriteImage#gelColRow\n * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열\n *\n * @example\n *\n * var colRow = sprites.getlColRow();\n * // colRow = [1, 2] - index of col is 1, index of row is 2\n *\n */\n public getColRow() {\n return this._colRow;\n }\n\n /**\n * Stop playing\n * @ko play 되고 있던 프레임 재생을 중지합니다.\n * @method eg.view360.SpriteImage#stop\n *\n * @example\n *\n * viewer.stop();\n *\n */\n public stop() {\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n }\n\n /**\n * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'.\n * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다.\n * @method eg.view360.SpriteImage#play\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위\n * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복\n *\n * @example\n *\n * viewer.play({angle: 16, playCount: 1});\n *\n */\n public play({ interval, playCount } = { interval: 1000 / this._totalCount, playCount: 0 }) {\n if (!this._bg) {\n this._autoPlayReservedInfo = {interval, playCount};\n return;\n }\n\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n\n let frameIndex = this.getFrameIndex();\n let count = 0;\n let frameCount = 0; // for checking 1 cycle\n\n this._autoPlayTimer = window.setInterval(() => {\n frameIndex %= this._totalCount;\n const colRow = this.toColRow(frameIndex);\n\n this.setColRow(colRow[0], colRow[1]);\n frameIndex++;\n\n // Done 1 Cycle?\n if (++frameCount === this._totalCount) {\n frameCount = 0;\n count++;\n }\n\n if (playCount > 0 && count === playCount) {\n clearInterval(this._autoPlayTimer);\n }\n }, interval);\n }\n\n public toColRow(frameIndex: number) {\n const colCount = this._colCount;\n const rowCount = this._rowCount;\n\n if (frameIndex < 0) {\n return [0, 0];\n } else if (frameIndex >= this._totalCount) {\n return [colCount - 1, rowCount - 1];\n }\n\n const col = frameIndex % colCount;\n const row = Math.floor(frameIndex / colCount);\n\n // console.log(frameIndex, col, row);\n return [col, row];\n }\n}\n\nexport default SpriteImage;\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { VERSION } from \"../version\";\nimport { merge } from \"../utils/utils\";\n\nimport SpinViewer from \"./SpinViewer\";\nimport SpriteImage from \"./SpriteImage\";\nimport * as Constants from \"./consts\";\n\nconst SpinViewerModule = {\n SpinViewer,\n SpriteImage,\n VERSION\n};\n\nmerge(SpinViewerModule, Constants);\n\nexport default SpinViewerModule;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport { VERSION } from \"../version\";\nimport { AnimationEndEvent, ChangeEvent, ImageErrorEvent, LoadEvent } from \"../types/event\";\n\nimport SpriteImage from \"./SpriteImage\";\n\nconst DEFAULT_PAN_SCALE = 0.21;\n\nexport interface SpinViewerEvent {\n load: LoadEvent;\n imageError: ImageErrorEvent;\n change: ChangeEvent;\n animationEnd: AnimationEndEvent;\n}\n\nexport interface SpinViewerOptions {\n imageUrl: string;\n rowCount: number;\n colCount: number;\n width: number | string;\n height: number | string;\n autoHeight: boolean;\n colRow: number[];\n scale: number;\n frameIndex: number;\n wrapperClass: string;\n imageClass: string;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpinViewer\n */\nclass SpinViewer extends Component {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @static\n * @example\n * eg.view360.SpinViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.SpinViewer\n */\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _sprites: SpriteImage;\n private _axes: Axes;\n private _panInput: PanInput;\n\n private _scale: number;\n private _panScale: number;\n private _frameCount: number;\n\n /**\n * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object.\n * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다.\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값\n * @param {String} [options.wrapperClass=\"view360-wrapper\"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @param {String} [options.imageClass=\"view360-image\"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n * ```\n * // Initialize SpinViewer\n * var el = document.getElementById(\"product-360\");\n * var viewer = new eg.view360.SpinViewer(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24 //required\n * });\n * ```\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n\n this._el = element;\n\n const opt = {...options};\n const colCount = opt.colCount || 1;\n const rowCount = opt.rowCount || 1;\n\n this._scale = (opt.scale || 1);\n this._panScale = this._scale * DEFAULT_PAN_SCALE;\n\n this._frameCount = colCount * rowCount;\n\n // Init SpriteImage\n this._sprites = new SpriteImage(element, opt).on({\n \"load\": evt => {\n this.trigger(new ComponentEvent(\"load\", evt));\n },\n \"imageError\": evt => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: evt.imageUrl\n }));\n }\n });\n\n // Init Axes\n this._panInput = new PanInput(this._el, {\n scale: [this._panScale, this._panScale]\n });\n this._axes = new Axes({\n angle: {\n range: [0, 359],\n circular: true\n }\n }).on({\n \"change\": evt => {\n const curr = Math.floor(evt.pos.angle / (360 / this._frameCount));\n const frameIndex = this._frameCount - curr - 1;\n\n this._sprites.setFrameIndex(frameIndex);\n\n this.trigger(new ComponentEvent(\"change\", {\n frameIndex,\n colRow: this._sprites.getColRow(),\n angle: evt.pos.angle\n }));\n },\n \"animationEnd\": evt => {\n this.trigger(new ComponentEvent(\"animationEnd\", {\n isTrusted: evt.isTrusted\n }));\n }\n });\n\n this._axes.connect(\"angle\", this._panInput);\n }\n\n /**\n * Set spin scale\n * @ko scale 을 조정할 수 있는 함수\n * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.setScale(2);// It moves twice as much.\n */\n public setScale(scale: number) {\n if (isNaN(scale) || scale < 0) {\n return this;\n }\n\n this._scale = scale;\n this._panScale = scale * DEFAULT_PAN_SCALE;\n this._panInput.options.scale = [this._panScale, this._panScale];\n\n return this;\n }\n\n /**\n * Get spin scale\n * @ko scale 값을 반환한다.\n *\n * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @example\n * viewer.getScale();// It returns number\n */\n public getScale() {\n return this._scale;\n }\n\n /**\n * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle.\n * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle상대적 회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinBy(720, {duration: 500});\n */\n public spinBy(angle = 0, param = {duration: 0}) {\n this._axes.setBy({angle}, param.duration);\n return this;\n }\n\n /**\n * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle).\n * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinTo(30, {duration:100});\n */\n public spinTo(angle = 0, param = {duration: 0}) {\n this._axes.setTo({angle}, param.duration);\n return this;\n }\n\n /**\n * Returns current angles\n * @ko 현재 각도를 반환한다.\n *\n * @return {Number} Current angle 현재 각도\n */\n public getAngle() {\n return this._axes.get().angle || 0;\n }\n}\n\nexport default SpinViewer;\n"],"names":["VERSION","win","window","Math","self","Function","doc","document","agent","navigator","getAgent","os","name","browser","Float32Array","Array","getComputedStyle","userAgent","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","target","i","len","length","SUPPORT_WILLCHANGE","CSS","supports","DEFAULT_WRAPPER_CLASS","DEFAULT_IMAGE_CLASS","imageUrl","rowCount","colCount","width","height","autoHeight","colRow","scale","frameIndex","wrapperClass","imageClass","LOAD","IMAGE_ERROR","CHANGE","ANIMATION_END","element","options","_super","opt","_this","_el","_rowCount","_colCount","_totalCount","_width","_height","_autoHeight","_colRow","setFrameIndex","SpriteImage","_getSizeString","setTimeout","trigger","ComponentEvent","imageInContainer","querySelector","wrapperInContainer","display","_image","Image","image","onload","_bg","_createBgDiv","appendChild","setColRow","bgElement","_autoPlayReservedInfo","play","onerror","src","__extends","img","el","createElement","position","overflow","ondragstart","willChange","unitWidth","naturalWidth","unitHeight","naturalHeight","r","paddingBottom","size","index","this","toColRow","col","row","_autoPlayTimer","clearInterval","_a","count","frameCount","_b","interval","playCount","getFrameIndex","setInterval","floor","Component","SpinViewerModule","SpinViewer","_scale","_panScale","_frameCount","_sprites","on","evt","_panInput","PanInput","_axes","Axes","angle","range","circular","curr","pos","getColRow","isTrusted","connect","isNaN","param","duration","setBy","setTo","get","_i","srcs","forEach","source","Object","keys","key","value","isArray","merge","Constants"],"mappings":"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"} \ No newline at end of file diff --git a/dist/SpinViewer/view360.spinviewer.pkgd.js b/dist/SpinViewer/view360.spinviewer.pkgd.js new file mode 100644 index 000000000..6d7f27132 --- /dev/null +++ b/dist/SpinViewer/view360.spinviewer.pkgd.js @@ -0,0 +1,4655 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.eg = global.eg || {}, global.eg.view360 = factory())); +}(this, (function () { 'use strict'; + + var VERSION = "3.6.3"; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); + }; + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + + return ar; + } + + var merge = function (target) { + var srcs = []; + + for (var _i = 1; _i < arguments.length; _i++) { + srcs[_i - 1] = arguments[_i]; + } + + srcs.forEach(function (source) { + Object.keys(source).forEach(function (key) { + var value = source[key]; + + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = __spread(target[key], value); + } else { + target[key] = value; + } + }); + }); + return target; + }; + + /* + Copyright (c) NAVER Corp. + name: @egjs/component + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-component + version: 3.0.1 + */ + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read$1(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread$1() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read$1(arguments[i])); + + return ar; + } + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + var isUndefined = function (value) { + return typeof value === "undefined"; + }; + + /** + * Event class to provide additional properties + * @ko Component에서 추가적인 프로퍼티를 제공하는 이벤트 클래스 + */ + + var ComponentEvent = + /*#__PURE__*/ + function () { + /** + * Create a new instance of ComponentEvent. + * @ko ComponentEvent의 새로운 인스턴스를 생성한다. + * @param eventType The name of the event.이벤트 이름. + * @param props An object that contains additional event properties.추가적인 이벤트 프로퍼티 오브젝트. + */ + function ComponentEvent(eventType, props) { + var e_1, _a; + + this.eventType = eventType; + this._canceled = false; + if (!props) return; + + try { + for (var _b = __values(Object.keys(props)), _c = _b.next(); !_c.done; _c = _b.next()) { + var key = _c.value; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + + this[key] = props[key]; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + } + /** + * Stop the event. {@link ComponentEvent#isCanceled} will return `true` after. + * @ko 이벤트를 중단한다. 이후 {@link ComponentEvent#isCanceled}가 `true`를 반환한다. + */ + + + var __proto = ComponentEvent.prototype; + + __proto.stop = function () { + this._canceled = true; + }; + /** + * Returns a boolean value that indicates whether {@link ComponentEvent#stop} is called before. + * @ko {@link ComponentEvent#stop}이 호출되었는지 여부를 반환한다. + * @return {boolean} A boolean value that indicates whether {@link ComponentEvent#stop} is called before.이전에 {@link ComponentEvent#stop}이 불려졌는지 여부를 반환한다. + */ + + + __proto.isCanceled = function () { + return this._canceled; + }; + + return ComponentEvent; + }(); + + /** + * A class used to manage events in a component + * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스 + */ + + var Component = + /*#__PURE__*/ + function () { + /** + * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"} + */ + function Component() { + this._eventHandler = {}; + } + /** + * Trigger a custom event. + * @ko 커스텀 이벤트를 발생시킨다 + * @param {string | ComponentEvent} event The name of the custom event to be triggered or an instance of the ComponentEvent발생할 커스텀 이벤트의 이름 또는 ComponentEvent의 인스턴스 + * @param {any[]} params Event data to be sent when triggering a custom event 커스텀 이벤트가 발생할 때 전달할 데이터 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * beforeHi: ComponentEvent<{ foo: number; bar: string }>; + * hi: { foo: { a: number; b: boolean } }; + * someEvent: (foo: number, bar: string) => void; + * someOtherEvent: void; // When there's no event argument + * }> { + * some(){ + * if(this.trigger("beforeHi")){ // When event call to stop return false. + * this.trigger("hi");// fire hi event. + * } + * } + * } + * + * const some = new Some(); + * some.on("beforeHi", e => { + * if(condition){ + * e.stop(); // When event call to stop, `hi` event not call. + * } + * // `currentTarget` is component instance. + * console.log(some === e.currentTarget); // true + * + * typeof e.foo; // number + * typeof e.bar; // string + * }); + * some.on("hi", e => { + * typeof e.foo.b; // boolean + * }); + * // If you want to more know event design. You can see article. + * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F + * ``` + */ + + + var __proto = Component.prototype; + + __proto.trigger = function (event) { + var params = []; + + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + + var eventName = event instanceof ComponentEvent ? event.eventType : event; + + var handlers = __spread$1(this._eventHandler[eventName] || []); + + if (handlers.length <= 0) { + return this; + } + + if (event instanceof ComponentEvent) { + event.currentTarget = this; + handlers.forEach(function (handler) { + handler(event); + }); + } else { + handlers.forEach(function (handler) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + handler.apply(void 0, __spread$1(params)); + }); + } + + return this; + }; + /** + * Executed event just one time. + * @ko 이벤트가 한번만 실행된다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: ComponentEvent; + * }> { + * hi() { + * alert("hi"); + * } + * thing() { + * this.once("hi", this.hi); + * } + * } + * + * var some = new Some(); + * some.thing(); + * some.trigger(new ComponentEvent("hi")); + * // fire alert("hi"); + * some.trigger(new ComponentEvent("hi")); + * // Nothing happens + * ``` + */ + + + __proto.once = function (eventName, handlerToAttach) { + var _this = this; + + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + + for (var key in eventHash) { + this.once(key, eventHash[key]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var listener_1 = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } // eslint-disable-next-line @typescript-eslint/no-unsafe-call + + + handlerToAttach.apply(void 0, __spread$1(args)); + + _this.off(eventName, listener_1); + }; + + this.on(eventName, listener_1); + } + + return this; + }; + /** + * Checks whether an event has been attached to a component. + * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다. + * @param {string} eventName The name of the event to be attached 등록 여부를 확인할 이벤트의 이름 + * @return {boolean} Indicates whether the event is attached. 이벤트 등록 여부 + * @example + * ```ts + * import Component from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * some() { + * this.hasOn("hi");// check hi event. + * } + * } + * ``` + */ + + + __proto.hasOn = function (eventName) { + return !!this._eventHandler[eventName]; + }; + /** + * Attaches an event to a component. + * @ko 컴포넌트에 이벤트를 등록한다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.on("hi",this.hi); //attach event + * } + * } + * ``` + */ + + + __proto.on = function (eventName, handlerToAttach) { + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + + for (var name in eventHash) { + this.on(name, eventHash[name]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var handlerList = this._eventHandler[eventName]; + + if (isUndefined(handlerList)) { + this._eventHandler[eventName] = []; + handlerList = this._eventHandler[eventName]; + } + + handlerList.push(handlerToAttach); + } + + return this; + }; + /** + * Detaches an event from the component.
If the `eventName` is not given this will detach all event handlers attached.
If the `handlerToDetach` is not given, this will detach all event handlers for `eventName`. + * @ko 컴포넌트에 등록된 이벤트를 해제한다.
`eventName`이 주어지지 않았을 경우 모든 이벤트 핸들러를 제거한다.
`handlerToAttach`가 주어지지 않았을 경우 `eventName`에 해당하는 모든 이벤트 핸들러를 제거한다. + * @param {string?} eventName The name of the event to be detached 해제할 이벤트의 이름 + * @param {function?} handlerToDetach The handler function of the event to be detached 해제할 이벤트의 핸들러 함수 + * @return An instance of a component itself 컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.off("hi",this.hi); //detach event + * } + * } + * ``` + */ + + + __proto.off = function (eventName, handlerToDetach) { + var e_1, _a; // Detach all event handlers. + + + if (isUndefined(eventName)) { + this._eventHandler = {}; + return this; + } // Detach all handlers for eventname or detach event handlers by object. + + + if (isUndefined(handlerToDetach)) { + if (typeof eventName === "string") { + delete this._eventHandler[eventName]; + return this; + } else { + var eventHash = eventName; + + for (var name in eventHash) { + this.off(name, eventHash[name]); + } + + return this; + } + } // Detach single event handler + + + var handlerList = this._eventHandler[eventName]; + + if (handlerList) { + var idx = 0; + + try { + for (var handlerList_1 = __values(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) { + var handlerFunction = handlerList_1_1.value; + + if (handlerFunction === handlerToDetach) { + handlerList.splice(idx, 1); + + if (handlerList.length <= 0) { + delete this._eventHandler[eventName]; + } + + break; + } + + idx++; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1); + } finally { + if (e_1) throw e_1.error; + } + } + } + + return this; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @example + * Component.VERSION; // ex) 3.0.0 + * @memberof Component + */ + + + Component.VERSION = "3.0.1"; + return Component; + }(); + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + var ComponentEvent$1 = ComponentEvent; + + /* + Copyright (c) 2015 NAVER Corp. + name: @egjs/agent + license: MIT + author: NAVER Corp. + repository: git+https://github.com/naver/agent.git + version: 2.2.1 + */ + function some(arr, callback) { + var length = arr.length; + + for (var i = 0; i < length; ++i) { + if (callback(arr[i], i)) { + return true; + } + } + + return false; + } + function find(arr, callback) { + var length = arr.length; + + for (var i = 0; i < length; ++i) { + if (callback(arr[i], i)) { + return arr[i]; + } + } + + return null; + } + function getUserAgent(agent) { + var userAgent = agent; + + if (typeof userAgent === "undefined") { + if (typeof navigator === "undefined" || !navigator) { + return ""; + } + + userAgent = navigator.userAgent || ""; + } + + return userAgent.toLowerCase(); + } + function execRegExp(pattern, text) { + try { + return new RegExp(pattern, "g").exec(text); + } catch (e) { + return null; + } + } + function hasUserAgentData() { + if (typeof navigator === "undefined" || !navigator || !navigator.userAgentData) { + return false; + } + + var userAgentData = navigator.userAgentData; + var brands = userAgentData.brands || userAgentData.uaList; + return !!(brands && brands.length); + } + function findVersion(versionTest, userAgent) { + var result = execRegExp("(" + versionTest + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent); + return result ? result[3] : ""; + } + function convertVersion(text) { + return text.replace(/_/g, "."); + } + function findPreset(presets, userAgent) { + var userPreset = null; + var version = "-1"; + some(presets, function (preset) { + var result = execRegExp("(" + preset.test + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent); + + if (!result || preset.brand) { + return false; + } + + userPreset = preset; + version = result[3] || "-1"; + + if (preset.versionAlias) { + version = preset.versionAlias; + } else if (preset.versionTest) { + version = findVersion(preset.versionTest.toLowerCase(), userAgent) || version; + } + + version = convertVersion(version); + return true; + }); + return { + preset: userPreset, + version: version + }; + } + function findBrand(brands, preset) { + return find(brands, function (_a) { + var brand = _a.brand; + return execRegExp("" + preset.test, brand.toLowerCase()); + }); + } + + var BROWSER_PRESETS = [{ + test: "phantomjs", + id: "phantomjs" + }, { + test: "whale", + id: "whale" + }, { + test: "edgios|edge|edg", + id: "edge" + }, { + test: "msie|trident|windows phone", + id: "ie", + versionTest: "iemobile|msie|rv" + }, { + test: "miuibrowser", + id: "miui browser" + }, { + test: "samsungbrowser", + id: "samsung internet" + }, { + test: "samsung", + id: "samsung internet", + versionTest: "version" + }, { + test: "chrome|crios", + id: "chrome" + }, { + test: "firefox|fxios", + id: "firefox" + }, { + test: "android", + id: "android browser", + versionTest: "version" + }, { + test: "safari|iphone|ipad|ipod", + id: "safari", + versionTest: "version" + }]; // chromium's engine(blink) is based on applewebkit 537.36. + + var CHROMIUM_PRESETS = [{ + test: "(?=.*applewebkit/(53[0-7]|5[0-2]|[0-4]))(?=.*\\schrome)", + id: "chrome" + }, { + test: "chromium", + id: "chrome" + }, { + test: "whale", + id: "chrome", + brand: true + }]; + var WEBKIT_PRESETS = [{ + test: "applewebkit", + id: "webkit" + }]; + var WEBVIEW_PRESETS = [{ + test: "(?=(iphone|ipad))(?!(.*version))", + id: "webview" + }, { + test: "(?=(android|iphone|ipad))(?=.*(naver|daum|; wv))", + id: "webview" + }, { + // test webview + test: "webview", + id: "webview" + }]; + var OS_PRESETS = [{ + test: "windows phone", + id: "windows phone" + }, { + test: "windows 2000", + id: "window", + versionAlias: "5.0" + }, { + test: "windows nt", + id: "window" + }, { + test: "iphone|ipad|ipod", + id: "ios", + versionTest: "iphone os|cpu os" + }, { + test: "mac os x", + id: "mac" + }, { + test: "android", + id: "android" + }, { + test: "tizen", + id: "tizen" + }, { + test: "webos|web0s", + id: "webos" + }]; + + function parseUserAgentData(osData) { + var userAgentData = navigator.userAgentData; + var brands = (userAgentData.uaList || userAgentData.brands).slice(); + var isMobile = userAgentData.mobile || false; + var firstBrand = brands[0]; + var browser = { + name: firstBrand.brand, + version: firstBrand.version, + majorVersion: -1, + webkit: false, + webview: some(WEBVIEW_PRESETS, function (preset) { + return findBrand(brands, preset); + }), + chromium: some(CHROMIUM_PRESETS, function (preset) { + return findBrand(brands, preset); + }) + }; + var os = { + name: "unknown", + version: "-1", + majorVersion: -1 + }; + browser.webkit = !browser.chromium && some(WEBKIT_PRESETS, function (preset) { + return findBrand(brands, preset); + }); + + if (osData) { + var platform_1 = osData.platform.toLowerCase(); + var result = find(OS_PRESETS, function (preset) { + return new RegExp("" + preset.test, "g").exec(platform_1); + }); + os.name = result ? result.id : platform_1; + os.version = osData.platformVersion; + } + + some(BROWSER_PRESETS, function (preset) { + var result = findBrand(brands, preset); + + if (!result) { + return false; + } + + browser.name = preset.id; + browser.version = osData ? osData.uaFullVersion : result.version; + return true; + }); + + if (navigator.platform === "Linux armv8l") { + os.name = "android"; + } else if (browser.webkit) { + os.name = isMobile ? "ios" : "mac"; + } + + if (os.name === "ios" && browser.webview) { + browser.version = "-1"; + } + + os.version = convertVersion(os.version); + browser.version = convertVersion(browser.version); + os.majorVersion = parseInt(os.version, 10); + browser.majorVersion = parseInt(browser.version, 10); + return { + browser: browser, + os: os, + isMobile: isMobile, + isHints: true + }; + } + + function parseUserAgent(userAgent) { + var nextAgent = getUserAgent(userAgent); + var isMobile = !!/mobi/g.exec(nextAgent); + var browser = { + name: "unknown", + version: "-1", + majorVersion: -1, + webview: !!findPreset(WEBVIEW_PRESETS, nextAgent).preset, + chromium: !!findPreset(CHROMIUM_PRESETS, nextAgent).preset, + webkit: false + }; + var os = { + name: "unknown", + version: "-1", + majorVersion: -1 + }; + + var _a = findPreset(BROWSER_PRESETS, nextAgent), + browserPreset = _a.preset, + browserVersion = _a.version; + + var _b = findPreset(OS_PRESETS, nextAgent), + osPreset = _b.preset, + osVersion = _b.version; + + browser.webkit = !browser.chromium && !!findPreset(WEBKIT_PRESETS, nextAgent).preset; + + if (osPreset) { + os.name = osPreset.id; + os.version = osVersion; + os.majorVersion = parseInt(osVersion, 10); + } + + if (browserPreset) { + browser.name = browserPreset.id; + browser.version = browserVersion; + + if (browser.webview && os.name === "ios" && browser.name !== "safari") { + browser.webview = false; + } + } + + browser.majorVersion = parseInt(browser.version, 10); + return { + browser: browser, + os: os, + isMobile: isMobile, + isHints: false + }; + } + /** + * Extracts browser and operating system information from the user agent string. + * @ko 유저 에이전트 문자열에서 브라우저와 운영체제 정보를 추출한다. + * @function eg.agent#agent + * @param - user agent string to parse 파싱할 유저에이전트 문자열 + * @return - agent Info 에이전트 정보 + * @example + import agent from "@egjs/agent"; + // eg.agent(); + const { os, browser, isMobile } = agent(); + */ + + function agent(userAgent) { + if (typeof userAgent === "undefined" && hasUserAgentData()) { + return parseUserAgentData(); + } else { + return parseUserAgent(userAgent); + } + } + + /* + Copyright (c) 2015 NAVER Corp. + name: @egjs/axes + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-axes + version: 3.3.0 + */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics$1 = function (d, b) { + extendStatics$1 = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics$1(d, b); + }; + + function __extends$1(d, b) { + extendStatics$1(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign$1 = function () { + __assign$1 = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign$1.apply(this, arguments); + }; + + /* eslint-disable no-new-func, no-nested-ternary */ + var win; + + if (typeof window === "undefined") { + // window is undefined in node.js + win = { + navigator: { + userAgent: "" + } + }; + } else { + win = window; + } + + var DIRECTION_NONE = 1; + var DIRECTION_LEFT = 2; + var DIRECTION_RIGHT = 4; + var DIRECTION_HORIZONTAL = 2 | 4; + var DIRECTION_UP = 8; + var DIRECTION_DOWN = 16; + var DIRECTION_VERTICAL = 8 | 16; + var DIRECTION_ALL = 2 | 4 | 8 | 16; + var MOUSE_LEFT = "left"; + var MOUSE_RIGHT = "right"; + var MOUSE_MIDDLE = "middle"; + var VELOCITY_INTERVAL = 16; + var IOS_EDGE_THRESHOLD = 30; + var IS_IOS_SAFARI = "ontouchstart" in win && agent().browser.name === "safari"; + var TRANSFORM = function () { + if (typeof document === "undefined") { + return ""; + } + + var bodyStyle = (document.head || document.getElementsByTagName("head")[0]).style; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in bodyStyle) { + return target[i]; + } + } + + return ""; + }(); + var PREVENT_DRAG_CSSPROPS = { + "user-select": "none", + "-webkit-user-drag": "none" + }; + + var toArray = function (nodes) { + // const el = Array.prototype.slice.call(nodes); + // for IE8 + var el = []; + + for (var i = 0, len = nodes.length; i < len; i++) { + el.push(nodes[i]); + } + + return el; + }; + var $ = function (param, multi) { + if (multi === void 0) { + multi = false; + } + + var el; + + if (typeof param === "string") { + // String (HTML, Selector) + // check if string is HTML tag format + var match = param.match(/^<([a-z]+)\s*([^>]*)>/); // creating element + + if (match) { + // HTML + var dummy = document.createElement("div"); + dummy.innerHTML = param; + el = toArray(dummy.childNodes); + } else { + // Selector + el = toArray(document.querySelectorAll(param)); + } + + if (!multi) { + el = el.length >= 1 ? el[0] : undefined; + } + } else if (param === win) { + // window + el = param; + } else if (param.nodeName && (param.nodeType === 1 || param.nodeType === 9)) { + // HTMLElement, Document + el = param; + } else if ("jQuery" in win && param instanceof jQuery || param.constructor.prototype.jquery) { + // jQuery + el = multi ? param.toArray() : param.get(0); + } else if (Array.isArray(param)) { + el = param.map(function (v) { + return $(v); + }); + + if (!multi) { + el = el.length >= 1 ? el[0] : undefined; + } + } + + return el; + }; + var raf = win.requestAnimationFrame || win.webkitRequestAnimationFrame; + var caf = win.cancelAnimationFrame || win.webkitCancelAnimationFrame; + + if (raf && !caf) { + var keyInfo_1 = {}; + var oldraf_1 = raf; + + raf = function (callback) { + var wrapCallback = function (timestamp) { + if (keyInfo_1[key]) { + callback(timestamp); + } + }; + + var key = oldraf_1(wrapCallback); + keyInfo_1[key] = true; + return key; + }; + + caf = function (key) { + delete keyInfo_1[key]; + }; + } else if (!(raf && caf)) { + raf = function (callback) { + return win.setTimeout(function () { + callback(win.performance && win.performance.now && win.performance.now() || new Date().getTime()); + }, 16); + }; + + caf = win.clearTimeout; + } + /** + * A polyfill for the window.requestAnimationFrame() method. + * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame + * @private + */ + + + var requestAnimationFrame = function (fp) { + return raf(fp); + }; + /** + * A polyfill for the window.cancelAnimationFrame() method. It cancels an animation executed through a call to the requestAnimationFrame() method. + * @param {Number} key − The ID value returned through a call to the requestAnimationFrame() method. requestAnimationFrame() 메서드가 반환한 아이디 값 + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame + * @private + */ + + var cancelAnimationFrame = function (key) { + caf(key); + }; + var map = function (obj, callback) { + var tranformed = {}; + + for (var k in obj) { + if (k) { + tranformed[k] = callback(obj[k], k); + } + } + + return tranformed; + }; + var filter = function (obj, callback) { + var filtered = {}; + + for (var k in obj) { + if (k && callback(obj[k], k)) { + filtered[k] = obj[k]; + } + } + + return filtered; + }; + var every = function (obj, callback) { + for (var k in obj) { + if (k && !callback(obj[k], k)) { + return false; + } + } + + return true; + }; + var equal = function (target, base) { + return every(target, function (v, k) { + return v === base[k]; + }); + }; + var roundNumFunc = {}; + var roundNumber = function (num, roundUnit) { + // Cache for performance + if (!roundNumFunc[roundUnit]) { + roundNumFunc[roundUnit] = getRoundFunc(roundUnit); + } + + return roundNumFunc[roundUnit](num); + }; + var roundNumbers = function (num, roundUnit) { + if (!num || !roundUnit) { + return num; + } + + return map(num, function (value, key) { + return roundNumber(value, typeof roundUnit === "number" ? roundUnit : roundUnit[key]); + }); + }; + var getDecimalPlace = function (val) { + if (!isFinite(val)) { + return 0; + } + + var v = "" + val; + + if (v.indexOf("e") >= 0) { + // Exponential Format + // 1e-10, 1e-12 + var p = 0; + var e = 1; + + while (Math.round(val * e) / e !== val) { + e *= 10; + p++; + } + + return p; + } // In general, following has performance benefit. + // https://jsperf.com/precision-calculation + + + return v.indexOf(".") >= 0 ? v.length - v.indexOf(".") - 1 : 0; + }; + var inversePow = function (n) { + // replace Math.pow(10, -n) to solve floating point issue. + // eg. Math.pow(10, -4) => 0.00009999999999999999 + return 1 / Math.pow(10, n); + }; + var getRoundFunc = function (v) { + var p = v < 1 ? Math.pow(10, getDecimalPlace(v)) : 1; + return function (n) { + if (v === 0) { + return 0; + } + + return Math.round(Math.round(n / v) * v * p) / p; + }; + }; + var getAngle = function (posX, posY) { + return Math.atan2(posY, posX) * 180 / Math.PI; + }; + var isCssPropsFromAxes = function (originalCssProps) { + var same = true; + Object.keys(PREVENT_DRAG_CSSPROPS).forEach(function (prop) { + if (!originalCssProps || originalCssProps[prop] !== PREVENT_DRAG_CSSPROPS[prop]) { + same = false; + } + }); + return same; + }; + var setCssProps = function (element, option, direction) { + var _a; + + var touchActionMap = (_a = {}, _a[DIRECTION_NONE] = "auto", _a[DIRECTION_ALL] = "none", _a[DIRECTION_VERTICAL] = "pan-x", _a[DIRECTION_HORIZONTAL] = "pan-y", _a); + var oldCssProps = {}; + + if (element && element.style) { + var touchAction = option.touchAction ? option.touchAction : touchActionMap[direction]; + + var newCssProps_1 = __assign$1(__assign$1({}, PREVENT_DRAG_CSSPROPS), { + "touch-action": element.style["touch-action"] === "none" ? "none" : touchAction + }); + + Object.keys(newCssProps_1).forEach(function (prop) { + oldCssProps[prop] = element.style[prop]; + element.style[prop] = newCssProps_1[prop]; + }); + } + + return oldCssProps; + }; + var revertCssProps = function (element, originalCssProps) { + if (element && element.style && originalCssProps) { + Object.keys(originalCssProps).forEach(function (prop) { + element.style[prop] = originalCssProps[prop]; + }); + } + + return; + }; + + var EventManager = + /*#__PURE__*/ + function () { + function EventManager(_axes) { + this._axes = _axes; + } + /** + * This event is fired when a user holds an element on the screen of the device. + * @ko 사용자가 기기의 화면에 손을 대고 있을 때 발생하는 이벤트 + * @event Axes#hold + * @type {object} + * @property {Object.} pos coordinate 좌표 정보 + * @property {Object} input The instance of inputType where the event occurred이벤트가 발생한 inputType 인스턴스 + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("hold", function(event) { + * // event.pos + * // event.input + * // event.inputEvent + * // isTrusted + * }); + * ``` + */ + + + var __proto = EventManager.prototype; + + __proto.hold = function (pos, option) { + var roundPos = this._getRoundPos(pos).roundPos; + + this._axes.trigger(new ComponentEvent$1("hold", { + pos: roundPos, + input: option.input || null, + inputEvent: option.event || null, + isTrusted: true + })); + }; + /** + * Specifies the coordinates to move after the 'change' event. It works when the holding value of the change event is true. + * @ko 'change' 이벤트 이후 이동할 좌표를 지정한다. change이벤트의 holding 값이 true일 경우에 동작한다 + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("change", function(event) { + * event.holding && event.set({x: 10}); + * }); + * ``` + */ + + /** Specifies the animation coordinates to move after the 'release' or 'animationStart' events. + * @ko 'release' 또는 'animationStart' 이벤트 이후 이동할 좌표를 지정한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("animationStart", function(event) { + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + /** + * This event is fired when a user release an element on the screen of the device. + * @ko 사용자가 기기의 화면에서 손을 뗐을 때 발생하는 이벤트 + * @event Axes#release + * @type {object} + * @property {Object.} depaPos The coordinates when releasing an element손을 뗐을 때의 좌표 + * @property {Object.} destPos The coordinates to move to after releasing an element손을 뗀 뒤에 이동할 좌표 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Object.} bounceRatio If the coordinates at the time of release are in the bounce area, the current bounce value divided by the maximum bounce value 손을 뗐을 때의 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치. + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {Object} input The instance of inputType where the event occurred이벤트가 발생한 inputType 인스턴스 + * @property {setTo} setTo Specifies the animation coordinates to move after the event 이벤트 이후 이동할 애니메이션 좌표를 지정한다 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("release", function(event) { + * // event.depaPos + * // event.destPos + * // event.delta + * // event.input + * // event.inputEvent + * // event.setTo + * // event.isTrusted + * + * // if you want to change the animation coordinates to move after the 'release' event. + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + + __proto.triggerRelease = function (param) { + var _a = this._getRoundPos(param.destPos, param.depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + param.destPos = roundPos; + param.depaPos = roundDepa; + param.setTo = this._createUserControll(param.destPos, param.duration); + + this._axes.trigger(new ComponentEvent$1("release", __assign$1(__assign$1({}, param), { + bounceRatio: this._getBounceRatio(roundPos) + }))); + }; + /** + * This event is fired when coordinate changes. + * @ko 좌표가 변경됐을 때 발생하는 이벤트 + * @event Axes#change + * @type {object} + * @property {Object.} pos The coordinate 좌표 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Object.} bounceRatio If the current coordinates are in the bounce area, the current bounce value divided by the maximum bounce value 현재 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치. + * @property {Boolean} holding Indicates whether a user holds an element on the screen of the device.사용자가 기기의 화면을 누르고 있는지 여부 + * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {Object} inputEvent The event object received from inputType. If the value is changed by animation, it returns 'null'.inputType으로 부터 받은 이벤트 객체. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {set} set Specifies the coordinates to move after the event. It works when the holding value is true 이벤트 이후 이동할 좌표를 지정한다. holding 값이 true일 경우에 동작한다. + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("change", function(event) { + * // event.pos + * // event.delta + * // event.input + * // event.inputEvent + * // event.holding + * // event.set + * // event.isTrusted + * + * // if you want to change the coordinates to move after the 'change' event. + * // it works when the holding value of the change event is true. + * event.holding && event.set({x: 10}); + * }); + * ``` + */ + + + __proto.triggerChange = function (pos, depaPos, option, holding) { + if (holding === void 0) { + holding = false; + } + + var animationManager = this.animationManager; + var axisManager = animationManager.axisManager; + var eventInfo = animationManager.getEventInfo(); + + var _a = this._getRoundPos(pos, depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + var moveTo = axisManager.moveTo(roundPos, roundDepa); + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.event) || null; + var param = { + pos: moveTo.pos, + delta: moveTo.delta, + bounceRatio: this._getBounceRatio(moveTo.pos), + holding: holding, + inputEvent: inputEvent, + isTrusted: !!inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.input) || null, + set: inputEvent ? this._createUserControll(moveTo.pos) : function () {} + }; + var event = new ComponentEvent$1("change", param); + + this._axes.trigger(event); + + if (inputEvent) { + axisManager.set(param.set().destPos); + } + + return !event.isCanceled(); + }; + /** + * This event is fired when animation starts. + * @ko 에니메이션이 시작할 때 발생한다. + * @event Axes#animationStart + * @type {object} + * @property {Object.} depaPos The coordinates when animation starts애니메이션이 시작 되었을 때의 좌표 + * @property {Object.} destPos The coordinates to move to. If you change this value, you can run the animation이동할 좌표. 이값을 변경하여 애니메이션을 동작시킬수 있다 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Number} duration Duration of the animation (unit: ms). If you change this value, you can control the animation duration time.애니메이션 진행 시간(단위: ms). 이값을 변경하여 애니메이션의 이동시간을 조절할 수 있다. + * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {setTo} setTo Specifies the animation coordinates to move after the event 이벤트 이후 이동할 애니메이션 좌표를 지정한다 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("release", function(event) { + * // event.depaPos + * // event.destPos + * // event.delta + * // event.input + * // event.inputEvent + * // event.setTo + * // event.isTrusted + * + * // if you want to change the animation coordinates to move after the 'animationStart' event. + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + + __proto.triggerAnimationStart = function (param) { + var _a = this._getRoundPos(param.destPos, param.depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + param.destPos = roundPos; + param.depaPos = roundDepa; + param.setTo = this._createUserControll(param.destPos, param.duration); + var event = new ComponentEvent$1("animationStart", param); + + this._axes.trigger(event); + + return !event.isCanceled(); + }; + /** + * This event is fired when animation ends. + * @ko 에니메이션이 끝났을 때 발생한다. + * @event Axes#animationEnd + * @type {object} + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("animationEnd", function(event) { + * // event.isTrusted + * }); + * ``` + */ + + + __proto.triggerAnimationEnd = function (isTrusted) { + if (isTrusted === void 0) { + isTrusted = false; + } + + this._axes.trigger(new ComponentEvent$1("animationEnd", { + isTrusted: isTrusted + })); + }; + /** + * This event is fired when all actions have been completed. + * @ko 에니메이션이 끝났을 때 발생한다. + * @event Axes#finish + * @type {object} + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("finish", function(event) { + * // event.isTrusted + * }); + * ``` + */ + + + __proto.triggerFinish = function (isTrusted) { + if (isTrusted === void 0) { + isTrusted = false; + } + + this._axes.trigger(new ComponentEvent$1("finish", { + isTrusted: isTrusted + })); + }; + + __proto.setAnimationManager = function (animationManager) { + this.animationManager = animationManager; + }; + + __proto.destroy = function () { + this._axes.off(); + }; + + __proto._createUserControll = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } // to controll + + + var userControl = { + destPos: __assign$1({}, pos), + duration: duration + }; + return function (toPos, userDuration) { + if (toPos) { + userControl.destPos = __assign$1({}, toPos); + } + + if (userDuration !== undefined) { + userControl.duration = userDuration; + } + + return userControl; + }; + }; + + __proto._getRoundPos = function (pos, depaPos) { + // round value if round exist + var roundUnit = this._axes.options.round; // if (round == null) { + // return {pos, depaPos}; // undefined, undefined + // } + + return { + roundPos: roundNumbers(pos, roundUnit), + roundDepa: roundNumbers(depaPos, roundUnit) + }; + }; + + __proto._getBounceRatio = function (pos) { + return this._axes.axisManager.map(pos, function (v, opt) { + if (v < opt.range[0] && opt.bounce[0] !== 0) { + return (opt.range[0] - v) / opt.bounce[0]; + } else if (v > opt.range[1] && opt.bounce[1] !== 0) { + return (v - opt.range[1]) / opt.bounce[1]; + } else { + return 0; + } + }); + }; + + return EventManager; + }(); + + var InterruptManager = + /*#__PURE__*/ + function () { + function InterruptManager(_options) { + this._options = _options; + this._prevented = false; // check whether the animation event was prevented + } + + var __proto = InterruptManager.prototype; + + __proto.isInterrupting = function () { + // when interruptable is 'true', return value is always 'true'. + return this._options.interruptable || this._prevented; + }; + + __proto.isInterrupted = function () { + return !this._options.interruptable && this._prevented; + }; + + __proto.setInterrupt = function (prevented) { + if (!this._options.interruptable) { + this._prevented = prevented; + } + }; + + return InterruptManager; + }(); + + var getInsidePosition = function (destPos, range, circular, bounce) { + var toDestPos = destPos; + var targetRange = [circular[0] ? range[0] : bounce ? range[0] - bounce[0] : range[0], circular[1] ? range[1] : bounce ? range[1] + bounce[1] : range[1]]; + toDestPos = Math.max(targetRange[0], toDestPos); + toDestPos = Math.min(targetRange[1], toDestPos); + return toDestPos; + }; // determine outside + + var isOutside = function (pos, range) { + return pos < range[0] || pos > range[1]; + }; // determine whether position has reached the maximum moveable area + + var isEndofBounce = function (pos, range, bounce, circular) { + return !circular[0] && pos === range[0] - bounce[0] || !circular[1] && pos === range[1] + bounce[1]; + }; + var getDuration = function (distance, deceleration) { + var duration = Math.sqrt(distance / deceleration * 2); // when duration is under 100, then value is zero + + return duration < 100 ? 0 : duration; + }; + var isCircularable = function (destPos, range, circular) { + return circular[1] && destPos > range[1] || circular[0] && destPos < range[0]; + }; + var getCirculatedPos = function (pos, range, circular) { + var toPos = pos; + var min = range[0]; + var max = range[1]; + var length = max - min; + + if (circular[1] && pos > max) { + // right + toPos = (toPos - max) % length + min; + } + + if (circular[0] && pos < min) { + // left + toPos = (toPos - min) % length + max; + } + + return toPos; + }; + + var AxisManager = + /*#__PURE__*/ + function () { + function AxisManager(_axis) { + var _this = this; + + this._axis = _axis; + + this._complementOptions(); + + this._pos = Object.keys(this._axis).reduce(function (acc, v) { + acc[v] = _this._axis[v].range[0]; + return acc; + }, {}); + } + + var __proto = AxisManager.prototype; + + __proto.getDelta = function (depaPos, destPos) { + var fullDepaPos = this.get(depaPos); + return map(this.get(destPos), function (v, k) { + return v - fullDepaPos[k]; + }); + }; + + __proto.get = function (axes) { + var _this = this; + + if (axes && Array.isArray(axes)) { + return axes.reduce(function (acc, v) { + if (v && v in _this._pos) { + acc[v] = _this._pos[v]; + } + + return acc; + }, {}); + } else { + return __assign$1(__assign$1({}, this._pos), axes || {}); + } + }; + + __proto.moveTo = function (pos, depaPos) { + if (depaPos === void 0) { + depaPos = this._pos; + } + + var delta = map(this._pos, function (v, key) { + return key in pos && key in depaPos ? pos[key] - depaPos[key] : 0; + }); + this.set(this.map(pos, function (v, opt) { + return opt ? getCirculatedPos(v, opt.range, opt.circular) : 0; + })); + return { + pos: __assign$1({}, this._pos), + delta: delta + }; + }; + + __proto.set = function (pos) { + for (var k in pos) { + if (k && k in this._pos) { + this._pos[k] = pos[k]; + } + } + }; + + __proto.every = function (pos, callback) { + var axisOptions = this._axis; + return every(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.filter = function (pos, callback) { + var axisOptions = this._axis; + return filter(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.map = function (pos, callback) { + var axisOptions = this._axis; + return map(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.isOutside = function (axes) { + return !this.every(axes ? this.get(axes) : this._pos, function (v, opt) { + return !isOutside(v, opt.range); + }); + }; + + __proto.getAxisOptions = function (key) { + return this._axis[key]; + }; + /** + * set up 'css' expression + * @private + */ + + + __proto._complementOptions = function () { + var _this = this; + + Object.keys(this._axis).forEach(function (axis) { + _this._axis[axis] = __assign$1({ + range: [0, 100], + bounce: [0, 0], + circular: [false, false] + }, _this._axis[axis]); + ["bounce", "circular"].forEach(function (v) { + var axisOption = _this._axis; + var key = axisOption[axis][v]; + + if (/string|number|boolean/.test(typeof key)) { + axisOption[axis][v] = [key, key]; + } + }); + }); + }; + + return AxisManager; + }(); + + var SUPPORT_TOUCH = ("ontouchstart" in win); + var SUPPORT_POINTER = ("PointerEvent" in win); + var SUPPORT_MSPOINTER = ("MSPointerEvent" in win); + var SUPPORT_POINTER_EVENTS = SUPPORT_POINTER || SUPPORT_MSPOINTER; + + var EventInput = + /*#__PURE__*/ + function () { + function EventInput() { + var _this = this; + + this._stopContextMenu = function (event) { + event.preventDefault(); + win.removeEventListener("contextmenu", _this._stopContextMenu); + }; + } + + var __proto = EventInput.prototype; + + __proto.extendEvent = function (event) { + var _a; + + var prevEvent = this.prevEvent; + + var center = this._getCenter(event); + + var movement = prevEvent ? this._getMovement(event) : { + x: 0, + y: 0 + }; + var scale = prevEvent ? this._getScale(event) : 1; + var angle = prevEvent ? getAngle(center.x - prevEvent.center.x, center.y - prevEvent.center.y) : 0; + var deltaX = prevEvent ? prevEvent.deltaX + movement.x : movement.x; + var deltaY = prevEvent ? prevEvent.deltaY + movement.y : movement.y; + var offsetX = movement.x; + var offsetY = movement.y; + var latestInterval = this._latestInterval; + var timeStamp = Date.now(); + var deltaTime = latestInterval ? timeStamp - latestInterval.timestamp : 0; + var velocityX = prevEvent ? prevEvent.velocityX : 0; + var velocityY = prevEvent ? prevEvent.velocityY : 0; + + if (!latestInterval || deltaTime >= VELOCITY_INTERVAL) { + if (latestInterval) { + _a = [(deltaX - latestInterval.deltaX) / deltaTime, (deltaY - latestInterval.deltaY) / deltaTime], velocityX = _a[0], velocityY = _a[1]; + } + + this._latestInterval = { + timestamp: timeStamp, + deltaX: deltaX, + deltaY: deltaY + }; + } + + return { + srcEvent: event, + scale: scale, + angle: angle, + center: center, + deltaX: deltaX, + deltaY: deltaY, + offsetX: offsetX, + offsetY: offsetY, + velocityX: velocityX, + velocityY: velocityY, + preventSystemEvent: true + }; + }; + + __proto._getDistance = function (start, end) { + var x = end.clientX - start.clientX; + var y = end.clientY - start.clientY; + return Math.sqrt(x * x + y * y); + }; + + __proto._getButton = function (event) { + var buttonCodeMap = { + 1: MOUSE_LEFT, + 2: MOUSE_RIGHT, + 4: MOUSE_MIDDLE + }; + var button = this._isTouchEvent(event) ? MOUSE_LEFT : buttonCodeMap[event.buttons]; + return button ? button : null; + }; + + __proto._isTouchEvent = function (event) { + return event.type.indexOf("touch") > -1; + }; + + __proto._isValidButton = function (button, inputButton) { + return inputButton.indexOf(button) > -1; + }; + + __proto._preventMouseButton = function (event, button) { + if (button === MOUSE_RIGHT) { + win.addEventListener("contextmenu", this._stopContextMenu); + } else if (button === MOUSE_MIDDLE) { + event.preventDefault(); + } + }; + + return EventInput; + }(); + + var MouseEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(MouseEventInput, _super); + + function MouseEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["mousedown"]; + _this.move = ["mousemove"]; + _this.end = ["mouseup"]; + return _this; + } + + var __proto = MouseEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function () { + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + return; + }; + + __proto.getTouches = function () { + return 0; + }; + + __proto._getScale = function () { + return 1; + }; + + __proto._getCenter = function (event) { + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + return { + x: event.clientX - prev.clientX, + y: event.clientY - prev.clientY + }; + }; + + return MouseEventInput; + }(EventInput); + + var TouchEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(TouchEventInput, _super); + + function TouchEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["touchstart"]; + _this.move = ["touchmove"]; + _this.end = ["touchend", "touchcancel"]; + return _this; + } + + var __proto = TouchEventInput.prototype; + + __proto.onEventStart = function (event) { + this._baseTouches = event.touches; + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event) { + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + this._baseTouches = event.touches; + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._baseTouches = null; + return; + }; + + __proto.getTouches = function (event) { + return event.touches.length; + }; + + __proto._getScale = function (event) { + if (event.touches.length !== 2 || this._baseTouches.length < 2) { + return null; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(event.touches[0], event.touches[1]) / this._getDistance(this._baseTouches[0], this._baseTouches[1]); + }; + + __proto._getCenter = function (event) { + return { + x: event.touches[0].clientX, + y: event.touches[0].clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + + if (event.touches[0].identifier !== prev.touches[0].identifier) { + return { + x: 0, + y: 0 + }; + } + + return { + x: event.touches[0].clientX - prev.touches[0].clientX, + y: event.touches[0].clientY - prev.touches[0].clientY + }; + }; + + return TouchEventInput; + }(EventInput); + + var PointerEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(PointerEventInput, _super); + + function PointerEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = SUPPORT_POINTER ? ["pointerdown"] : ["MSPointerDown"]; + _this.move = SUPPORT_POINTER ? ["pointermove"] : ["MSPointerMove"]; + _this.end = SUPPORT_POINTER ? ["pointerup", "pointercancel"] : ["MSPointerUp", "MSPointerCancel"]; // store first, recent inputs for each event id + + _this._firstInputs = []; + _this._recentInputs = []; + return _this; + } + + var __proto = PointerEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + this._updatePointerEvent(event); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + this._updatePointerEvent(event); + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + this._removePointerEvent(event); + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._firstInputs = []; + this._recentInputs = []; + return; + }; + + __proto.getTouches = function () { + return this._recentInputs.length; + }; + + __proto._getScale = function () { + if (this._recentInputs.length !== 2) { + return null; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(this._recentInputs[0], this._recentInputs[1]) / this._getDistance(this._firstInputs[0], this._firstInputs[1]); + }; + + __proto._getCenter = function (event) { + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + + if (event.pointerId !== prev.pointerId) { + return { + x: 0, + y: 0 + }; + } + + return { + x: event.clientX - prev.clientX, + y: event.clientY - prev.clientY + }; + }; + + __proto._updatePointerEvent = function (event) { + var _this = this; + + var addFlag = false; + + this._recentInputs.forEach(function (e, i) { + if (e.pointerId === event.pointerId) { + addFlag = true; + _this._recentInputs[i] = event; + } + }); + + if (!addFlag) { + this._firstInputs.push(event); + + this._recentInputs.push(event); + } + }; + + __proto._removePointerEvent = function (event) { + this._firstInputs = this._firstInputs.filter(function (x) { + return x.pointerId !== event.pointerId; + }); + this._recentInputs = this._recentInputs.filter(function (x) { + return x.pointerId !== event.pointerId; + }); + }; + + return PointerEventInput; + }(EventInput); + + var TouchMouseEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(TouchMouseEventInput, _super); + + function TouchMouseEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["mousedown", "touchstart"]; + _this.move = ["mousemove", "touchmove"]; + _this.end = ["mouseup", "touchend", "touchcancel"]; + return _this; + } + + var __proto = TouchMouseEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (this._isTouchEvent(event)) { + this._baseTouches = event.touches; + } + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + if (this._isTouchEvent(event)) { + this._baseTouches = event.touches; + } + + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._baseTouches = null; + return; + }; + + __proto.getTouches = function (event) { + return this._isTouchEvent(event) ? event.touches.length : 0; + }; + + __proto._getScale = function (event) { + if (this._isTouchEvent(event)) { + if (event.touches.length !== 2 || this._baseTouches.length < 2) { + return 1; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(event.touches[0], event.touches[1]) / this._getDistance(this._baseTouches[0], this._baseTouches[1]); + } + + return this.prevEvent.scale; + }; + + __proto._getCenter = function (event) { + if (this._isTouchEvent(event)) { + return { + x: event.touches[0].clientX, + y: event.touches[0].clientY + }; + } + + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var _this = this; + + var prev = this.prevEvent.srcEvent; + + var _a = [event, prev].map(function (e) { + if (_this._isTouchEvent(e)) { + return { + id: e.touches[0].identifier, + x: e.touches[0].clientX, + y: e.touches[0].clientY + }; + } + + return { + id: null, + x: e.clientX, + y: e.clientY + }; + }), + nextSpot = _a[0], + prevSpot = _a[1]; + + return nextSpot.id === prevSpot.id ? { + x: nextSpot.x - prevSpot.x, + y: nextSpot.y - prevSpot.y + } : { + x: 0, + y: 0 + }; + }; + + return TouchMouseEventInput; + }(EventInput); + + var toAxis = function (source, offset) { + return offset.reduce(function (acc, v, i) { + if (source[i]) { + acc[source[i]] = v; + } + + return acc; + }, {}); + }; + var convertInputType = function (inputType) { + if (inputType === void 0) { + inputType = []; + } + + var hasTouch = false; + var hasMouse = false; + var hasPointer = false; + inputType.forEach(function (v) { + switch (v) { + case "mouse": + hasMouse = true; + break; + + case "touch": + hasTouch = SUPPORT_TOUCH; + break; + + case "pointer": + hasPointer = SUPPORT_POINTER_EVENTS; + // no default + } + }); + + if (hasPointer) { + return new PointerEventInput(); + } else if (hasTouch && hasMouse) { + return new TouchMouseEventInput(); + } else if (hasTouch) { + return new TouchEventInput(); + } else if (hasMouse) { + return new MouseEventInput(); + } + + return null; + }; + + var InputObserver = + /*#__PURE__*/ + function () { + function InputObserver(_a) { + var options = _a.options, + interruptManager = _a.interruptManager, + eventManager = _a.eventManager, + axisManager = _a.axisManager, + animationManager = _a.animationManager; + this._isOutside = false; + this._moveDistance = null; + this._isStopped = false; + this.options = options; + this._interruptManager = interruptManager; + this._eventManager = eventManager; + this._axisManager = axisManager; + this._animationManager = animationManager; + } + + var __proto = InputObserver.prototype; + + __proto.get = function (input) { + return this._axisManager.get(input.axes); + }; + + __proto.hold = function (input, event) { + if (this._interruptManager.isInterrupted() || !input.axes.length) { + return; + } + + var changeOption = { + input: input, + event: event + }; + this._isStopped = false; + + this._interruptManager.setInterrupt(true); + + this._animationManager.stopAnimation(changeOption); + + if (!this._moveDistance) { + this._eventManager.hold(this._axisManager.get(), changeOption); + } + + this._isOutside = this._axisManager.isOutside(input.axes); + this._moveDistance = this._axisManager.get(input.axes); + }; + + __proto.change = function (input, event, offset, useAnimation) { + if (this._isStopped || !this._interruptManager.isInterrupting() || this._axisManager.every(offset, function (v) { + return v === 0; + })) { + return; + } + + var nativeEvent = event.srcEvent ? event.srcEvent : event; + + if (nativeEvent.__childrenAxesAlreadyChanged) { + return; + } + + var depaPos = this._moveDistance || this._axisManager.get(input.axes); + + var destPos; // for outside logic + + destPos = map(depaPos, function (v, k) { + return v + (offset[k] || 0); + }); + + if (this._moveDistance) { + this._moveDistance = this._axisManager.map(destPos, function (v, _a) { + var circular = _a.circular, + range = _a.range; + return circular && (circular[0] || circular[1]) ? getCirculatedPos(v, range, circular) : v; + }); + } // from outside to inside + + + if (this._isOutside && this._axisManager.every(depaPos, function (v, opt) { + return !isOutside(v, opt.range); + })) { + this._isOutside = false; + } + + depaPos = this._atOutside(depaPos); + destPos = this._atOutside(destPos); + + if (!this.options.nested || !this._isEndofAxis(offset, depaPos, destPos)) { + nativeEvent.__childrenAxesAlreadyChanged = true; + } + + var changeOption = { + input: input, + event: event + }; + + if (useAnimation) { + var duration = this._animationManager.getDuration(destPos, depaPos); + + this._animationManager.animateTo(destPos, duration, changeOption); + } else { + var isCanceled = !this._eventManager.triggerChange(destPos, depaPos, changeOption, true); + + if (isCanceled) { + this._isStopped = true; + this._moveDistance = null; + + this._animationManager.finish(false); + } + } + }; + + __proto.release = function (input, event, velocity, inputDuration) { + if (this._isStopped || !this._interruptManager.isInterrupting() || !this._moveDistance) { + return; + } + + var nativeEvent = event.srcEvent ? event.srcEvent : event; + + if (nativeEvent.__childrenAxesAlreadyReleased) { + velocity = velocity.map(function () { + return 0; + }); + } + + var pos = this._axisManager.get(input.axes); + + var depaPos = this._axisManager.get(); + + var displacement = this._animationManager.getDisplacement(velocity); + + var offset = toAxis(input.axes, displacement); + + var destPos = this._axisManager.get(this._axisManager.map(offset, function (v, opt, k) { + if (opt.circular && (opt.circular[0] || opt.circular[1])) { + return pos[k] + v; + } else { + return getInsidePosition(pos[k] + v, opt.range, opt.circular, opt.bounce); + } + })); + + nativeEvent.__childrenAxesAlreadyReleased = true; + + var duration = this._animationManager.getDuration(destPos, pos, inputDuration); + + if (duration === 0) { + destPos = __assign$1({}, depaPos); + } // prepare params + + + var param = { + depaPos: depaPos, + destPos: destPos, + duration: duration, + delta: this._axisManager.getDelta(depaPos, destPos), + inputEvent: event, + input: input, + isTrusted: true + }; + + this._eventManager.triggerRelease(param); + + this._moveDistance = null; // to contol + + var userWish = this._animationManager.getUserControl(param); + + var isEqual = equal(userWish.destPos, depaPos); + var changeOption = { + input: input, + event: event + }; + + if (isEqual || userWish.duration === 0) { + if (!isEqual) { + this._eventManager.triggerChange(userWish.destPos, depaPos, changeOption, true); + } + + this._interruptManager.setInterrupt(false); + + if (this._axisManager.isOutside()) { + this._animationManager.restore(changeOption); + } else { + this._eventManager.triggerFinish(true); + } + } else { + this._animationManager.animateTo(userWish.destPos, userWish.duration, changeOption); + } + }; // when move pointer is held in outside + + + __proto._atOutside = function (pos) { + var _this = this; + + if (this._isOutside) { + return this._axisManager.map(pos, function (v, opt) { + var tn = opt.range[0] - opt.bounce[0]; + var tx = opt.range[1] + opt.bounce[1]; + return v > tx ? tx : v < tn ? tn : v; + }); + } else { + return this._axisManager.map(pos, function (v, opt) { + var min = opt.range[0]; + var max = opt.range[1]; + var out = opt.bounce; + var circular = opt.circular; + + if (circular && (circular[0] || circular[1])) { + return v; + } else if (v < min) { + // left + return min - _this._animationManager.interpolate(min - v, out[0]); + } else if (v > max) { + // right + return max + _this._animationManager.interpolate(v - max, out[1]); + } + + return v; + }); + } + }; + + __proto._isEndofAxis = function (offset, depaPos, destPos) { + return this._axisManager.every(depaPos, function (value, option, key) { + return offset[key] === 0 || depaPos[key] === destPos[key] && isEndofBounce(value, option.range, option.bounce, option.circular); + }); + }; + + return InputObserver; + }(); + + var clamp = function (value, min, max) { + return Math.max(Math.min(value, max), min); + }; + + var AnimationManager = + /*#__PURE__*/ + function () { + function AnimationManager(_a) { + var options = _a.options, + interruptManager = _a.interruptManager, + eventManager = _a.eventManager, + axisManager = _a.axisManager; + this._options = options; + this.interruptManager = interruptManager; + this.eventManager = eventManager; + this.axisManager = axisManager; + this.animationEnd = this.animationEnd.bind(this); + } + + var __proto = AnimationManager.prototype; + + __proto.getDuration = function (depaPos, destPos, wishDuration) { + var _this = this; + + var duration; + + if (typeof wishDuration !== "undefined") { + duration = wishDuration; + } else { + var durations_1 = map(destPos, function (v, k) { + return getDuration(Math.abs(v - depaPos[k]), _this._options.deceleration); + }); + duration = Object.keys(durations_1).reduce(function (max, v) { + return Math.max(max, durations_1[v]); + }, -Infinity); + } + + return clamp(duration, this._options.minimumDuration, this._options.maximumDuration); + }; + + __proto.getDisplacement = function (velocity) { + var totalVelocity = Math.pow(velocity.reduce(function (total, v) { + return total + v * v; + }, 0), 1 / velocity.length); + var duration = Math.abs(totalVelocity / -this._options.deceleration); + return velocity.map(function (v) { + return v / 2 * duration; + }); + }; + + __proto.stopAnimation = function (option) { + if (this._animateParam) { + var orgPos_1 = this.axisManager.get(); + var pos = this.axisManager.map(orgPos_1, function (v, opt) { + return getCirculatedPos(v, opt.range, opt.circular); + }); + + if (!every(pos, function (v, k) { + return orgPos_1[k] === v; + })) { + this.eventManager.triggerChange(pos, orgPos_1, option, !!option); + } + + this._animateParam = null; + + if (this._raf) { + cancelAnimationFrame(this._raf); + } + + this._raf = null; + this.eventManager.triggerAnimationEnd(!!(option === null || option === void 0 ? void 0 : option.event)); + } + }; + + __proto.getEventInfo = function () { + if (this._animateParam && this._animateParam.input && this._animateParam.inputEvent) { + return { + input: this._animateParam.input, + event: this._animateParam.inputEvent + }; + } else { + return null; + } + }; + + __proto.restore = function (option) { + var pos = this.axisManager.get(); + var destPos = this.axisManager.map(pos, function (v, opt) { + return Math.min(opt.range[1], Math.max(opt.range[0], v)); + }); + this.stopAnimation(); + this.animateTo(destPos, this.getDuration(pos, destPos), option); + }; + + __proto.animationEnd = function () { + var beforeParam = this.getEventInfo(); + this._animateParam = null; // for Circular + + var circularTargets = this.axisManager.filter(this.axisManager.get(), function (v, opt) { + return isCircularable(v, opt.range, opt.circular); + }); + + if (Object.keys(circularTargets).length > 0) { + this.setTo(this.axisManager.map(circularTargets, function (v, opt) { + return getCirculatedPos(v, opt.range, opt.circular); + })); + } + + this.interruptManager.setInterrupt(false); + this.eventManager.triggerAnimationEnd(!!beforeParam); + + if (this.axisManager.isOutside()) { + this.restore(beforeParam); + } else { + this.finish(!!beforeParam); + } + }; + + __proto.finish = function (isTrusted) { + this._animateParam = null; + this.interruptManager.setInterrupt(false); + this.eventManager.triggerFinish(isTrusted); + }; + + __proto.getUserControl = function (param) { + var userWish = param.setTo(); + userWish.destPos = this.axisManager.get(userWish.destPos); + userWish.duration = clamp(userWish.duration, this._options.minimumDuration, this._options.maximumDuration); + return userWish; + }; + + __proto.animateTo = function (destPos, duration, option) { + var _this = this; + + this.stopAnimation(); + + var param = this._createAnimationParam(destPos, duration, option); + + var depaPos = __assign$1({}, param.depaPos); + + var retTrigger = this.eventManager.triggerAnimationStart(param); // to control + + var userWish = this.getUserControl(param); // You can't stop the 'animationStart' event when 'circular' is true. + + if (!retTrigger && this.axisManager.every(userWish.destPos, function (v, opt) { + return isCircularable(v, opt.range, opt.circular); + })) { + console.warn("You can't stop the 'animation' event when 'circular' is true."); + } + + if (retTrigger && !equal(userWish.destPos, depaPos)) { + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || null; + + this._animateLoop({ + depaPos: depaPos, + destPos: userWish.destPos, + duration: userWish.duration, + delta: this.axisManager.getDelta(depaPos, userWish.destPos), + isTrusted: !!inputEvent, + inputEvent: inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || null + }, function () { + return _this.animationEnd(); + }); + } + }; + + __proto.setTo = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + var axes = Object.keys(pos); + var orgPos = this.axisManager.get(axes); + + if (equal(pos, orgPos)) { + return this; + } + + this.interruptManager.setInterrupt(true); + var movedPos = filter(pos, function (v, k) { + return orgPos[k] !== v; + }); + + if (!Object.keys(movedPos).length) { + return this; + } + + movedPos = this.axisManager.map(movedPos, function (v, opt) { + var range = opt.range, + circular = opt.circular; + + if (circular && (circular[0] || circular[1])) { + return v; + } else { + return getInsidePosition(v, range, circular); + } + }); + + if (equal(movedPos, orgPos)) { + return this; + } + + if (duration > 0) { + this.animateTo(movedPos, duration); + } else { + this.stopAnimation(); + this.eventManager.triggerChange(movedPos); + this.finish(false); + } + + return this; + }; + + __proto.setBy = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + return this.setTo(map(this.axisManager.get(Object.keys(pos)), function (v, k) { + return v + pos[k]; + }), duration); + }; + + __proto._createAnimationParam = function (pos, duration, option) { + var depaPos = this.axisManager.get(); + var destPos = pos; + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || null; + return { + depaPos: depaPos, + destPos: destPos, + duration: clamp(duration, this._options.minimumDuration, this._options.maximumDuration), + delta: this.axisManager.getDelta(depaPos, destPos), + inputEvent: inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || null, + isTrusted: !!inputEvent, + done: this.animationEnd + }; + }; + + __proto._animateLoop = function (param, complete) { + var _this = this; + + if (param.duration) { + this._animateParam = __assign$1(__assign$1({}, param), { + startTime: new Date().getTime() + }); + var originalIntendedPos_1 = map(param.destPos, function (v) { + return v; + }); + + var state_1 = this._initState(this._animateParam); + + var loop_1 = function () { + _this._raf = null; + var animateParam = _this._animateParam; + + var nextState = _this._getNextState(state_1); + + var isCanceled = !_this.eventManager.triggerChange(nextState.pos, state_1.pos); + state_1 = nextState; + + if (nextState.finished) { + animateParam.destPos = _this._getFinalPos(animateParam.destPos, originalIntendedPos_1); + + if (!equal(animateParam.destPos, _this.axisManager.get(Object.keys(animateParam.destPos)))) { + _this.eventManager.triggerChange(animateParam.destPos, nextState.pos); + } + + complete(); + return; + } else if (isCanceled) { + _this.finish(false); + } else { + _this._raf = requestAnimationFrame(loop_1); + } + }; + + loop_1(); + } else { + this.eventManager.triggerChange(param.destPos); + complete(); + } + }; + /** + * Get estimated final value. + * + * If destPos is within the 'error range' of the original intended position, the initial intended position is returned. + * - eg. original intended pos: 100, destPos: 100.0000000004 ==> return 100; + * If dest Pos is outside the 'range of error' compared to the originally intended pos, it is returned rounded based on the originally intended pos. + * - eg. original intended pos: 100.123 destPos: 50.12345 => return 50.123 + * @param originalIntendedPos + * @param destPos + */ + + + __proto._getFinalPos = function (destPos, originalIntendedPos) { + var _this = this; // compare destPos and originalIntendedPos + // eslint-disable-next-line @typescript-eslint/naming-convention + + + var ERROR_LIMIT = 0.000001; + var finalPos = map(destPos, function (value, key) { + if (value >= originalIntendedPos[key] - ERROR_LIMIT && value <= originalIntendedPos[key] + ERROR_LIMIT) { + // In error range, return original intended + return originalIntendedPos[key]; + } else { + // Out of error range, return rounded pos. + var roundUnit = _this._getRoundUnit(value, key); + + var result = roundNumber(value, roundUnit); + return result; + } + }); + return finalPos; + }; + + __proto._getRoundUnit = function (val, key) { + var roundUnit = this._options.round; // manual mode + + var minRoundUnit = null; // auto mode + // auto mode + + if (!roundUnit) { + // Get minimum round unit + var options = this.axisManager.getAxisOptions(key); + minRoundUnit = inversePow(Math.max(getDecimalPlace(options.range[0]), getDecimalPlace(options.range[1]), getDecimalPlace(val))); + } + + return minRoundUnit || roundUnit; + }; + + return AnimationManager; + }(); + + var EasingManager = + /*#__PURE__*/ + function (_super) { + __extends$1(EasingManager, _super); + + function EasingManager() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this._useDuration = true; + return _this; + } + + var __proto = EasingManager.prototype; + + __proto.interpolate = function (displacement, threshold) { + var initSlope = this._easing(0.00001) / 0.00001; + return this._easing(displacement / (threshold * initSlope)) * threshold; + }; + + __proto.updateAnimation = function (options) { + var animateParam = this._animateParam; + + if (!animateParam) { + return; + } + + var diffTime = new Date().getTime() - animateParam.startTime; + var pos = (options === null || options === void 0 ? void 0 : options.destPos) || animateParam.destPos; + var duration = (options === null || options === void 0 ? void 0 : options.duration) || animateParam.duration; + + if ((options === null || options === void 0 ? void 0 : options.restart) || duration <= diffTime) { + this.setTo(pos, duration - diffTime); + return; + } + + if (options === null || options === void 0 ? void 0 : options.destPos) { + var currentPos = this.axisManager.get(); // When destination is changed, new delta should be calculated as remaining percent. + // For example, moving x:0, y:0 to x:200, y:200 and it has current easing percent of 92%. coordinate is x:184 and y:184 + // If destination changes to x:300, y:300. xdelta:200, ydelta:200 changes to xdelta:116, ydelta:116 and use remaining easingPer as 100%, not 8% as previous. + // Therefore, original easingPer by time is kept. And divided by (1 - self._initialEasingPer) which means new total easing percent. Like calculating 8% as 100%. + + this._initialEasingPer = this._prevEasingPer; + animateParam.delta = this.axisManager.getDelta(currentPos, pos); + animateParam.destPos = pos; + } + + if (options === null || options === void 0 ? void 0 : options.duration) { + var ratio = (diffTime + this._durationOffset) / animateParam.duration; // Use durationOffset for keeping animation ratio after duration is changed. + // newRatio = (diffTime + newDurationOffset) / newDuration = oldRatio + // newDurationOffset = oldRatio * newDuration - diffTime + + this._durationOffset = ratio * duration - diffTime; + animateParam.duration = duration; + } + }; + + __proto._initState = function (info) { + this._initialEasingPer = 0; + this._prevEasingPer = 0; + this._durationOffset = 0; + return { + pos: info.depaPos, + easingPer: 0, + finished: false + }; + }; + + __proto._getNextState = function (prevState) { + var _this = this; + + var animateParam = this._animateParam; + var prevPos = prevState.pos; + var destPos = animateParam.destPos; + var directions = map(prevPos, function (value, key) { + return value <= destPos[key] ? 1 : -1; + }); + var diffTime = new Date().getTime() - animateParam.startTime; + var ratio = (diffTime + this._durationOffset) / animateParam.duration; + + var easingPer = this._easing(ratio); + + var toPos = this.axisManager.map(prevPos, function (pos, options, key) { + var nextPos = ratio >= 1 ? destPos[key] : pos + animateParam.delta[key] * (easingPer - _this._prevEasingPer) / (1 - _this._initialEasingPer); // Subtract distance from distance already moved. + // Recalculate the remaining distance. + // Fix the bouncing phenomenon by changing the range. + + var circulatedPos = getCirculatedPos(nextPos, options.range, options.circular); + + if (nextPos !== circulatedPos) { + // circular + var rangeOffset = directions[key] * (options.range[1] - options.range[0]); + destPos[key] -= rangeOffset; + prevPos[key] -= rangeOffset; + } + + return circulatedPos; + }); + this._prevEasingPer = easingPer; + return { + pos: toPos, + easingPer: easingPer, + finished: easingPer >= 1 + }; + }; + + __proto._easing = function (p) { + return p > 1 ? 1 : this._options.easing(p); + }; + + return EasingManager; + }(AnimationManager); + + /** + * @typedef {Object} AxisOption The Axis information. The key of the axis specifies the name to use as the logical virtual coordinate system. + * @ko 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다. + * @param {Number[]} [range] The coordinate of range 좌표 범위 + * @param {Number} [range[0]=0] The coordinate of the minimum 최소 좌표 + * @param {Number} [range[1]=0] The coordinate of the maximum 최대 좌표 + * @param {Number[]} [bounce] The size of bouncing area. The coordinates can exceed the coordinate area as much as the bouncing area based on user action. If the coordinates does not exceed the bouncing area when an element is dragged, the coordinates where bouncing effects are applied are retuned back into the coordinate area바운스 영역의 크기. 사용자의 동작에 따라 좌표가 좌표 영역을 넘어 바운스 영역의 크기만큼 더 이동할 수 있다. 사용자가 끌어다 놓는 동작을 했을 때 좌표가 바운스 영역에 있으면, 바운스 효과가 적용된 좌표가 다시 좌표 영역 안으로 들어온다 + * @param {Number} [bounce[0]=0] The size of coordinate of the minimum area 최소 좌표 바운스 영역의 크기 + * @param {Number} [bounce[1]=0] The size of coordinate of the maximum area 최대 좌표 바운스 영역의 크기 + * @param {Boolean[]} [circular] Indicates whether a circular element is available. If it is set to "true" and an element is dragged outside the coordinate area, the element will appear on the other side.순환 여부. 'true'로 설정한 방향의 좌표 영역 밖으로 엘리먼트가 이동하면 반대 방향에서 엘리먼트가 나타난다 + * @param {Boolean} [circular[0]=false] Indicates whether to circulate to the coordinate of the minimum 최소 좌표 방향의 순환 여부 + * @param {Boolean} [circular[1]=false] Indicates whether to circulate to the coordinate of the maximum 최대 좌표 방향의 순환 여부 + **/ + + /** + * @typedef {Object} AxesOption The option object of the eg.Axes module + * @ko eg.Axes 모듈의 옵션 객체 + * @param {Function} [easing=easing.easeOutCubic] The easing function to apply to an animation 애니메이션에 적용할 easing 함수 + * @param {Number} [maximumDuration=Infinity] Maximum duration of the animation 가속도에 의해 애니메이션이 동작할 때의 최대 좌표 이동 시간 + * @param {Number} [minimumDuration=0] Minimum duration of the animation 가속도에 의해 애니메이션이 동작할 때의 최소 좌표 이동 시간 + * @param {Number} [deceleration=0.0006] Deceleration of the animation where acceleration is manually enabled by user. A higher value indicates shorter running time. 사용자의 동작으로 가속도가 적용된 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아진다 + * @param {Boolean} [interruptable=true] Indicates whether an animation is interruptible. + * - true: It can be paused or stopped by user action or the API. + * - false: It cannot be paused or stopped by user action or the API while it is running. + * 진행 중인 애니메이션 중지 가능 여부. + * - true: 사용자의 동작이나 API로 애니메이션을 중지할 수 있다. + * - false: 애니메이션이 진행 중일 때는 사용자의 동작이나 API가 적용되지 않는다 + * @param {Number} [round=null] Rounding unit. For example, 0.1 rounds to 0.1 decimal point(6.1234 => 6.1), 5 rounds to 5 (93 => 95) + * [Details](https://github.com/naver/egjs-axes/wiki/round-option)반올림 단위. 예를 들어 0.1 은 소숫점 0.1 까지 반올림(6.1234 => 6.1), 5 는 5 단위로 반올림(93 => 95). + * [상세내용](https://github.com/naver/egjs-axes/wiki/round-option) + * @param {Boolean} [nested=false] Whether the event propagates to other instances when the coordinates reach the end of the movable area 좌표가 이동 가능한 영역의 끝까지 도달했을 때 다른 인스턴스들로의 이벤트 전파 여부 + **/ + + /** + * A module used to change the information of user action entered by various input devices such as touch screen or mouse into the logical virtual coordinates. You can easily create a UI that responds to user actions. + * @ko 터치 입력 장치나 마우스와 같은 다양한 입력 장치를 통해 전달 받은 사용자의 동작을 논리적인 가상 좌표로 변경하는 모듈이다. 사용자 동작에 반응하는 UI를 손쉽게 만들수 있다. + * @extends eg.Component + * + * @param {Object.} axis Axis information managed by eg.Axes. The key of the axis specifies the name to use as the logical virtual coordinate system. eg.Axes가 관리하는 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다. + * @param {AxesOption} [options={}] The option object of the eg.Axes moduleeg.Axes 모듈의 옵션 객체 + * @param {Object.} [startPos=null] The coordinates to be moved when creating an instance. not triggering change event.인스턴스 생성시 이동할 좌표, change 이벤트는 발생하지 않음. + * + * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * ```js + * // 1. Initialize eg.Axes + * const axes = new eg.Axes({ + * something1: { + * range: [0, 150], + * bounce: 50 + * }, + * something2: { + * range: [0, 200], + * bounce: 100 + * }, + * somethingN: { + * range: [1, 10], + * } + * }, { + * deceleration : 0.0024 + * }); + * + * // 2. attach event handler + * axes.on({ + * "hold" : function(evt) { + * }, + * "release" : function(evt) { + * }, + * "animationStart" : function(evt) { + * }, + * "animationEnd" : function(evt) { + * }, + * "change" : function(evt) { + * } + * }); + * + * // 3. Initialize inputTypes + * const panInputArea = new eg.Axes.PanInput("#area", { + * scale: [0.5, 1] + * }); + * const panInputHmove = new eg.Axes.PanInput("#hmove"); + * const panInputVmove = new eg.Axes.PanInput("#vmove"); + * const pinchInputArea = new eg.Axes.PinchInput("#area", { + * scale: 1.5 + * }); + * + * // 4. Connect eg.Axes and InputTypes + * // [PanInput] When the mouse or touchscreen is down and moved. + * // Connect the 'something2' axis to the mouse or touchscreen x position and + * // connect the 'somethingN' axis to the mouse or touchscreen y position. + * axes.connect(["something2", "somethingN"], panInputArea); // or axes.connect("something2 somethingN", panInputArea); + * + * // Connect only one 'something1' axis to the mouse or touchscreen x position. + * axes.connect(["something1"], panInputHmove); // or axes.connect("something1", panInputHmove); + * + * // Connect only one 'something2' axis to the mouse or touchscreen y position. + * axes.connect(["", "something2"], panInputVmove); // or axes.connect(" something2", panInputVmove); + * + * // [PinchInput] Connect 'something2' axis when two pointers are moving toward (zoom-in) or away from each other (zoom-out). + * axes.connect("something2", pinchInputArea); + * ``` + */ + + var Axes = + /*#__PURE__*/ + function (_super) { + __extends$1(Axes, _super); + /** + * + */ + + + function Axes(axis, options, startPos) { + if (axis === void 0) { + axis = {}; + } + + if (options === void 0) { + options = {}; + } + + if (startPos === void 0) { + startPos = null; + } + + var _this = _super.call(this) || this; + + _this.axis = axis; + _this._inputs = []; + _this.options = __assign$1({ + easing: function (x) { + return 1 - Math.pow(1 - x, 3); + }, + interruptable: true, + maximumDuration: Infinity, + minimumDuration: 0, + deceleration: 0.0006, + round: null, + nested: false + }, options); + _this.interruptManager = new InterruptManager(_this.options); + _this.axisManager = new AxisManager(_this.axis); + _this.eventManager = new EventManager(_this); + _this.animationManager = new EasingManager(_this); + _this.inputObserver = new InputObserver(_this); + + _this.eventManager.setAnimationManager(_this.animationManager); + + if (startPos) { + _this.eventManager.triggerChange(startPos); + } + + return _this; + } + /** + * Connect the axis of eg.Axes to the inputType. + * @ko eg.Axes의 축과 inputType을 연결한다 + * @param {(String[]|String)} axes The name of the axis to associate with inputType inputType과 연결할 축의 이름 + * @param {Object} inputType The inputType instance to associate with the axis of eg.Axes eg.Axes의 축과 연결할 inputType 인스턴스 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * } + * }); + * + * axes.connect("x", new eg.Axes.PanInput("#area1")) + * .connect("x xOther", new eg.Axes.PanInput("#area2")) + * .connect(" xOther", new eg.Axes.PanInput("#area3")) + * .connect(["x"], new eg.Axes.PanInput("#area4")) + * .connect(["xOther", "x"], new eg.Axes.PanInput("#area5")) + * .connect(["", "xOther"], new eg.Axes.PanInput("#area6")); + * ``` + */ + + + var __proto = Axes.prototype; + + __proto.connect = function (axes, inputType) { + var mapped; + + if (typeof axes === "string") { + mapped = axes.split(" "); + } else { + mapped = axes.concat(); + } // check same instance + + + if (~this._inputs.indexOf(inputType)) { + this.disconnect(inputType); + } + + inputType.mapAxes(mapped); + inputType.connect(this.inputObserver); + + this._inputs.push(inputType); + + return this; + }; + /** + * Disconnect the axis of eg.Axes from the inputType. + * @ko eg.Axes의 축과 inputType의 연결을 끊는다. + * @param {Object} [inputType] An inputType instance associated with the axis of eg.Axes eg.Axes의 축과 연결한 inputType 인스턴스 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * } + * }); + * + * const input1 = new eg.Axes.PanInput("#area1"); + * const input2 = new eg.Axes.PanInput("#area2"); + * const input3 = new eg.Axes.PanInput("#area3"); + * + * axes.connect("x", input1); + * .connect("x xOther", input2) + * .connect(["xOther", "x"], input3); + * + * axes.disconnect(input1); // disconnects input1 + * axes.disconnect(); // disconnects all of them + * ``` + */ + + + __proto.disconnect = function (inputType) { + if (inputType) { + var index = this._inputs.indexOf(inputType); + + if (index >= 0) { + this._inputs[index].disconnect(); + + this._inputs.splice(index, 1); + } + } else { + this._inputs.forEach(function (v) { + return v.disconnect(); + }); + + this._inputs = []; + } + + return this; + }; + /** + * Returns the current position of the coordinates. + * @ko 좌표의 현재 위치를 반환한다 + * @param {Object} [axes] The names of the axis 축 이름들 + * @return {Object.} Axis coordinate information 축 좌표 정보 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.get(); // {"x": 0, "xOther": -100, "zoom": 50} + * axes.get(["x", "zoom"]); // {"x": 0, "zoom": 50} + * ``` + */ + + + __proto.get = function (axes) { + return this.axisManager.get(axes); + }; + /** + * Moves an axis to specific coordinates. + * @ko 좌표를 이동한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.setTo({"x": 30, "zoom": 60}); + * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60} + * + * axes.setTo({"x": 100, "xOther": 60}, 1000); // animatation + * + * // after 1000 ms + * axes.get(); // {"x": 100, "xOther": 60, "zoom": 60} + * ``` + */ + + + __proto.setTo = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + this.animationManager.setTo(pos, duration); + return this; + }; + /** + * Moves an axis from the current coordinates to specific coordinates. + * @ko 현재 좌표를 기준으로 좌표를 이동한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.setBy({"x": 30, "zoom": 10}); + * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60} + * + * axes.setBy({"x": 70, "xOther": 60}, 1000); // animatation + * + * // after 1000 ms + * axes.get(); // {"x": 100, "xOther": -40, "zoom": 60} + * ``` + */ + + + __proto.setBy = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + this.animationManager.setBy(pos, duration); + return this; + }; + /** + * Stop an animation in progress. + * @ko 재생 중인 애니메이션을 정지한다. + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * }); + * + * axes.setTo({"x": 10}, 1000); // start animatation + * + * // after 500 ms + * axes.stopAnimation(); // stop animation during movement. + * ``` + */ + + + __proto.stopAnimation = function () { + this.animationManager.stopAnimation(); + return this; + }; + /** + * Change the destination of an animation in progress. + * @ko 재생 중인 애니메이션의 목적지와 진행 시간을 변경한다. + * @param {UpdateAnimationOption} pos The coordinate to move to 이동할 좌표 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 200] + * }, + * "y": { + * range: [0, 200] + * } + * }); + * + * axes.setTo({"x": 50, "y": 50}, 1000); // trigger animation by setTo + * + * // after 500 ms + * axes.updateAnimation({destPos: {"x": 100, "y": 100}}); // animation will end after 500 ms, at {"x": 100, "y": 100} + * + * // after 500 ms + * axes.setTo({"x": 50, "y": 50}, 1000); // trigger animation by setTo + * + * // after 700 ms + * axes.updateAnimation({destPos: {"x": 100, "y": 100}, duration: 1500, restart: true}); // this works same as axes.setTo({"x": 100, "y": 100}, 800) since restart is true. + * ``` + */ + + + __proto.updateAnimation = function (options) { + this.animationManager.updateAnimation(options); + return this; + }; + /** + * Returns whether there is a coordinate in the bounce area of ​​the target axis. + * @ko 대상 축 중 bounce영역에 좌표가 존재하는지를 반환한다 + * @param {Object} [axes] The names of the axis 축 이름들 + * @return {Boolen} Whether the bounce area exists. bounce 영역 존재 여부 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.isBounceArea(["x"]); + * axes.isBounceArea(["x", "zoom"]); + * axes.isBounceArea(); + * ``` + */ + + + __proto.isBounceArea = function (axes) { + return this.axisManager.isOutside(axes); + }; + /** + * Destroys properties, and events used in a module and disconnect all connections to inputTypes. + * @ko 모듈에 사용한 속성, 이벤트를 해제한다. 모든 inputType과의 연결을 끊는다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.eventManager.destroy(); + }; + /** + * @name VERSION + * @desc Version info string + * @ko 버전정보 문자열 + * + * @constant + * @type {String} + * @example + * ```js + * eg.Axes.VERSION; // ex) 3.3.3 + * ``` + */ + + + Axes.VERSION = "3.3.0"; + /* eslint-enable */ + + /** + * @name TRANSFORM + * @desc Returns the transform attribute with CSS vendor prefixes. + * @ko CSS vendor prefixes를 붙인 transform 속성을 반환한다. + * + * @constant + * @type {String} + * @example + * ```js + * eg.Axes.TRANSFORM; // "transform" or "webkitTransform" + * ``` + */ + + Axes.TRANSFORM = TRANSFORM; + /** + * @name DIRECTION_NONE + * @constant + * @type {Number} + */ + + Axes.DIRECTION_NONE = DIRECTION_NONE; + /** + * @name DIRECTION_LEFT + * @constant + * @type {Number} + */ + + Axes.DIRECTION_LEFT = DIRECTION_LEFT; + /** + * @name DIRECTION_RIGHT + * @constant + * @type {Number} + */ + + Axes.DIRECTION_RIGHT = DIRECTION_RIGHT; + /** + * @name DIRECTION_UP + * @constant + * @type {Number} + */ + + Axes.DIRECTION_UP = DIRECTION_UP; + /** + * @name DIRECTION_DOWN + * @constant + * @type {Number} + */ + + Axes.DIRECTION_DOWN = DIRECTION_DOWN; + /** + * @name DIRECTION_HORIZONTAL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL; + /** + * @name DIRECTION_VERTICAL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_VERTICAL = DIRECTION_VERTICAL; + /** + * @name DIRECTION_ALL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_ALL = DIRECTION_ALL; + return Axes; + }(Component); + + /* eslint-disable @typescript-eslint/no-empty-function */ + + var getDirectionByAngle = function (angle, thresholdAngle) { + if (thresholdAngle < 0 || thresholdAngle > 90) { + return DIRECTION_NONE; + } + + var toAngle = Math.abs(angle); + return toAngle > thresholdAngle && toAngle < 180 - thresholdAngle ? DIRECTION_VERTICAL : DIRECTION_HORIZONTAL; + }; + var useDirection = function (checkType, direction, userDirection) { + if (userDirection) { + return !!(direction === DIRECTION_ALL || direction & checkType && userDirection & checkType); + } else { + return !!(direction & checkType); + } + }; + /** + * @typedef {Object} PanInputOption The option object of the eg.Axes.PanInput module. + * @ko eg.Axes.PanInput 모듈의 옵션 객체 + * @param {String[]} [inputType=["touch", "mouse", "pointer"]] Types of input devices + * - touch: Touch screen + * - mouse: Mouse + * - pointer: Mouse and touch 입력 장치 종류 + * - touch: 터치 입력 장치 + * - mouse: 마우스 + * - pointer: 마우스 및 터치 + * @param {String[]} [inputButton=["left"]] List of buttons to allow input + * - left: Left mouse button and normal touch + * - middle: Mouse wheel press + * - right: Right mouse button 입력을 허용할 버튼 목록 + * - left: 마우스 왼쪽 버튼 + * - middle: 마우스 휠 눌림 + * - right: 마우스 오른쪽 버튼 + * @param {Number[]} [scale] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [scale[0]=1] horizontal axis scale 수평축 배율 + * @param {Number} [scale[1]=1] vertical axis scale 수직축 배율 + * @param {Number} [thresholdAngle=45] The threshold value that determines whether user action is horizontal or vertical (0~90) 사용자의 동작이 가로 방향인지 세로 방향인지 판단하는 기준 각도(0~90) + * @param {Number} [threshold=0] Minimal pan distance required before recognizing 사용자의 Pan 동작을 인식하기 위해산 최소한의 거리 + * @param {Number} [iOSEdgeSwipeThreshold=30] Area (px) that can go to the next page when swiping the right edge in iOS safari iOS Safari에서 오른쪽 엣지를 스와이프 하는 경우 다음 페이지로 넘어갈 수 있는 영역(px) + * @param {String} [touchAction=null] Value that overrides the element's "touch-action" css property. If set to null, it is automatically set to prevent scrolling in the direction of the connected axis. 엘리먼트의 "touch-action" CSS 속성을 덮어쓰는 값. 만약 null로 설정된 경우, 연결된 축 방향으로의 스크롤을 방지하게끔 자동으로 설정된다. + **/ + + /** + * A module that passes the amount of change to eg.Axes when the mouse or touchscreen is down and moved. use less than two axes. + * @ko 마우스나 터치 스크린을 누르고 움직일때의 변화량을 eg.Axes에 전달하는 모듈. 두개 이하의 축을 사용한다. + * + * @example + * ```js + * const pan = new eg.Axes.PanInput("#area", { + * inputType: ["touch"], + * scale: [1, 1.3], + * }); + * + * // Connect the 'something2' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved. + * // Connect the 'somethingN' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved. + * axes.connect(["something2", "somethingN"], pan); // or axes.connect("something2 somethingN", pan); + * + * // Connect only one 'something1' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved. + * axes.connect(["something1"], pan); // or axes.connect("something1", pan); + * + * // Connect only one 'something2' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved. + * axes.connect(["", "something2"], pan); // or axes.connect(" something2", pan); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.PanInput module eg.Axes.PanInput 모듈을 사용할 엘리먼트 + * @param {PanInputOption} [options={}] The option object of the eg.Axes.PanInput moduleeg.Axes.PanInput 모듈의 옵션 객체 + */ + + var PanInput = + /*#__PURE__*/ + function () { + /** + * + */ + function PanInput(el, options) { + var _this = this; + + this.axes = []; + this.element = null; + this._enabled = false; + this._activeEvent = null; + this._atRightEdge = false; + this._rightEdgeTimer = 0; + + this._forceRelease = function () { + var activeEvent = _this._activeEvent; + var prevEvent = activeEvent.prevEvent; + activeEvent.onRelease(); + + _this._observer.release(_this, prevEvent, [0, 0]); + + _this._detachWindowEvent(activeEvent); + }; + + this._voidFunction = function () {}; + + this.element = $(el); + this.options = __assign$1({ + inputType: ["touch", "mouse", "pointer"], + inputButton: [MOUSE_LEFT], + scale: [1, 1], + thresholdAngle: 45, + threshold: 0, + iOSEdgeSwipeThreshold: IOS_EDGE_THRESHOLD, + releaseOnScroll: false, + touchAction: null + }, options); + this._onPanstart = this._onPanstart.bind(this); + this._onPanmove = this._onPanmove.bind(this); + this._onPanend = this._onPanend.bind(this); + } + + var __proto = PanInput.prototype; + + __proto.mapAxes = function (axes) { + var useHorizontal = !!axes[0]; + var useVertical = !!axes[1]; + + if (useHorizontal && useVertical) { + this._direction = DIRECTION_ALL; + } else if (useHorizontal) { + this._direction = DIRECTION_HORIZONTAL; + } else if (useVertical) { + this._direction = DIRECTION_VERTICAL; + } else { + this._direction = DIRECTION_NONE; + } + + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this._activeEvent) { + this._detachElementEvent(); + + this._detachWindowEvent(this._activeEvent); + } + + this._attachElementEvent(observer); + + this._originalCssProps = setCssProps(this.element, this.options, this._direction); + return this; + }; + + __proto.disconnect = function () { + this._detachElementEvent(); + + this._detachWindowEvent(this._activeEvent); + + if (!isCssPropsFromAxes(this._originalCssProps)) { + revertCssProps(this.element, this._originalCssProps); + } + + this._direction = DIRECTION_NONE; + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {PanInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {PanInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onPanstart = function (event) { + var activeEvent = this._activeEvent; + var panEvent = activeEvent.onEventStart(event, this.options.inputButton); + + if (!panEvent || !this._enabled || activeEvent.getTouches(event) > 1) { + return; + } + + if (panEvent.srcEvent.cancelable !== false) { + var edgeThreshold = this.options.iOSEdgeSwipeThreshold; + + this._observer.hold(this, panEvent); + + this._atRightEdge = IS_IOS_SAFARI && panEvent.center.x > window.innerWidth - edgeThreshold; + + this._attachWindowEvent(activeEvent); + + activeEvent.prevEvent = panEvent; + } + }; + + __proto._onPanmove = function (event) { + var _this = this; + + var activeEvent = this._activeEvent; + var panEvent = activeEvent.onEventMove(event, this.options.inputButton); + + if (!panEvent || !this._enabled || activeEvent.getTouches(event) > 1) { + return; + } + + var _a = this.options, + iOSEdgeSwipeThreshold = _a.iOSEdgeSwipeThreshold, + releaseOnScroll = _a.releaseOnScroll; + var userDirection = getDirectionByAngle(panEvent.angle, this.options.thresholdAngle); + + if (releaseOnScroll && !panEvent.srcEvent.cancelable) { + this._onPanend(event); + + return; + } + + if (activeEvent.prevEvent && IS_IOS_SAFARI) { + var swipeLeftToRight = panEvent.center.x < 0; + + if (swipeLeftToRight) { + // iOS swipe left => right + this._forceRelease(); + + return; + } else if (this._atRightEdge) { + clearTimeout(this._rightEdgeTimer); // - is right to left + + var swipeRightToLeft = panEvent.deltaX < -iOSEdgeSwipeThreshold; + + if (swipeRightToLeft) { + this._atRightEdge = false; + } else { + // iOS swipe right => left + this._rightEdgeTimer = window.setTimeout(function () { + return _this._forceRelease(); + }, 100); + } + } + } + + var offset = this._getOffset([panEvent.offsetX, panEvent.offsetY], [useDirection(DIRECTION_HORIZONTAL, this._direction, userDirection), useDirection(DIRECTION_VERTICAL, this._direction, userDirection)]); + + var prevent = offset.some(function (v) { + return v !== 0; + }); + + if (prevent) { + if (panEvent.srcEvent.cancelable !== false) { + panEvent.srcEvent.preventDefault(); + } + + panEvent.srcEvent.stopPropagation(); + } + + panEvent.preventSystemEvent = prevent; + + if (prevent) { + this._observer.change(this, panEvent, toAxis(this.axes, offset)); + } + + activeEvent.prevEvent = panEvent; + }; + + __proto._onPanend = function (event) { + var activeEvent = this._activeEvent; + activeEvent.onEventEnd(event); + + if (!this._enabled || activeEvent.getTouches(event) !== 0) { + return; + } + + this._detachWindowEvent(activeEvent); + + clearTimeout(this._rightEdgeTimer); + var prevEvent = activeEvent.prevEvent; + + var velocity = this._getOffset([Math.abs(prevEvent.velocityX) * (prevEvent.offsetX < 0 ? -1 : 1), Math.abs(prevEvent.velocityY) * (prevEvent.offsetY < 0 ? -1 : 1)], [useDirection(DIRECTION_HORIZONTAL, this._direction), useDirection(DIRECTION_VERTICAL, this._direction)]); + + activeEvent.onRelease(); + + this._observer.release(this, prevEvent, velocity); + }; + + __proto._attachWindowEvent = function (activeEvent) { + var _this = this; + + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + window.addEventListener(event, _this._onPanmove, { + passive: false + }); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) { + window.addEventListener(event, _this._onPanend, { + passive: false + }); + }); + }; + + __proto._detachWindowEvent = function (activeEvent) { + var _this = this; + + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + window.removeEventListener(event, _this._onPanmove); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) { + window.removeEventListener(event, _this._onPanend); + }); + }; + + __proto._getOffset = function (properties, direction) { + var offset = [0, 0]; + var scale = this.options.scale; + + if (direction[0]) { + offset[0] = properties[0] * scale[0]; + } + + if (direction[1]) { + offset[1] = properties[1] * scale[1]; + } + + return offset; + }; + + __proto._attachElementEvent = function (observer) { + var _this = this; + + var activeEvent = convertInputType(this.options.inputType); + + if (!activeEvent) { + return; + } + + this._observer = observer; + this._enabled = true; + this._activeEvent = activeEvent; + activeEvent.start.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.addEventListener(event, _this._onPanstart); + }); // adding event listener to element prevents invalid behavior in iOS Safari + + activeEvent.move.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.addEventListener(event, _this._voidFunction); + }); + }; + + __proto._detachElementEvent = function () { + var _this = this; + + var activeEvent = this._activeEvent; + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.start.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, _this._onPanstart); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, _this._voidFunction); + }); + this._enabled = false; + this._observer = null; + }; + + return PanInput; + }(); + + /* eslint-disable @typescript-eslint/no-implied-eval */ + /* eslint-disable no-new-func, no-nested-ternary */ + + var win$1 = typeof window !== "undefined" && window.Math === Math ? window : typeof self !== "undefined" && self.Math === Math ? self : Function("return this")(); + /* eslint-enable no-new-func, no-nested-ternary */ + + var doc = win$1.document; + var nav = win$1.navigator; + var agent$1 = agent(); + var osName = agent$1.os.name; + var browserName = agent$1.browser.name; + + /* eslint-disable @typescript-eslint/naming-convention */ + win$1.Float32Array = typeof win$1.Float32Array !== "undefined" ? win$1.Float32Array : win$1.Array; + var Float32Array = win$1.Float32Array; + var getComputedStyle = win$1.getComputedStyle; + var userAgent = win$1.navigator && win$1.navigator.userAgent; + var DeviceMotionEvent = win$1.DeviceMotionEvent; + var devicePixelRatio = win$1.devicePixelRatio; + + var TRANSFORM$1 = function () { + var _a; + + var docStyle = (_a = doc === null || doc === void 0 ? void 0 : doc.documentElement.style) !== null && _a !== void 0 ? _a : {}; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in docStyle) { + return target[i]; + } + } + + return ""; + }(); // check for will-change support + + + var SUPPORT_WILLCHANGE = win$1.CSS && win$1.CSS.supports && win$1.CSS.supports("will-change", "transform"); + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + var SPINVIEWER_OPTIONS = { + imageUrl: true, + rowCount: true, + colCount: true, + width: true, + height: true, + autoHeight: true, + colRow: true, + scale: true, + frameIndex: true, + wrapperClass: true, + imageClass: true + }; + var SPINVIEWER_EVENTS = { + LOAD: "load", + IMAGE_ERROR: "imageError", + CHANGE: "change", + ANIMATION_END: "animationEnd" + }; + var DEFAULT_WRAPPER_CLASS = "view360-wrapper"; + var DEFAULT_IMAGE_CLASS = "view360-image"; + + var Constants = { + __proto__: null, + SPINVIEWER_OPTIONS: SPINVIEWER_OPTIONS, + SPINVIEWER_EVENTS: SPINVIEWER_EVENTS, + DEFAULT_WRAPPER_CLASS: DEFAULT_WRAPPER_CLASS, + DEFAULT_IMAGE_CLASS: DEFAULT_IMAGE_CLASS + }; + + /** + * @memberof eg.view360 + * @extends eg.Component + * SpriteImage + */ + + var SpriteImage = + /*#__PURE__*/ + function (_super) { + __extends(SpriteImage, _super); + /** + * @class eg.view360.SpriteImage + * @classdesc A module that displays a single or continuous image of any one of the "sprite images". SpinViewer internally uses SpriteImage to show each frame of the sprite image. + * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다. + * @extends eg.Component + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the "Sprite image". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
+ * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * + * // Initialize SpriteImage + * + * var el = document.getElementById("image-div"); + * var sprites = new eg.view360.SpriteImage(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 + * }); + */ + + + function SpriteImage(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + var opt = options || {}; + _this._el = element; + _this._rowCount = opt.rowCount || 1; + _this._colCount = opt.colCount || 1; + _this._totalCount = _this._rowCount * _this._colCount; // total frames + + _this._width = opt.width || "auto"; + _this._height = opt.height || "auto"; + _this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten. + + _this._colRow = [0, 0]; + + if (opt.colRow) { + _this._colRow = opt.colRow; + } else if (opt.frameIndex) { + _this.setFrameIndex(opt.frameIndex); + } + + _this._el.style.width = SpriteImage._getSizeString(_this._width); + _this._el.style.height = SpriteImage._getSizeString(_this._height); + var wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS; + var imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS; + + if (!opt.imageUrl) { + setTimeout(function () { + _this.trigger(new ComponentEvent$1("imageError", { + imageUrl: opt.imageUrl + })); + }, 0); + return _this; + } + + var imageInContainer = element.querySelector("." + imageClass); + var wrapperInContainer = element.querySelector("." + wrapperClass); + + if (wrapperInContainer && imageInContainer) { + // Set it to invisible to prevent wrapper being resized + imageInContainer.style.display = "none"; + } + + _this._image = imageInContainer || new Image(); + /** + * Event + */ + + var image = _this._image; + + image.onload = function () { + if (wrapperInContainer && imageInContainer) { + imageInContainer.style.display = ""; + } + + _this._bg = SpriteImage._createBgDiv(wrapperInContainer, image, _this._rowCount, _this._colCount, _this._autoHeight); + + _this._el.appendChild(_this._bg); + + _this.setColRow(_this._colRow[0], _this._colRow[1]); + + _this.trigger(new ComponentEvent$1("load", { + target: _this._el, + bgElement: _this._bg + })); + + if (_this._autoPlayReservedInfo) { + _this.play(_this._autoPlayReservedInfo); + + _this._autoPlayReservedInfo = null; + } + }; + + image.onerror = function () { + _this.trigger(new ComponentEvent$1("imageError", { + imageUrl: opt.imageUrl + })); + }; + + image.src = opt.imageUrl; + return _this; + } + + var __proto = SpriteImage.prototype; + + SpriteImage._createBgDiv = function (wrapperInContainer, img, rowCount, colCount, autoHeight) { + var el = wrapperInContainer || document.createElement("div"); + el.style.position = "relative"; + el.style.overflow = "hidden"; + img.style.position = "absolute"; + img.style.width = colCount * 100 + "%"; + img.style.height = rowCount * 100 + "%"; + /** Prevent image from being dragged on IE10, IE11, Safari especially */ + + img.ondragstart = function () { + return false; + }; // img.style.pointerEvents = "none"; + // Use hardware accelerator if available + + + if (SUPPORT_WILLCHANGE) { + img.style.willChange = "transform"; + } + + el.appendChild(img); + var unitWidth = img.naturalWidth / colCount; + var unitHeight = img.naturalHeight / rowCount; + + if (autoHeight) { + var r = unitHeight / unitWidth; + el.style.paddingBottom = r * 100 + "%"; + } else { + el.style.height = "100%"; + } + + return el; + }; + + SpriteImage._getSizeString = function (size) { + if (typeof size === "number") { + return size + "px"; + } + + return size; + }; + /** + * Specifies the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정 + * @method eg.view360.SpriteImage#setFrameIndex + * @param {Number} frameIndex frame index of a frame프레임의 인덱스 + * + * @example + * + * sprites.setFrameIndex(0, 1);// col = 0, row = 1 + */ + + + __proto.setFrameIndex = function (index) { + var colRow = this.toColRow(index); + this.setColRow(colRow[0], colRow[1]); + }; + /** + * Returns the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환 + * @method eg.view360.SpriteImage#getFrameIndex + * @return {Number} frame index frame 인덱스 + * + * @example + * + * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1 + * + */ + + + __proto.getFrameIndex = function () { + return this._colRow[1] * this._colCount + this._colRow[0]; + }; + /** + * Specifies the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정 + * @method eg.view360.SpriteImage#setColRow + * @param {Number} col Column number of a frame프레임의 행값 + * @param {Number} row Row number of a frame프레임의 열값 + * + * @example + * + * sprites.setlColRow(1, 2); // col = 1, row = 2 + */ + + + __proto.setColRow = function (col, row) { + if (row > this._rowCount - 1 || col > this._colCount - 1) { + return; + } + + if (this._image && TRANSFORM$1) { + // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser? + this._image.style[TRANSFORM$1] = "translate(" + -(col / this._colCount * 100) + "%, " + -(row / this._rowCount * 100) + "%)"; + } + + this._colRow = [col, row]; + }; + /** + * Returns the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환 + * @method eg.view360.SpriteImage#gelColRow + * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열 + * + * @example + * + * var colRow = sprites.getlColRow(); + * // colRow = [1, 2] - index of col is 1, index of row is 2 + * + */ + + + __proto.getColRow = function () { + return this._colRow; + }; + /** + * Stop playing + * @ko play 되고 있던 프레임 재생을 중지합니다. + * @method eg.view360.SpriteImage#stop + * + * @example + * + * viewer.stop(); + * + */ + + + __proto.stop = function () { + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + }; + /** + * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'. + * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다. + * @method eg.view360.SpriteImage#play + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위 + * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복 + * + * @example + * + * viewer.play({angle: 16, playCount: 1}); + * + */ + + + __proto.play = function (_a) { + var _this = this; + + var _b = _a === void 0 ? { + interval: 1000 / this._totalCount, + playCount: 0 + } : _a, + interval = _b.interval, + playCount = _b.playCount; + + if (!this._bg) { + this._autoPlayReservedInfo = { + interval: interval, + playCount: playCount + }; + return; + } + + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + + var frameIndex = this.getFrameIndex(); + var count = 0; + var frameCount = 0; // for checking 1 cycle + + this._autoPlayTimer = window.setInterval(function () { + frameIndex %= _this._totalCount; + + var colRow = _this.toColRow(frameIndex); + + _this.setColRow(colRow[0], colRow[1]); + + frameIndex++; // Done 1 Cycle? + + if (++frameCount === _this._totalCount) { + frameCount = 0; + count++; + } + + if (playCount > 0 && count === playCount) { + clearInterval(_this._autoPlayTimer); + } + }, interval); + }; + + __proto.toColRow = function (frameIndex) { + var colCount = this._colCount; + var rowCount = this._rowCount; + + if (frameIndex < 0) { + return [0, 0]; + } else if (frameIndex >= this._totalCount) { + return [colCount - 1, rowCount - 1]; + } + + var col = frameIndex % colCount; + var row = Math.floor(frameIndex / colCount); // console.log(frameIndex, col, row); + + return [col, row]; + }; + + SpriteImage.VERSION = VERSION; + return SpriteImage; + }(Component); + + var DEFAULT_PAN_SCALE = 0.21; + /** + * @memberof eg.view360 + * @extends eg.Component + * SpinViewer + */ + + var SpinViewer = + /*#__PURE__*/ + function (_super) { + __extends(SpinViewer, _super); + /** + * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object. + * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다. + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값 + * @param {String} [options.wrapperClass="view360-wrapper"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @param {String} [options.imageClass="view360-image"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * ``` + * // Initialize SpinViewer + * var el = document.getElementById("product-360"); + * var viewer = new eg.view360.SpinViewer(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 //required + * }); + * ``` + */ + + + function SpinViewer(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this._el = element; + + var opt = __assign({}, options); + + var colCount = opt.colCount || 1; + var rowCount = opt.rowCount || 1; + _this._scale = opt.scale || 1; + _this._panScale = _this._scale * DEFAULT_PAN_SCALE; + _this._frameCount = colCount * rowCount; // Init SpriteImage + + _this._sprites = new SpriteImage(element, opt).on({ + "load": function (evt) { + _this.trigger(new ComponentEvent$1("load", evt)); + }, + "imageError": function (evt) { + _this.trigger(new ComponentEvent$1("imageError", { + imageUrl: evt.imageUrl + })); + } + }); // Init Axes + + _this._panInput = new PanInput(_this._el, { + scale: [_this._panScale, _this._panScale] + }); + _this._axes = new Axes({ + angle: { + range: [0, 359], + circular: true + } + }).on({ + "change": function (evt) { + var curr = Math.floor(evt.pos.angle / (360 / _this._frameCount)); + var frameIndex = _this._frameCount - curr - 1; + + _this._sprites.setFrameIndex(frameIndex); + + _this.trigger(new ComponentEvent$1("change", { + frameIndex: frameIndex, + colRow: _this._sprites.getColRow(), + angle: evt.pos.angle + })); + }, + "animationEnd": function (evt) { + _this.trigger(new ComponentEvent$1("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + + _this._axes.connect("angle", _this._panInput); + + return _this; + } + /** + * Set spin scale + * @ko scale 을 조정할 수 있는 함수 + * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.setScale(2);// It moves twice as much. + */ + + + var __proto = SpinViewer.prototype; + + __proto.setScale = function (scale) { + if (isNaN(scale) || scale < 0) { + return this; + } + + this._scale = scale; + this._panScale = scale * DEFAULT_PAN_SCALE; + this._panInput.options.scale = [this._panScale, this._panScale]; + return this; + }; + /** + * Get spin scale + * @ko scale 값을 반환한다. + * + * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @example + * viewer.getScale();// It returns number + */ + + + __proto.getScale = function () { + return this._scale; + }; + /** + * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle. + * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle상대적 회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinBy(720, {duration: 500}); + */ + + + __proto.spinBy = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setBy({ + angle: angle + }, param.duration); + + return this; + }; + /** + * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle). + * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinTo(30, {duration:100}); + */ + + + __proto.spinTo = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setTo({ + angle: angle + }, param.duration); + + return this; + }; + /** + * Returns current angles + * @ko 현재 각도를 반환한다. + * + * @return {Number} Current angle 현재 각도 + */ + + + __proto.getAngle = function () { + return this._axes.get().angle || 0; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @static + * @example + * eg.view360.SpinViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.SpinViewer + */ + + + SpinViewer.VERSION = VERSION; + return SpinViewer; + }(Component); + + /* eslint-disable @typescript-eslint/naming-convention */ + var SpinViewerModule = { + SpinViewer: SpinViewer, + SpriteImage: SpriteImage, + VERSION: VERSION + }; + merge(SpinViewerModule, Constants); + + return SpinViewerModule; + +}))); +//# sourceMappingURL=view360.spinviewer.pkgd.js.map diff --git a/dist/SpinViewer/view360.spinviewer.pkgd.js.map b/dist/SpinViewer/view360.spinviewer.pkgd.js.map new file mode 100644 index 000000000..41d6d1607 --- /dev/null +++ b/dist/SpinViewer/view360.spinviewer.pkgd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.spinviewer.pkgd.js","sources":["../../src/version.ts","../../src/utils/utils.ts","../../src/utils/browser.ts","../../src/utils/browserFeature.ts","../../src/SpinViewer/consts.ts","../../src/SpinViewer/SpriteImage.ts","../../src/SpinViewer/SpinViewer.ts","../../src/SpinViewer/index.umd.ts"],"sourcesContent":["const VERSION = \"#__VERSION__#\";\n\nexport {\n VERSION\n};\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","import { SpinViewerOptions, SpinViewerEvent } from \"./SpinViewer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const SPINVIEWER_OPTIONS: { [key in keyof SpinViewerOptions]: true } = {\n imageUrl: true,\n rowCount: true,\n colCount: true,\n width: true,\n height: true,\n autoHeight: true,\n colRow: true,\n scale: true,\n frameIndex: true,\n wrapperClass: true,\n imageClass: true\n};\n\nexport const SPINVIEWER_EVENTS: {\n [key: string]: keyof SpinViewerEvent;\n} = {\n LOAD: \"load\",\n IMAGE_ERROR: \"imageError\",\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n};\n\nexport const DEFAULT_WRAPPER_CLASS = \"view360-wrapper\";\nexport const DEFAULT_IMAGE_CLASS = \"view360-image\";\n","import Component, { ComponentEvent } from \"@egjs/component\";\n\nimport { TRANSFORM, SUPPORT_WILLCHANGE } from \"../utils/browserFeature\";\nimport { VERSION } from \"../version\";\n\nimport { SpinViewerOptions } from \"./SpinViewer\";\nimport { DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS } from \"./consts\";\n\nexport interface SpriteImageEvent {\n /**\n * Events that occur when component loading is complete\n * @ko 컴포넌트 로딩이 완료되면 발생하는 이벤트\n * @name eg.view360.SpriteImage#load\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {HTMLElement} param.target The target element for which to display the image 이미지를 보여줄 대상 엘리먼트\n * @param {HTMLElement} param.bgElement Generated background image element 생성된 background 이미지 엘리먼트\n *\n * @example\n *\n * sprites.on({\n * \"load\" : function(evt) {\n * console.log(\"load event fired - e.target\", e.target, \"e.bgElement\", e.bgElement);\n * }\n * });\n */\n load: {\n target: HTMLElement;\n bgElement: HTMLDivElement;\n };\n /**\n * An event that occurs when the image index is changed by the user's left / right panning\n * @ko 사용자의 좌우 Panning 에 의해 이미지 인덱스가 변경되었을때 발생하는 이벤트\n * @name eg.view360.SpriteImage#imageError\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {String} param.imageUrl User-specified image URL 사용자가 지정한 이미지 URL\n *\n * @example\n *\n * sprites.on({\n * \"imageError\" : function(evt) {\n * // Error handling\n * console.log(e.imageUrl);\n * }\n * });\n */\n imageError: {\n imageUrl?: string;\n };\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpriteImage\n */\nclass SpriteImage extends Component {\n private static _createBgDiv(wrapperInContainer: HTMLDivElement | null, img: HTMLImageElement, rowCount: number, colCount: number, autoHeight: boolean) {\n const el = wrapperInContainer || document.createElement(\"div\");\n\n el.style.position = \"relative\";\n el.style.overflow = \"hidden\";\n\n img.style.position = \"absolute\";\n img.style.width = `${colCount * 100}%`;\n img.style.height = `${rowCount * 100}%`;\n\n /** Prevent image from being dragged on IE10, IE11, Safari especially */\n img.ondragstart = () => (false); // img.style.pointerEvents = \"none\";\n // Use hardware accelerator if available\n if (SUPPORT_WILLCHANGE) {\n (img.style.willChange = \"transform\");\n }\n\n el.appendChild(img);\n\n const unitWidth = img.naturalWidth / colCount;\n const unitHeight = img.naturalHeight / rowCount;\n\n if (autoHeight) {\n const r = unitHeight / unitWidth;\n\n el.style.paddingBottom = `${r * 100}%`;\n } else {\n el.style.height = \"100%\";\n }\n\n return el;\n }\n\n private static _getSizeString(size) {\n if (typeof size === \"number\") {\n return `${size}px`;\n }\n\n return size;\n }\n\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _rowCount: number;\n private _colCount: number;\n private _totalCount: number;\n private _width: number | string;\n private _height: number | string;\n private _autoHeight: boolean;\n private _colRow: number[];\n private _image: HTMLImageElement;\n private _bg: HTMLDivElement;\n private _autoPlayReservedInfo: { interval: number; playCount: number } | null;\n private _autoPlayTimer: number;\n\n /**\n * @class eg.view360.SpriteImage\n * @classdesc A module that displays a single or continuous image of any one of the \"sprite images\". SpinViewer internally uses SpriteImage to show each frame of the sprite image.\n * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다.\n * @extends eg.Component\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the \"Sprite image\". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n *\n * // Initialize SpriteImage\n *\n * var el = document.getElementById(\"image-div\");\n * var sprites = new eg.view360.SpriteImage(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24\n * });\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n const opt = options || {};\n\n this._el = element;\n this._rowCount = opt.rowCount || 1;\n this._colCount = opt.colCount || 1;\n this._totalCount = this._rowCount * this._colCount; // total frames\n this._width = opt.width || \"auto\";\n this._height = opt.height || \"auto\";\n this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten.\n this._colRow = [0, 0];\n\n if (opt.colRow) {\n this._colRow = opt.colRow;\n } else if (opt.frameIndex) {\n this.setFrameIndex(opt.frameIndex);\n }\n\n this._el.style.width = SpriteImage._getSizeString(this._width);\n this._el.style.height = SpriteImage._getSizeString(this._height);\n\n const wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS;\n const imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS;\n\n if (!opt.imageUrl) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n }, 0);\n return;\n }\n\n const imageInContainer = element.querySelector(`.${imageClass}`);\n const wrapperInContainer = element.querySelector(`.${wrapperClass}`);\n\n if (wrapperInContainer && imageInContainer) {\n // Set it to invisible to prevent wrapper being resized\n imageInContainer.style.display = \"none\";\n }\n\n this._image = imageInContainer || new Image();\n /**\n * Event\n */\n\n const image = this._image;\n\n image.onload = () => {\n if (wrapperInContainer && imageInContainer) {\n imageInContainer.style.display = \"\";\n }\n\n this._bg = SpriteImage._createBgDiv(\n wrapperInContainer,\n image,\n this._rowCount,\n this._colCount,\n this._autoHeight\n );\n this._el.appendChild(this._bg);\n this.setColRow(this._colRow[0], this._colRow[1]);\n\n this.trigger(new ComponentEvent(\"load\", {\n target: this._el,\n bgElement: this._bg\n }));\n\n if (this._autoPlayReservedInfo) {\n this.play(this._autoPlayReservedInfo);\n this._autoPlayReservedInfo = null;\n }\n };\n\n image.onerror = () => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n };\n\n image.src = opt.imageUrl;\n }\n\n /**\n * Specifies the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정\n * @method eg.view360.SpriteImage#setFrameIndex\n * @param {Number} frameIndex frame index of a frame프레임의 인덱스\n *\n * @example\n *\n * sprites.setFrameIndex(0, 1);// col = 0, row = 1\n */\n public setFrameIndex(index: number) {\n const colRow = this.toColRow(index);\n\n this.setColRow(colRow[0], colRow[1]);\n }\n\n /**\n * Returns the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환\n * @method eg.view360.SpriteImage#getFrameIndex\n * @return {Number} frame index frame 인덱스\n *\n * @example\n *\n * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1\n *\n */\n public getFrameIndex() {\n return this._colRow[1] * this._colCount + this._colRow[0];\n }\n\n /**\n * Specifies the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정\n * @method eg.view360.SpriteImage#setColRow\n * @param {Number} col Column number of a frame프레임의 행값\n * @param {Number} row Row number of a frame프레임의 열값\n *\n * @example\n *\n * sprites.setlColRow(1, 2); // col = 1, row = 2\n */\n public setColRow(col: number, row: number) {\n if (row > this._rowCount - 1 || col > this._colCount - 1) {\n return;\n }\n\n if (this._image && TRANSFORM) {\n // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser?\n this._image.style[TRANSFORM] = `translate(${-(col / this._colCount * 100)}%, ${-(row / this._rowCount * 100)}%)`;\n }\n\n this._colRow = [col, row];\n }\n\n /**\n * Returns the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환\n * @method eg.view360.SpriteImage#gelColRow\n * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열\n *\n * @example\n *\n * var colRow = sprites.getlColRow();\n * // colRow = [1, 2] - index of col is 1, index of row is 2\n *\n */\n public getColRow() {\n return this._colRow;\n }\n\n /**\n * Stop playing\n * @ko play 되고 있던 프레임 재생을 중지합니다.\n * @method eg.view360.SpriteImage#stop\n *\n * @example\n *\n * viewer.stop();\n *\n */\n public stop() {\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n }\n\n /**\n * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'.\n * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다.\n * @method eg.view360.SpriteImage#play\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위\n * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복\n *\n * @example\n *\n * viewer.play({angle: 16, playCount: 1});\n *\n */\n public play({ interval, playCount } = { interval: 1000 / this._totalCount, playCount: 0 }) {\n if (!this._bg) {\n this._autoPlayReservedInfo = {interval, playCount};\n return;\n }\n\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n\n let frameIndex = this.getFrameIndex();\n let count = 0;\n let frameCount = 0; // for checking 1 cycle\n\n this._autoPlayTimer = window.setInterval(() => {\n frameIndex %= this._totalCount;\n const colRow = this.toColRow(frameIndex);\n\n this.setColRow(colRow[0], colRow[1]);\n frameIndex++;\n\n // Done 1 Cycle?\n if (++frameCount === this._totalCount) {\n frameCount = 0;\n count++;\n }\n\n if (playCount > 0 && count === playCount) {\n clearInterval(this._autoPlayTimer);\n }\n }, interval);\n }\n\n public toColRow(frameIndex: number) {\n const colCount = this._colCount;\n const rowCount = this._rowCount;\n\n if (frameIndex < 0) {\n return [0, 0];\n } else if (frameIndex >= this._totalCount) {\n return [colCount - 1, rowCount - 1];\n }\n\n const col = frameIndex % colCount;\n const row = Math.floor(frameIndex / colCount);\n\n // console.log(frameIndex, col, row);\n return [col, row];\n }\n}\n\nexport default SpriteImage;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport { VERSION } from \"../version\";\nimport { AnimationEndEvent, ChangeEvent, ImageErrorEvent, LoadEvent } from \"../types/event\";\n\nimport SpriteImage from \"./SpriteImage\";\n\nconst DEFAULT_PAN_SCALE = 0.21;\n\nexport interface SpinViewerEvent {\n load: LoadEvent;\n imageError: ImageErrorEvent;\n change: ChangeEvent;\n animationEnd: AnimationEndEvent;\n}\n\nexport interface SpinViewerOptions {\n imageUrl: string;\n rowCount: number;\n colCount: number;\n width: number | string;\n height: number | string;\n autoHeight: boolean;\n colRow: number[];\n scale: number;\n frameIndex: number;\n wrapperClass: string;\n imageClass: string;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpinViewer\n */\nclass SpinViewer extends Component {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @static\n * @example\n * eg.view360.SpinViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.SpinViewer\n */\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _sprites: SpriteImage;\n private _axes: Axes;\n private _panInput: PanInput;\n\n private _scale: number;\n private _panScale: number;\n private _frameCount: number;\n\n /**\n * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object.\n * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다.\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값\n * @param {String} [options.wrapperClass=\"view360-wrapper\"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @param {String} [options.imageClass=\"view360-image\"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n * ```\n * // Initialize SpinViewer\n * var el = document.getElementById(\"product-360\");\n * var viewer = new eg.view360.SpinViewer(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24 //required\n * });\n * ```\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n\n this._el = element;\n\n const opt = {...options};\n const colCount = opt.colCount || 1;\n const rowCount = opt.rowCount || 1;\n\n this._scale = (opt.scale || 1);\n this._panScale = this._scale * DEFAULT_PAN_SCALE;\n\n this._frameCount = colCount * rowCount;\n\n // Init SpriteImage\n this._sprites = new SpriteImage(element, opt).on({\n \"load\": evt => {\n this.trigger(new ComponentEvent(\"load\", evt));\n },\n \"imageError\": evt => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: evt.imageUrl\n }));\n }\n });\n\n // Init Axes\n this._panInput = new PanInput(this._el, {\n scale: [this._panScale, this._panScale]\n });\n this._axes = new Axes({\n angle: {\n range: [0, 359],\n circular: true\n }\n }).on({\n \"change\": evt => {\n const curr = Math.floor(evt.pos.angle / (360 / this._frameCount));\n const frameIndex = this._frameCount - curr - 1;\n\n this._sprites.setFrameIndex(frameIndex);\n\n this.trigger(new ComponentEvent(\"change\", {\n frameIndex,\n colRow: this._sprites.getColRow(),\n angle: evt.pos.angle\n }));\n },\n \"animationEnd\": evt => {\n this.trigger(new ComponentEvent(\"animationEnd\", {\n isTrusted: evt.isTrusted\n }));\n }\n });\n\n this._axes.connect(\"angle\", this._panInput);\n }\n\n /**\n * Set spin scale\n * @ko scale 을 조정할 수 있는 함수\n * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.setScale(2);// It moves twice as much.\n */\n public setScale(scale: number) {\n if (isNaN(scale) || scale < 0) {\n return this;\n }\n\n this._scale = scale;\n this._panScale = scale * DEFAULT_PAN_SCALE;\n this._panInput.options.scale = [this._panScale, this._panScale];\n\n return this;\n }\n\n /**\n * Get spin scale\n * @ko scale 값을 반환한다.\n *\n * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @example\n * viewer.getScale();// It returns number\n */\n public getScale() {\n return this._scale;\n }\n\n /**\n * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle.\n * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle상대적 회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinBy(720, {duration: 500});\n */\n public spinBy(angle = 0, param = {duration: 0}) {\n this._axes.setBy({angle}, param.duration);\n return this;\n }\n\n /**\n * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle).\n * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinTo(30, {duration:100});\n */\n public spinTo(angle = 0, param = {duration: 0}) {\n this._axes.setTo({angle}, param.duration);\n return this;\n }\n\n /**\n * Returns current angles\n * @ko 현재 각도를 반환한다.\n *\n * @return {Number} Current angle 현재 각도\n */\n public getAngle() {\n return this._axes.get().angle || 0;\n }\n}\n\nexport default SpinViewer;\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { VERSION } from \"../version\";\nimport { merge } from \"../utils/utils\";\n\nimport SpinViewer from \"./SpinViewer\";\nimport SpriteImage from \"./SpriteImage\";\nimport * as Constants from \"./consts\";\n\nconst SpinViewerModule = {\n SpinViewer,\n SpriteImage,\n VERSION\n};\n\nmerge(SpinViewerModule, Constants);\n\nexport default SpinViewerModule;\n"],"names":["VERSION","merge","target","_i","srcs","forEach","source","Object","keys","key","value","Array","isArray","win","window","Math","self","Function","doc","document","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","Float32Array","getComputedStyle","userAgent","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","i","len","length","SUPPORT_WILLCHANGE","CSS","supports","SPINVIEWER_OPTIONS","imageUrl","rowCount","colCount","width","height","autoHeight","colRow","scale","frameIndex","wrapperClass","imageClass","SPINVIEWER_EVENTS","LOAD","IMAGE_ERROR","CHANGE","ANIMATION_END","DEFAULT_WRAPPER_CLASS","DEFAULT_IMAGE_CLASS","__extends","element","options","_super","opt","_this","_el","_rowCount","_colCount","_totalCount","_width","_height","_autoHeight","_colRow","setFrameIndex","SpriteImage","_getSizeString","setTimeout","trigger","ComponentEvent","imageInContainer","querySelector","wrapperInContainer","display","_image","Image","image","onload","_bg","_createBgDiv","appendChild","setColRow","bgElement","_autoPlayReservedInfo","play","onerror","src","img","el","createElement","position","overflow","ondragstart","willChange","unitWidth","naturalWidth","unitHeight","naturalHeight","r","paddingBottom","size","index","toColRow","col","row","_autoPlayTimer","clearInterval","_a","_b","interval","playCount","getFrameIndex","count","frameCount","setInterval","floor","Component","DEFAULT_PAN_SCALE","_scale","_panScale","_frameCount","_sprites","on","evt","_panInput","PanInput","_axes","Axes","angle","range","circular","curr","pos","getColRow","isTrusted","connect","isNaN","param","duration","setBy","setTo","get","SpinViewer","SpinViewerModule","Constants"],"mappings":";;;;;;;;;;;;;;EAAA,IAAMA,OAAO,GAAG,OAAhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECIO,IAAMC,KAAK,GAAG,UAAyCC,MAAzC;EAAuD,eAAA;;SAAA,YAAAC,uBAAAA;EAAAC,IAAAA,YAAA,gBAAA;;;EAC1EA,EAAAA,IAAI,CAACC,OAAL,CAAa,UAAAC,MAAA;EACZC,IAAAA,MAAM,CAACC,IAAP,CAAYF,MAAZ,EAAoBD,OAApB,CAA4B,UAAAI,GAAA;EACzB,UAAMC,KAAK,GAAGJ,MAAM,CAACG,GAAD,CAApB;;EACA,UAAIE,KAAK,CAACC,OAAN,CAAcV,MAAM,CAACO,GAAD,CAApB,KAA8BE,KAAK,CAACC,OAAN,CAAcF,KAAd,CAAlC,EAAwD;EACtDR,QAAAA,MAAM,CAACO,GAAD,CAAN,YAAkBP,MAAM,CAACO,GAAD,GAAUC,MAAlC;EACD,OAFD,MAEO;EACLR,QAAAA,MAAM,CAACO,GAAD,CAAN,GAAcC,KAAd;EACD;EACH,KAPD;EAQA,GATD;EAWA,SAAOR,MAAP;EACD,CAbM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"} \ No newline at end of file diff --git a/dist/SpinViewer/view360.spinviewer.pkgd.min.js b/dist/SpinViewer/view360.spinviewer.pkgd.min.js new file mode 100644 index 000000000..4de0228ab --- /dev/null +++ b/dist/SpinViewer/view360.spinviewer.pkgd.min.js @@ -0,0 +1,10 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((t="undefined"!=typeof globalThis?globalThis:t||self).eg=t.eg||{},t.eg.view360=n())}(this,function(){"use strict";var e="3.6.3",i=function(t,n){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var e in n)n.hasOwnProperty(e)&&(t[e]=n[e])})(t,n)};function r(t,n){function e(){this.constructor=t}i(t,n),t.prototype=null===n?Object.create(n):(e.prototype=n.prototype,new e)}var a=function(){return(a=Object.assign||function(t){for(var n,e=1,i=arguments.length;e=t.length&&(t=void 0),{value:t&&t[i++],done:!t}}};throw new TypeError(n?"Object is not iterable.":"Symbol.iterator is not defined.")}function s(){for(var t=[],n=0;n]*)>/)?((e=document.createElement("div")).innerHTML=t,T(e.childNodes)):T(document.querySelectorAll(t)),n||(e=1<=e.length?e[0]:void 0)):t!==A&&(!t.nodeName||1!==t.nodeType&&9!==t.nodeType)?"jQuery"in A&&t instanceof jQuery||t.constructor.prototype.jquery?e=n?t.toArray():t.get(0):Array.isArray(t)&&(e=t.map(function(t){return L(t)}),n||(e=1<=e.length?e[0]:void 0)):e=t,e},F=A.requestAnimationFrame||A.webkitRequestAnimationFrame,V=A.cancelAnimationFrame||A.webkitCancelAnimationFrame;F&&!V?(I={},C=F,F=function(n){var e=C(function(t){I[e]&&n(t)});return I[e]=!0,e},V=function(t){delete I[t]}):F&&V||(F=function(t){return A.setTimeout(function(){t(A.performance&&A.performance.now&&A.performance.now()||(new Date).getTime())},16)},V=A.clearTimeout);function X(t,n){var e,i={};for(e in t)e&&(i[e]=n(t[e],e));return i}function Y(t,n){var e,i={};for(e in t)e&&n(t[e],e)&&(i[e]=t[e]);return i}function H(t,n){for(var e in t)if(e&&!n(t[e],e))return!1;return!0}function U(t,e){return H(t,function(t,n){return t===e[n]})}function W(t,n){return nt[n]||(nt[n]=et(n)),nt[n](t)}function q(t,e){return t&&e?X(t,function(t,n){return W(t,"number"==typeof e?e:e[n])}):t}function z(t){if(!isFinite(t))return 0;var n=""+t;if(0<=n.indexOf("e")){for(var e=0,i=1;Math.round(t*i)/i!==t;)i*=10,e++;return e}return 0<=n.indexOf(".")?n.length-n.indexOf(".")-1:0}function G(t,n,e,i){return n=[!e[0]&&i?n[0]-i[0]:n[0],!e[1]&&i?n[1]+i[1]:n[1]],t=Math.max(n[0],t),t=Math.min(n[1],t)}function Q(t,n){return tn[1]}function Z(t,n,e){return e[1]&&t>n[1]||e[0]&&tn.range[1]&&0!==n.bounce[1]?(t-n.range[1])/n.bounce[1]:0})},t}(),rt=function(){function t(t){this._options=t,this._prevented=!1}var n=t.prototype;return n.isInterrupting=function(){return this._options.interruptable||this._prevented},n.isInterrupted=function(){return!this._options.interruptable&&this._prevented},n.setInterrupt=function(t){this._options.interruptable||(this._prevented=t)},t}(),ot=function(){function t(t){var e=this;this._axis=t,this._complementOptions(),this._pos=Object.keys(this._axis).reduce(function(t,n){return t[n]=e._axis[n].range[0],t},{})}var n=t.prototype;return n.getDelta=function(t,n){var e=this.get(t);return X(this.get(n),function(t,n){return t-e[n]})},n.get=function(t){var e=this;return t&&Array.isArray(t)?t.reduce(function(t,n){return n&&n in e._pos&&(t[n]=e._pos[n]),t},{}):O(O({},this._pos),t||{})},n.moveTo=function(e,i){void 0===i&&(i=this._pos);var t=X(this._pos,function(t,n){return n in e&&n in i?e[n]-i[n]:0});return this.set(this.map(e,function(t,n){return n?J(t,n.range,n.circular):0})),{pos:O({},this._pos),delta:t}},n.set=function(t){for(var n in t)n&&n in this._pos&&(this._pos[n]=t[n])},n.every=function(t,e){var i=this._axis;return H(t,function(t,n){return e(t,i[n],n)})},n.filter=function(t,e){var i=this._axis;return Y(t,function(t,n){return e(t,i[n],n)})},n.map=function(t,e){var i=this._axis;return X(t,function(t,n){return e(t,i[n],n)})},n.isOutside=function(t){return!this.every(t?this.get(t):this._pos,function(t,n){return!Q(t,n.range)})},n.getAxisOptions=function(t){return this._axis[t]},n._complementOptions=function(){var r=this;Object.keys(this._axis).forEach(function(i){r._axis[i]=O({range:[0,100],bounce:[0,0],circular:[!1,!1]},r._axis[i]),["bounce","circular"].forEach(function(t){var n=r._axis,e=n[i][t];/string|number|boolean/.test(typeof e)&&(n[i][t]=[e,e])})})},t}(),at="ontouchstart"in A,st="PointerEvent"in A,ut="MSPointerEvent"in A,ct=st||ut,ht=function(){function t(){var n=this;this._stopContextMenu=function(t){t.preventDefault(),A.removeEventListener("contextmenu",n._stopContextMenu)}}var n=t.prototype;return n.extendEvent=function(t){var n=this.prevEvent,e=this._getCenter(t),i=n?this._getMovement(t):{x:0,y:0},r=n?this._getScale(t):1,o=n?(f=e.x-n.center.x,l=e.y-n.center.y,180*Math.atan2(l,f)/Math.PI):0,a=n?n.deltaX+i.x:i.x,s=n?n.deltaY+i.y:i.y,u=i.x,c=i.y,h=this._latestInterval,l=Date.now(),f=h?l-h.timestamp:0,i=n?n.velocityX:0,n=n?n.velocityY:0;return(!h||16<=f)&&(h&&(i=(f=[(a-h.deltaX)/f,(s-h.deltaY)/f])[0],n=f[1]),this._latestInterval={timestamp:l,deltaX:a,deltaY:s}),{srcEvent:t,scale:r,angle:o,center:e,deltaX:a,deltaY:s,offsetX:u,offsetY:c,velocityX:i,velocityY:n,preventSystemEvent:!0}},n._getDistance=function(t,n){var e=n.clientX-t.clientX,t=n.clientY-t.clientY;return Math.sqrt(e*e+t*t)},n._getButton=function(t){var n={1:R,2:D,4:j},t=this._isTouchEvent(t)?R:n[t.buttons];return t||null},n._isTouchEvent=function(t){return-1=e[n]-1e-6&&t<=e[n]+1e-6)return e[n];n=i._getRoundUnit(t,n);return W(t,n)})},n._getRoundUnit=function(t,n){var e=this._options.round,i=null;return e||(n=this.axisManager.getAxisOptions(n),t=Math.max(z(n.range[0]),z(n.range[1]),z(t)),i=1/Math.pow(10,t)),i||e},t}()),pt=function(r){function t(t,n,e){void 0===t&&(t={}),void 0===n&&(n={}),void 0===e&&(e=null);var i=r.call(this)||this;return i.axis=t,i._inputs=[],i.options=O({easing:function(t){return 1-Math.pow(1-t,3)},interruptable:!0,maximumDuration:1/0,minimumDuration:0,deceleration:6e-4,round:null,nested:!1},n),i.interruptManager=new rt(i.options),i.axisManager=new ot(i.axis),i.eventManager=new it(i),i.animationManager=new _t(i),i.inputObserver=new gt(i),i.eventManager.setAnimationManager(i.animationManager),e&&i.eventManager.triggerChange(e),i}P(t,r);var n=t.prototype;return n.connect=function(t,n){t="string"==typeof t?t.split(" "):t.concat();return~this._inputs.indexOf(n)&&this.disconnect(n),n.mapAxes(t),n.connect(this.inputObserver),this._inputs.push(n),this},n.disconnect=function(t){return t?0<=(t=this._inputs.indexOf(t))&&(this._inputs[t].disconnect(),this._inputs.splice(t,1)):(this._inputs.forEach(function(t){return t.disconnect()}),this._inputs=[]),this},n.get=function(t){return this.axisManager.get(t)},n.setTo=function(t,n){return void 0===n&&(n=0),this.animationManager.setTo(t,n),this},n.setBy=function(t,n){return void 0===n&&(n=0),this.animationManager.setBy(t,n),this},n.stopAnimation=function(){return this.animationManager.stopAnimation(),this},n.updateAnimation=function(t){return this.animationManager.updateAnimation(t),this},n.isBounceArea=function(t){return this.axisManager.isOutside(t)},n.destroy=function(){this.disconnect(),this.eventManager.destroy()},t.VERSION="3.3.0",t.TRANSFORM=N,t.DIRECTION_NONE=1,t.DIRECTION_LEFT=2,t.DIRECTION_RIGHT=4,t.DIRECTION_UP=8,t.DIRECTION_DOWN=16,t.DIRECTION_HORIZONTAL=6,t.DIRECTION_VERTICAL=S,t.DIRECTION_ALL=30,t}(t),mt=function(){function t(t,n){var e=this;this.axes=[],this.element=null,this._enabled=!1,this._activeEvent=null,this._atRightEdge=!1,this._rightEdgeTimer=0,this._forceRelease=function(){var t=e._activeEvent,n=t.prevEvent;t.onRelease(),e._observer.release(e,n,[0,0]),e._detachWindowEvent(t)},this._voidFunction=function(){},this.element=L(t),this.options=O({inputType:["touch","mouse","pointer"],inputButton:[R],scale:[1,1],thresholdAngle:45,threshold:0,iOSEdgeSwipeThreshold:30,releaseOnScroll:!1,touchAction:null},n),this._onPanstart=this._onPanstart.bind(this),this._onPanmove=this._onPanmove.bind(this),this._onPanend=this._onPanend.bind(this)}var n=t.prototype;return n.mapAxes=function(t){var n=!!t[0],e=!!t[1];this._direction=n&&e?30:n?6:e?S:1,this.axes=t},n.connect=function(t){var n,e,i,r,o;return this._activeEvent&&(this._detachElementEvent(),this._detachWindowEvent(this._activeEvent)),this._attachElementEvent(t),this._originalCssProps=(n=this.element,e=this.options,i=this._direction,(t={})[1]="auto",t[30]="none",t[S]="pan-x",t[6]="pan-y",t,o={},n&&n.style&&(i=e.touchAction||t[i],r=O(O({},k),{"touch-action":"none"===n.style["touch-action"]?"none":i}),Object.keys(r).forEach(function(t){o[t]=n.style[t],n.style[t]=r[t]})),o),this},n.disconnect=function(){var n,e,i,r;return this._detachElementEvent(),this._detachWindowEvent(this._activeEvent),i=this._originalCssProps,r=!0,Object.keys(k).forEach(function(t){i&&i[t]===k[t]||(r=!1)}),r||(n=this.element,e=this._originalCssProps,n&&n.style&&e&&Object.keys(e).forEach(function(t){n.style[t]=e[t]})),this._direction=1,this},n.destroy=function(){this.disconnect(),this.element=null},n.enable=function(){return this._enabled=!0,this},n.disable=function(){return this._enabled=!1,this},n.isEnabled=function(){return this._enabled},n._onPanstart=function(t){var n=this._activeEvent,e=n.onEventStart(t,this.options.inputButton);!e||!this._enabled||1window.innerWidth-t,this._attachWindowEvent(n),n.prevEvent=e)},n._onPanmove=function(t){var n=this,e=this._activeEvent,i=e.onEventMove(t,this.options.inputButton);if(i&&this._enabled&&!(1this._rowCount-1||t>this._colCount-1||(this._image&&Et&&(this._image.style[Et]="translate("+-(t/this._colCount)*100+"%, "+-(n/this._rowCount)*100+"%)"),this._colRow=[t,n])},t.getColRow=function(){return this._colRow},t.stop=function(){this._autoPlayTimer&&(clearInterval(this._autoPlayTimer),this._autoPlayTimer=-1)},t.play=function(t){var n,e,i,r=this,o=void 0===t?{interval:1e3/this._totalCount,playCount:0}:t,t=o.interval,a=o.playCount;this._bg?(this._autoPlayTimer&&(clearInterval(this._autoPlayTimer),this._autoPlayTimer=-1),n=this.getFrameIndex(),i=e=0,this._autoPlayTimer=window.setInterval(function(){n%=r._totalCount;var t=r.toColRow(n);r.setColRow(t[0],t[1]),n++,++i===r._totalCount&&(i=0,e++),0=this._totalCount?[n-1,e-1]:[t%n,Math.floor(t/n)]},c.VERSION=e,c}(t),t={SpinViewer:function(o){function t(t,n){void 0===n&&(n={});var e=o.call(this)||this;e._el=t;var i=a({},n),r=i.colCount||1,n=i.rowCount||1;return e._scale=i.scale||1,e._panScale=.21*e._scale,e._frameCount=r*n,e._sprites=new bt(t,i).on({load:function(t){e.trigger(new f("load",t))},imageError:function(t){e.trigger(new f("imageError",{imageUrl:t.imageUrl}))}}),e._panInput=new mt(e._el,{scale:[e._panScale,e._panScale]}),e._axes=new pt({angle:{range:[0,359],circular:!0}}).on({change:function(t){var n=Math.floor(t.pos.angle/(360/e._frameCount)),n=e._frameCount-n-1;e._sprites.setFrameIndex(n),e.trigger(new f("change",{frameIndex:n,colRow:e._sprites.getColRow(),angle:t.pos.angle}))},animationEnd:function(t){e.trigger(new f("animationEnd",{isTrusted:t.isTrusted}))}}),e._axes.connect("angle",e._panInput),e}r(t,o);var n=t.prototype;return n.setScale=function(t){return isNaN(t)||t<0||(this._scale=t,this._panScale=.21*t,this._panInput.options.scale=[this._panScale,this._panScale]),this},n.getScale=function(){return this._scale},n.spinBy=function(t,n){return void 0===t&&(t=0),void 0===n&&(n={duration:0}),this._axes.setBy({angle:t},n.duration),this},n.spinTo=function(t,n){return void 0===t&&(t=0),void 0===n&&(n={duration:0}),this._axes.setTo({angle:t},n.duration),this},n.getAngle=function(){return this._axes.get().angle||0},t.VERSION=e,t}(t),SpriteImage:bt,VERSION:e};return function(i){for(var t=[],n=1;n {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","import { SpinViewerOptions, SpinViewerEvent } from \"./SpinViewer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const SPINVIEWER_OPTIONS: { [key in keyof SpinViewerOptions]: true } = {\n imageUrl: true,\n rowCount: true,\n colCount: true,\n width: true,\n height: true,\n autoHeight: true,\n colRow: true,\n scale: true,\n frameIndex: true,\n wrapperClass: true,\n imageClass: true\n};\n\nexport const SPINVIEWER_EVENTS: {\n [key: string]: keyof SpinViewerEvent;\n} = {\n LOAD: \"load\",\n IMAGE_ERROR: \"imageError\",\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n};\n\nexport const DEFAULT_WRAPPER_CLASS = \"view360-wrapper\";\nexport const DEFAULT_IMAGE_CLASS = \"view360-image\";\n","import Component, { ComponentEvent } from \"@egjs/component\";\n\nimport { TRANSFORM, SUPPORT_WILLCHANGE } from \"../utils/browserFeature\";\nimport { VERSION } from \"../version\";\n\nimport { SpinViewerOptions } from \"./SpinViewer\";\nimport { DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS } from \"./consts\";\n\nexport interface SpriteImageEvent {\n /**\n * Events that occur when component loading is complete\n * @ko 컴포넌트 로딩이 완료되면 발생하는 이벤트\n * @name eg.view360.SpriteImage#load\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {HTMLElement} param.target The target element for which to display the image 이미지를 보여줄 대상 엘리먼트\n * @param {HTMLElement} param.bgElement Generated background image element 생성된 background 이미지 엘리먼트\n *\n * @example\n *\n * sprites.on({\n * \"load\" : function(evt) {\n * console.log(\"load event fired - e.target\", e.target, \"e.bgElement\", e.bgElement);\n * }\n * });\n */\n load: {\n target: HTMLElement;\n bgElement: HTMLDivElement;\n };\n /**\n * An event that occurs when the image index is changed by the user's left / right panning\n * @ko 사용자의 좌우 Panning 에 의해 이미지 인덱스가 변경되었을때 발생하는 이벤트\n * @name eg.view360.SpriteImage#imageError\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {String} param.imageUrl User-specified image URL 사용자가 지정한 이미지 URL\n *\n * @example\n *\n * sprites.on({\n * \"imageError\" : function(evt) {\n * // Error handling\n * console.log(e.imageUrl);\n * }\n * });\n */\n imageError: {\n imageUrl?: string;\n };\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpriteImage\n */\nclass SpriteImage extends Component {\n private static _createBgDiv(wrapperInContainer: HTMLDivElement | null, img: HTMLImageElement, rowCount: number, colCount: number, autoHeight: boolean) {\n const el = wrapperInContainer || document.createElement(\"div\");\n\n el.style.position = \"relative\";\n el.style.overflow = \"hidden\";\n\n img.style.position = \"absolute\";\n img.style.width = `${colCount * 100}%`;\n img.style.height = `${rowCount * 100}%`;\n\n /** Prevent image from being dragged on IE10, IE11, Safari especially */\n img.ondragstart = () => (false); // img.style.pointerEvents = \"none\";\n // Use hardware accelerator if available\n if (SUPPORT_WILLCHANGE) {\n (img.style.willChange = \"transform\");\n }\n\n el.appendChild(img);\n\n const unitWidth = img.naturalWidth / colCount;\n const unitHeight = img.naturalHeight / rowCount;\n\n if (autoHeight) {\n const r = unitHeight / unitWidth;\n\n el.style.paddingBottom = `${r * 100}%`;\n } else {\n el.style.height = \"100%\";\n }\n\n return el;\n }\n\n private static _getSizeString(size) {\n if (typeof size === \"number\") {\n return `${size}px`;\n }\n\n return size;\n }\n\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _rowCount: number;\n private _colCount: number;\n private _totalCount: number;\n private _width: number | string;\n private _height: number | string;\n private _autoHeight: boolean;\n private _colRow: number[];\n private _image: HTMLImageElement;\n private _bg: HTMLDivElement;\n private _autoPlayReservedInfo: { interval: number; playCount: number } | null;\n private _autoPlayTimer: number;\n\n /**\n * @class eg.view360.SpriteImage\n * @classdesc A module that displays a single or continuous image of any one of the \"sprite images\". SpinViewer internally uses SpriteImage to show each frame of the sprite image.\n * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다.\n * @extends eg.Component\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the \"Sprite image\". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n *\n * // Initialize SpriteImage\n *\n * var el = document.getElementById(\"image-div\");\n * var sprites = new eg.view360.SpriteImage(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24\n * });\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n const opt = options || {};\n\n this._el = element;\n this._rowCount = opt.rowCount || 1;\n this._colCount = opt.colCount || 1;\n this._totalCount = this._rowCount * this._colCount; // total frames\n this._width = opt.width || \"auto\";\n this._height = opt.height || \"auto\";\n this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten.\n this._colRow = [0, 0];\n\n if (opt.colRow) {\n this._colRow = opt.colRow;\n } else if (opt.frameIndex) {\n this.setFrameIndex(opt.frameIndex);\n }\n\n this._el.style.width = SpriteImage._getSizeString(this._width);\n this._el.style.height = SpriteImage._getSizeString(this._height);\n\n const wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS;\n const imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS;\n\n if (!opt.imageUrl) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n }, 0);\n return;\n }\n\n const imageInContainer = element.querySelector(`.${imageClass}`);\n const wrapperInContainer = element.querySelector(`.${wrapperClass}`);\n\n if (wrapperInContainer && imageInContainer) {\n // Set it to invisible to prevent wrapper being resized\n imageInContainer.style.display = \"none\";\n }\n\n this._image = imageInContainer || new Image();\n /**\n * Event\n */\n\n const image = this._image;\n\n image.onload = () => {\n if (wrapperInContainer && imageInContainer) {\n imageInContainer.style.display = \"\";\n }\n\n this._bg = SpriteImage._createBgDiv(\n wrapperInContainer,\n image,\n this._rowCount,\n this._colCount,\n this._autoHeight\n );\n this._el.appendChild(this._bg);\n this.setColRow(this._colRow[0], this._colRow[1]);\n\n this.trigger(new ComponentEvent(\"load\", {\n target: this._el,\n bgElement: this._bg\n }));\n\n if (this._autoPlayReservedInfo) {\n this.play(this._autoPlayReservedInfo);\n this._autoPlayReservedInfo = null;\n }\n };\n\n image.onerror = () => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n };\n\n image.src = opt.imageUrl;\n }\n\n /**\n * Specifies the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정\n * @method eg.view360.SpriteImage#setFrameIndex\n * @param {Number} frameIndex frame index of a frame프레임의 인덱스\n *\n * @example\n *\n * sprites.setFrameIndex(0, 1);// col = 0, row = 1\n */\n public setFrameIndex(index: number) {\n const colRow = this.toColRow(index);\n\n this.setColRow(colRow[0], colRow[1]);\n }\n\n /**\n * Returns the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환\n * @method eg.view360.SpriteImage#getFrameIndex\n * @return {Number} frame index frame 인덱스\n *\n * @example\n *\n * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1\n *\n */\n public getFrameIndex() {\n return this._colRow[1] * this._colCount + this._colRow[0];\n }\n\n /**\n * Specifies the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정\n * @method eg.view360.SpriteImage#setColRow\n * @param {Number} col Column number of a frame프레임의 행값\n * @param {Number} row Row number of a frame프레임의 열값\n *\n * @example\n *\n * sprites.setlColRow(1, 2); // col = 1, row = 2\n */\n public setColRow(col: number, row: number) {\n if (row > this._rowCount - 1 || col > this._colCount - 1) {\n return;\n }\n\n if (this._image && TRANSFORM) {\n // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser?\n this._image.style[TRANSFORM] = `translate(${-(col / this._colCount * 100)}%, ${-(row / this._rowCount * 100)}%)`;\n }\n\n this._colRow = [col, row];\n }\n\n /**\n * Returns the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환\n * @method eg.view360.SpriteImage#gelColRow\n * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열\n *\n * @example\n *\n * var colRow = sprites.getlColRow();\n * // colRow = [1, 2] - index of col is 1, index of row is 2\n *\n */\n public getColRow() {\n return this._colRow;\n }\n\n /**\n * Stop playing\n * @ko play 되고 있던 프레임 재생을 중지합니다.\n * @method eg.view360.SpriteImage#stop\n *\n * @example\n *\n * viewer.stop();\n *\n */\n public stop() {\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n }\n\n /**\n * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'.\n * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다.\n * @method eg.view360.SpriteImage#play\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위\n * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복\n *\n * @example\n *\n * viewer.play({angle: 16, playCount: 1});\n *\n */\n public play({ interval, playCount } = { interval: 1000 / this._totalCount, playCount: 0 }) {\n if (!this._bg) {\n this._autoPlayReservedInfo = {interval, playCount};\n return;\n }\n\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n\n let frameIndex = this.getFrameIndex();\n let count = 0;\n let frameCount = 0; // for checking 1 cycle\n\n this._autoPlayTimer = window.setInterval(() => {\n frameIndex %= this._totalCount;\n const colRow = this.toColRow(frameIndex);\n\n this.setColRow(colRow[0], colRow[1]);\n frameIndex++;\n\n // Done 1 Cycle?\n if (++frameCount === this._totalCount) {\n frameCount = 0;\n count++;\n }\n\n if (playCount > 0 && count === playCount) {\n clearInterval(this._autoPlayTimer);\n }\n }, interval);\n }\n\n public toColRow(frameIndex: number) {\n const colCount = this._colCount;\n const rowCount = this._rowCount;\n\n if (frameIndex < 0) {\n return [0, 0];\n } else if (frameIndex >= this._totalCount) {\n return [colCount - 1, rowCount - 1];\n }\n\n const col = frameIndex % colCount;\n const row = Math.floor(frameIndex / colCount);\n\n // console.log(frameIndex, col, row);\n return [col, row];\n }\n}\n\nexport default SpriteImage;\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { VERSION } from \"../version\";\nimport { merge } from \"../utils/utils\";\n\nimport SpinViewer from \"./SpinViewer\";\nimport SpriteImage from \"./SpriteImage\";\nimport * as Constants from \"./consts\";\n\nconst SpinViewerModule = {\n SpinViewer,\n SpriteImage,\n VERSION\n};\n\nmerge(SpinViewerModule, Constants);\n\nexport default SpinViewerModule;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport { VERSION } from \"../version\";\nimport { AnimationEndEvent, ChangeEvent, ImageErrorEvent, LoadEvent } from \"../types/event\";\n\nimport SpriteImage from \"./SpriteImage\";\n\nconst DEFAULT_PAN_SCALE = 0.21;\n\nexport interface SpinViewerEvent {\n load: LoadEvent;\n imageError: ImageErrorEvent;\n change: ChangeEvent;\n animationEnd: AnimationEndEvent;\n}\n\nexport interface SpinViewerOptions {\n imageUrl: string;\n rowCount: number;\n colCount: number;\n width: number | string;\n height: number | string;\n autoHeight: boolean;\n colRow: number[];\n scale: number;\n frameIndex: number;\n wrapperClass: string;\n imageClass: string;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpinViewer\n */\nclass SpinViewer extends Component {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @static\n * @example\n * eg.view360.SpinViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.SpinViewer\n */\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _sprites: SpriteImage;\n private _axes: Axes;\n private _panInput: PanInput;\n\n private _scale: number;\n private _panScale: number;\n private _frameCount: number;\n\n /**\n * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object.\n * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다.\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값\n * @param {String} [options.wrapperClass=\"view360-wrapper\"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @param {String} [options.imageClass=\"view360-image\"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n * ```\n * // Initialize SpinViewer\n * var el = document.getElementById(\"product-360\");\n * var viewer = new eg.view360.SpinViewer(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24 //required\n * });\n * ```\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n\n this._el = element;\n\n const opt = {...options};\n const colCount = opt.colCount || 1;\n const rowCount = opt.rowCount || 1;\n\n this._scale = (opt.scale || 1);\n this._panScale = this._scale * DEFAULT_PAN_SCALE;\n\n this._frameCount = colCount * rowCount;\n\n // Init SpriteImage\n this._sprites = new SpriteImage(element, opt).on({\n \"load\": evt => {\n this.trigger(new ComponentEvent(\"load\", evt));\n },\n \"imageError\": evt => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: evt.imageUrl\n }));\n }\n });\n\n // Init Axes\n this._panInput = new PanInput(this._el, {\n scale: [this._panScale, this._panScale]\n });\n this._axes = new Axes({\n angle: {\n range: [0, 359],\n circular: true\n }\n }).on({\n \"change\": evt => {\n const curr = Math.floor(evt.pos.angle / (360 / this._frameCount));\n const frameIndex = this._frameCount - curr - 1;\n\n this._sprites.setFrameIndex(frameIndex);\n\n this.trigger(new ComponentEvent(\"change\", {\n frameIndex,\n colRow: this._sprites.getColRow(),\n angle: evt.pos.angle\n }));\n },\n \"animationEnd\": evt => {\n this.trigger(new ComponentEvent(\"animationEnd\", {\n isTrusted: evt.isTrusted\n }));\n }\n });\n\n this._axes.connect(\"angle\", this._panInput);\n }\n\n /**\n * Set spin scale\n * @ko scale 을 조정할 수 있는 함수\n * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.setScale(2);// It moves twice as much.\n */\n public setScale(scale: number) {\n if (isNaN(scale) || scale < 0) {\n return this;\n }\n\n this._scale = scale;\n this._panScale = scale * DEFAULT_PAN_SCALE;\n this._panInput.options.scale = [this._panScale, this._panScale];\n\n return this;\n }\n\n /**\n * Get spin scale\n * @ko scale 값을 반환한다.\n *\n * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @example\n * viewer.getScale();// It returns number\n */\n public getScale() {\n return this._scale;\n }\n\n /**\n * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle.\n * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle상대적 회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinBy(720, {duration: 500});\n */\n public spinBy(angle = 0, param = {duration: 0}) {\n this._axes.setBy({angle}, param.duration);\n return this;\n }\n\n /**\n * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle).\n * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinTo(30, {duration:100});\n */\n public spinTo(angle = 0, param = {duration: 0}) {\n this._axes.setTo({angle}, param.duration);\n return this;\n }\n\n /**\n * Returns current angles\n * @ko 현재 각도를 반환한다.\n *\n * @return {Number} Current angle 현재 각도\n */\n public getAngle() {\n return this._axes.get().angle || 0;\n }\n}\n\nexport default SpinViewer;\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n"],"names":["VERSION","win","window","Math","self","Function","doc","document","agent","navigator","getAgent","os","name","browser","Float32Array","Array","getComputedStyle","userAgent","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","target","i","len","length","SUPPORT_WILLCHANGE","CSS","supports","DEFAULT_WRAPPER_CLASS","DEFAULT_IMAGE_CLASS","imageUrl","rowCount","colCount","width","height","autoHeight","colRow","scale","frameIndex","wrapperClass","imageClass","LOAD","IMAGE_ERROR","CHANGE","ANIMATION_END","element","options","_super","opt","_this","_el","_rowCount","_colCount","_totalCount","_width","_height","_autoHeight","_colRow","setFrameIndex","SpriteImage","_getSizeString","setTimeout","trigger","ComponentEvent","imageInContainer","querySelector","wrapperInContainer","display","_image","Image","image","onload","_bg","_createBgDiv","appendChild","setColRow","bgElement","_autoPlayReservedInfo","play","onerror","src","__extends","img","el","createElement","position","overflow","ondragstart","willChange","unitWidth","naturalWidth","unitHeight","naturalHeight","r","paddingBottom","size","index","this","toColRow","col","row","_autoPlayTimer","clearInterval","_a","count","frameCount","_b","interval","playCount","getFrameIndex","setInterval","floor","Component","SpinViewerModule","SpinViewer","_scale","_panScale","_frameCount","_sprites","on","evt","_panInput","PanInput","_axes","Axes","angle","range","circular","curr","pos","getColRow","isTrusted","connect","isNaN","param","duration","setBy","setTo","get","_i","srcs","forEach","source","Object","keys","key","value","isArray","merge","Constants"],"mappings":"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"} \ No newline at end of file diff --git a/dist/view360.esm.js b/dist/view360.esm.js new file mode 100644 index 000000000..d6aa95117 --- /dev/null +++ b/dist/view360.esm.js @@ -0,0 +1,7366 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +import Component, { ComponentEvent } from '@egjs/component'; +import Promise$1 from 'promise-polyfill'; +import agent$1 from '@egjs/agent'; +import Axes, { PanInput, WheelInput, PinchInput, MoveKeyInput } from '@egjs/axes'; +import { vec2, vec3, quat, glMatrix, mat4, mat3 } from 'gl-matrix'; +import ImReady from '@egjs/imready'; + +var VERSION = "3.6.3"; + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ + +/* global Reflect, Promise */ +var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics(d, b); +}; + +function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} +var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); +}; +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} +function __generator(thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }, + f, + y, + t, + g; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; + + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + + switch (op[0]) { + case 0: + case 1: + t = op; + break; + + case 4: + _.label++; + return { + value: op[1], + done: false + }; + + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + + case 7: + op = _.ops.pop(); + + _.trys.pop(); + + continue; + + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + + if (t && _.label < t[2]) { + _.label = t[2]; + + _.ops.push(op); + + break; + } + + if (t[2]) _.ops.pop(); + + _.trys.pop(); + + continue; + } + + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; + } +} +function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); +} +function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; +} +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + + return ar; +} + +/* eslint-disable @typescript-eslint/no-implied-eval */ +/* eslint-disable no-new-func, no-nested-ternary */ + +var win = typeof window !== "undefined" && window.Math === Math ? window : typeof self !== "undefined" && self.Math === Math ? self : Function("return this")(); +/* eslint-enable no-new-func, no-nested-ternary */ + +var doc = win.document; +var nav = win.navigator; +var agent = agent$1(); +var osName = agent.os.name; +var browserName = agent.browser.name; +var IS_IOS = osName === "ios"; +var IS_SAFARI_ON_DESKTOP = osName === "mac" && browserName === "safari"; + +/* eslint-disable @typescript-eslint/naming-convention */ +win.Float32Array = typeof win.Float32Array !== "undefined" ? win.Float32Array : win.Array; +var Float32Array$1 = win.Float32Array; +var getComputedStyle = win.getComputedStyle; +var userAgent = win.navigator && win.navigator.userAgent; +var SUPPORT_TOUCH = ("ontouchstart" in win); +var SUPPORT_DEVICEMOTION = ("ondevicemotion" in win); +var DeviceMotionEvent = win.DeviceMotionEvent; +var devicePixelRatio = win.devicePixelRatio; + +var TRANSFORM = function () { + var _a; + + var docStyle = (_a = doc === null || doc === void 0 ? void 0 : doc.documentElement.style) !== null && _a !== void 0 ? _a : {}; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in docStyle) { + return target[i]; + } + } + + return ""; +}(); // check for will-change support + + +var SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports && win.CSS.supports("will-change", "transform"); +var WEBXR_SUPPORTED = false; + +var checkXRSupport = function () { + var navigator = window.navigator; + + if (!navigator.xr) { + return; + } + + if (navigator.xr.isSessionSupported) { + navigator.xr.isSessionSupported("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } else if (navigator.xr.supportsSession) { + navigator.xr.supportsSession("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } +}; + +/** + * Original Code + * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js + * Math Util + * modified by egjs + */ + +var quatToVec3 = function (quaternion) { + var baseV = vec3.fromValues(0, 0, 1); + vec3.transformQuat(baseV, baseV, quaternion); + return baseV; +}; + +var toDegree = function (a) { + return a * 180 / Math.PI; +}; + +var util = {}; + +util.isPowerOfTwo = function (n) { + return n && (n & n - 1) === 0; +}; + +util.extractPitchFromQuat = function (quaternion) { + var baseV = quatToVec3(quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); +}; + +util.hypot = Math.hypot || function (x, y) { + return Math.sqrt(x * x + y * y); +}; // implement reference +// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식 +// calculating angle between two vectors : http://darkpgmr.tistory.com/121 + + +var ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] +}; + +var getRotationDelta = function (prevQ, curQ, rotateKind) { + var targetAxis = vec3.fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + var meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + var prevQuaternion = quat.clone(prevQ); + var curQuaternion = quat.clone(curQ); + quat.normalize(prevQuaternion, prevQuaternion); + quat.normalize(curQuaternion, curQuaternion); + var prevPoint = vec3.fromValues(0, 0, 1); + var curPoint = vec3.fromValues(0, 0, 1); + vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + vec3.transformQuat(curPoint, curPoint, curQuaternion); + vec3.transformQuat(targetAxis, targetAxis, curQuaternion); + var rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint)); + var rotateDirection = rotateDistance > 0 ? 1 : -1; // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + + var meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + var meshPoint3; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = vec3.fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = vec3.fromValues(rotateDirection, 0, 0); + } + + vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion); + vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion); + var vecU = meshPoint2; + var vecV = meshPoint3; + var vecN = vec3.create(); + vec3.cross(vecN, vecU, vecV); + vec3.normalize(vecN, vecN); + var coefficientA = vecN[0]; + var coefficientB = vecN[1]; + var coefficientC = vecN[2]; // const coefficientD = -1 * vec3.dot(vecN, meshPoint1); + // a point on the plane + + curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + vec3.transformQuat(curPoint, curPoint, curQuaternion); // a point should project on the plane + + prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); // distance between prevPoint and the plane + + var distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + var projectedPrevPoint = vec3.create(); + vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance)); + var trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (vec3.length(projectedPrevPoint) * vec3.length(curPoint)); // defensive block + + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + + var theta = Math.acos(trigonometricRatio); + var crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + var thetaDirection; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + + var deltaRadian = theta * thetaDirection * rotateDirection; + return toDegree(deltaRadian); +}; + +var angleBetweenVec2 = function (v1, v2) { + var det = v1[0] * v2[1] - v2[0] * v1[1]; + var theta = -Math.atan2(det, vec2.dot(v1, v2)); + return theta; +}; + +util.yawOffsetBetween = function (viewDir, targetDir) { + var viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]); + var targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]); + vec2.normalize(viewDirXZ, viewDirXZ); + vec2.normalize(targetDirXZ, targetDirXZ); + var theta = -angleBetweenVec2(viewDirXZ, targetDirXZ); + return theta; +}; + +util.sign = function (x) { + return Math.sign ? Math.sign(x) : Number(x > 0) - Number(x < 0) || +x; +}; + +util.toDegree = toDegree; +util.getRotationDelta = getRotationDelta; +util.angleBetweenVec2 = angleBetweenVec2; + +var toAxis = function (source, offset) { + return offset.reduce(function (acc, v, i) { + if (source[i]) { + acc[source[i]] = v; + } + + return acc; + }, {}); +}; + +/** + * Returns a number value indiciating the version of Chrome being used, + * or otherwise `null` if not on Chrome. + * + * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19 + */ + +/** + * In Chrome m65, `devicemotion` events are broken but subsequently fixed + * in 65.0.3325.148. Since many browsers use Chromium, ensure that + * we scope this detection by branch and build numbers to provide + * a proper fallback. + * https://github.com/immersive-web/webvr-polyfill/issues/307 + */ + +var version = -1; // It should not be null because it will be compared with number + +var branch = null; +var build = null; +var match = /Chrome\/([0-9]+)\.(?:[0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(userAgent); + +if (match) { + version = parseInt(match[1], 10); + branch = match[2]; + build = match[3]; +} + +var CHROME_VERSION = version; +var IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === "3325" && parseInt(build, 10) < 148; +var IS_ANDROID = /Android/i.test(userAgent); +var CONTROL_MODE_VR = 1; +var CONTROL_MODE_YAWPITCH = 2; +var TOUCH_DIRECTION_NONE = 1; +var TOUCH_DIRECTION_YAW = 2; +var TOUCH_DIRECTION_PITCH = 4; +var TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH; +/* Const for MovableCoord */ + +var MC_DECELERATION = 0.0014; +var MC_MAXIMUM_DURATION = 1000; +var MC_BIND_SCALE = [0.20, 0.20]; +var MAX_FIELD_OF_VIEW = 110; +var PAN_SCALE = 320; // const DELTA_THRESHOLD = 0.015; + +var YAW_RANGE_HALF = 180; +var PITCH_RANGE_HALF = 90; +var CIRCULAR_PITCH_RANGE_HALF = 180; +var GYRO_MODE = { + NONE: "none", + YAWPITCH: "yawPitch", + VR: "VR" +}; + +/* eslint-disable */ +var MathUtil = win.MathUtil || {}; +MathUtil.degToRad = Math.PI / 180; +MathUtil.radToDeg = 180 / Math.PI; // Some minimal math functionality borrowed from THREE.Math and stripped down +// for the purposes of this library. + +MathUtil.Vector2 = function (x, y) { + this.x = x || 0; + this.y = y || 0; +}; + +MathUtil.Vector2.prototype = { + constructor: MathUtil.Vector2, + set: function (x, y) { + this.x = x; + this.y = y; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + return this; + }, + subVectors: function (a, b) { + this.x = a.x - b.x; + this.y = a.y - b.y; + return this; + } +}; + +MathUtil.Vector3 = function (x, y, z) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; +}; + +MathUtil.Vector3.prototype = { + constructor: MathUtil.Vector3, + set: function (x, y, z) { + this.x = x; + this.y = y; + this.z = z; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + return this; + }, + length: function () { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + }, + normalize: function () { + var scalar = this.length(); + + if (scalar !== 0) { + var invScalar = 1 / scalar; + this.multiplyScalar(invScalar); + } else { + this.x = 0; + this.y = 0; + this.z = 0; + } + + return this; + }, + multiplyScalar: function (scalar) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + }, + applyQuaternion: function (q) { + var x = this.x; + var y = this.y; + var z = this.z; + var qx = q.x; + var qy = q.y; + var qz = q.z; + var qw = q.w; // calculate quat * vector + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + + this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return this; + }, + dot: function (v) { + return this.x * v.x + this.y * v.y + this.z * v.z; + }, + crossVectors: function (a, b) { + var ax = a.x; + var ay = a.y; + var az = a.z; + var bx = b.x; + var by = b.y; + var bz = b.z; + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; + return this; + } +}; + +MathUtil.Quaternion = function (x, y, z, w) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w !== undefined ? w : 1; +}; + +MathUtil.Quaternion.prototype = { + constructor: MathUtil.Quaternion, + set: function (x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + return this; + }, + copy: function (quaternion) { + this.x = quaternion.x; + this.y = quaternion.y; + this.z = quaternion.z; + this.w = quaternion.w; + return this; + }, + setFromEulerXYZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + return this; + }, + setFromEulerYXZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + return this; + }, + setFromAxisAngle: function (axis, angle) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // assumes axis is normalized + var halfAngle = angle / 2; + var s = Math.sin(halfAngle); + this.x = axis.x * s; + this.y = axis.y * s; + this.z = axis.z * s; + this.w = Math.cos(halfAngle); + return this; + }, + multiply: function (q) { + return this.multiplyQuaternions(this, q); + }, + multiplyQuaternions: function (a, b) { + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + var qax = a.x; + var qay = a.y; + var qaz = a.z; + var qaw = a.w; + var qbx = b.x; + var qby = b.y; + var qbz = b.z; + var qbw = b.w; + this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; + return this; + }, + inverse: function () { + this.x *= -1; + this.y *= -1; + this.z *= -1; + this.normalize(); + return this; + }, + normalize: function () { + var l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + + if (l === 0) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 1; + } else { + l = 1 / l; + this.x = this.x * l; + this.y = this.y * l; + this.z = this.z * l; + this.w = this.w * l; + } + + return this; + }, + slerp: function (qb, t) { + if (t === 0) return this; + if (t === 1) return this.copy(qb); + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + + var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z; + + if (cosHalfTheta < 0) { + this.w = -qb.w; + this.x = -qb.x; + this.y = -qb.y; + this.z = -qb.z; + cosHalfTheta = -cosHalfTheta; + } else { + this.copy(qb); + } + + if (cosHalfTheta >= 1.0) { + this.w = w; + this.x = x; + this.y = y; + this.z = z; + return this; + } + + var halfTheta = Math.acos(cosHalfTheta); + var sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta); + + if (Math.abs(sinHalfTheta) < 0.001) { + this.w = 0.5 * (w + this.w); + this.x = 0.5 * (x + this.x); + this.y = 0.5 * (y + this.y); + this.z = 0.5 * (z + this.z); + return this; + } + + var ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta; + var ratioB = Math.sin(t * halfTheta) / sinHalfTheta; + this.w = w * ratioA + this.w * ratioB; + this.x = x * ratioA + this.x * ratioB; + this.y = y * ratioA + this.y * ratioB; + this.z = z * ratioA + this.z * ratioB; + return this; + }, + setFromUnitVectors: function () { + // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final + // assumes direction vectors vFrom and vTo are normalized + var v1; + var r; + var EPS = 0.000001; + return function (vFrom, vTo) { + if (v1 === undefined) v1 = new MathUtil.Vector3(); + r = vFrom.dot(vTo) + 1; + + if (r < EPS) { + r = 0; + + if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { + v1.set(-vFrom.y, vFrom.x, 0); + } else { + v1.set(0, -vFrom.z, vFrom.y); + } + } else { + v1.crossVectors(vFrom, vTo); + } + + this.x = v1.x; + this.y = v1.y; + this.z = v1.z; + this.w = r; + this.normalize(); + return this; + }; + }() +}; + +/* eslint-disable */ + +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var _a; // tslint:disable: only-arrow-functions +var userAgent$1 = (_a = nav === null || nav === void 0 ? void 0 : nav.userAgent) !== null && _a !== void 0 ? _a : ""; +var Util = win.Util || {}; +Util.MIN_TIMESTEP = 0.001; +Util.MAX_TIMESTEP = 1; + +Util.base64 = function (mimeType, base64) { + return "data:" + mimeType + ";base64," + base64; +}; + +Util.clamp = function (value, min, max) { + return Math.min(Math.max(min, value), max); +}; + +Util.lerp = function (a, b, t) { + return a + (b - a) * t; +}; + +Util.isIOS = function () { + var isIOS = /iPad|iPhone|iPod/.test(nav === null || nav === void 0 ? void 0 : nav.platform); + return function () { + return isIOS; + }; +}(); + +Util.isWebViewAndroid = function () { + var isWebViewAndroid = userAgent$1.indexOf("Version") !== -1 && userAgent$1.indexOf("Android") !== -1 && userAgent$1.indexOf("Chrome") !== -1; + return function () { + return isWebViewAndroid; + }; +}(); + +Util.isSafari = function () { + var isSafari = /^((?!chrome|android).)*safari/i.test(userAgent$1); + return function () { + return isSafari; + }; +}(); + +Util.isFirefoxAndroid = function () { + var isFirefoxAndroid = userAgent$1.indexOf("Firefox") !== -1 && userAgent$1.indexOf("Android") !== -1; + return function () { + return isFirefoxAndroid; + }; +}(); + +Util.isR7 = function () { + var isR7 = userAgent$1.indexOf("R7 Build") !== -1; + return function () { + return isR7; + }; +}(); + +Util.isLandscapeMode = function () { + var rtn = win.orientation === 90 || win.orientation === -90; + return Util.isR7() ? !rtn : rtn; +}; // Helper method to validate the time steps of sensor timestamps. + + +Util.isTimestampDeltaValid = function (timestampDeltaS) { + if (isNaN(timestampDeltaS)) { + return false; + } + + if (timestampDeltaS <= Util.MIN_TIMESTEP) { + return false; + } + + if (timestampDeltaS > Util.MAX_TIMESTEP) { + return false; + } + + return true; +}; + +Util.getScreenWidth = function () { + return Math.max(win.screen.width, win.screen.height) * win.devicePixelRatio; +}; + +Util.getScreenHeight = function () { + return Math.min(win.screen.width, win.screen.height) * win.devicePixelRatio; +}; + +Util.requestFullscreen = function (element) { + if (Util.isWebViewAndroid()) { + return false; + } + + if (element.requestFullscreen) { + element.requestFullscreen(); + } else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } else { + return false; + } + + return true; +}; + +Util.exitFullscreen = function () { + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else if (doc.webkitExitFullscreen) { + doc.webkitExitFullscreen(); + } else if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } else { + return false; + } + + return true; +}; + +Util.getFullscreenElement = function () { + return doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement; +}; + +Util.linkProgram = function (gl, vertexSource, fragmentSource, attribLocationMap) { + // No error checking for brevity. + var vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vertexSource); + gl.compileShader(vertexShader); + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + for (var attribName in attribLocationMap) gl.bindAttribLocation(program, attribLocationMap[attribName], attribName); + + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + return program; +}; + +Util.getProgramUniforms = function (gl, program) { + var uniforms = {}; + var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + var uniformName = ""; + + for (var i = 0; i < uniformCount; i++) { + var uniformInfo = gl.getActiveUniform(program, i); + uniformName = uniformInfo.name.replace("[0]", ""); + uniforms[uniformName] = gl.getUniformLocation(program, uniformName); + } + + return uniforms; +}; + +Util.orthoMatrix = function (out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 2 * nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = (far + near) * nf; + out[15] = 1; + return out; +}; + +Util.copyArray = function (source, dest) { + for (var i = 0, n = source.length; i < n; i++) { + dest[i] = source[i]; + } +}; + +Util.isMobile = function () { + var check = false; + + (function (a) { + if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; + })(userAgent$1 || (nav === null || nav === void 0 ? void 0 : nav.vendor) || win.opera); + + return check; +}; + +Util.extend = function (dest, src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dest[key] = src[key]; + } + } + + return dest; +}; + +Util.safariCssSizeWorkaround = function (canvas) { + // TODO(smus): Remove this workaround when Safari for iOS is fixed. + // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556). + // + // "To the last I grapple with thee; + // from hell's heart I stab at thee; + // for hate's sake I spit my last breath at thee." + // -- Moby Dick, by Herman Melville + if (Util.isIOS()) { + var width_1 = canvas.style.width; + var height_1 = canvas.style.height; + canvas.style.width = parseInt(width_1) + 1 + "px"; + canvas.style.height = parseInt(height_1) + "px"; + setTimeout(function () { + canvas.style.width = width_1; + canvas.style.height = height_1; + }, 100); + } // Debug only. + + + win.Util = Util; + win.canvas = canvas; +}; + +Util.isDebug = function () { + return Util.getQueryParameter("debug"); +}; + +Util.getQueryParameter = function (name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"); + var results = regex.exec(location.search); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); +}; + +Util.frameDataFromPose = function () { + var piOver180 = Math.PI / 180.0; + var rad45 = Math.PI * 0.25; // Borrowed from glMatrix. + + function mat4_perspectiveFromFieldOfView(out, fov, near, far) { + var upTan = Math.tan(fov ? fov.upDegrees * piOver180 : rad45); + var downTan = Math.tan(fov ? fov.downDegrees * piOver180 : rad45); + var leftTan = Math.tan(fov ? fov.leftDegrees * piOver180 : rad45); + var rightTan = Math.tan(fov ? fov.rightDegrees * piOver180 : rad45); + var xScale = 2.0 / (leftTan + rightTan); + var yScale = 2.0 / (upTan + downTan); + out[0] = xScale; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + out[4] = 0.0; + out[5] = yScale; + out[6] = 0.0; + out[7] = 0.0; + out[8] = -((leftTan - rightTan) * xScale * 0.5); + out[9] = (upTan - downTan) * yScale * 0.5; + out[10] = far / (near - far); + out[11] = -1.0; + out[12] = 0.0; + out[13] = 0.0; + out[14] = far * near / (near - far); + out[15] = 0.0; + return out; + } + + function mat4_fromRotationTranslation(out, q, v) { + // Quaternion math + var x = q[0]; + var y = q[1]; + var z = q[2]; + var w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - (yy + zz); + out[1] = xy + wz; + out[2] = xz - wy; + out[3] = 0; + out[4] = xy - wz; + out[5] = 1 - (xx + zz); + out[6] = yz + wx; + out[7] = 0; + out[8] = xz + wy; + out[9] = yz - wx; + out[10] = 1 - (xx + yy); + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + + function mat4_translate(out, a, v) { + var x = v[0]; + var y = v[1]; + var z = v[2]; + var a00; + var a01; + var a02; + var a03; + var a10; + var a11; + var a12; + var a13; + var a20; + var a21; + var a22; + var a23; + + if (a === out) { + out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; + out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; + out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; + out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; + } else { + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a03; + out[4] = a10; + out[5] = a11; + out[6] = a12; + out[7] = a13; + out[8] = a20; + out[9] = a21; + out[10] = a22; + out[11] = a23; + out[12] = a00 * x + a10 * y + a20 * z + a[12]; + out[13] = a01 * x + a11 * y + a21 * z + a[13]; + out[14] = a02 * x + a12 * y + a22 * z + a[14]; + out[15] = a03 * x + a13 * y + a23 * z + a[15]; + } + + return out; + } + + function mat4_invert(out, a) { + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + var a30 = a[12]; + var a31 = a[13]; + var a32 = a[14]; + var a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + return out; + } + + var defaultOrientation = new Float32Array([0, 0, 0, 1]); + var defaultPosition = new Float32Array([0, 0, 0]); + + function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) { + mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar); + var orientation = pose.orientation || defaultOrientation; + var position = pose.position || defaultPosition; + mat4_fromRotationTranslation(view, orientation, position); + if (parameters) mat4_translate(view, view, parameters.offset); + mat4_invert(view, view); + } + + return function (frameData, pose, vrDisplay) { + if (!frameData || !pose) return false; + frameData.pose = pose; + frameData.timestamp = pose.timestamp; + updateEyeMatrices(frameData.leftProjectionMatrix, frameData.leftViewMatrix, pose, vrDisplay.getEyeParameters("left"), vrDisplay); + updateEyeMatrices(frameData.rightProjectionMatrix, frameData.rightViewMatrix, pose, vrDisplay.getEyeParameters("right"), vrDisplay); + return true; + }; +}(); + +Util.isInsideCrossDomainIFrame = function () { + var isFramed = win.self !== win.top; + var refDomain = Util.getDomainFromUrl(doc.referrer); + var thisDomain = Util.getDomainFromUrl(win.location.href); + return isFramed && refDomain !== thisDomain; +}; // From http://stackoverflow.com/a/23945027. + + +Util.getDomainFromUrl = function (url) { + var domain; // Find & remove protocol (http, ftp, etc.) and get domain. + + if (url.indexOf("://") > -1) { + domain = url.split("/")[2]; + } else { + domain = url.split("/")[0]; + } // find & remove port number + + + domain = domain.split(":")[0]; + return domain; +}; + +/* eslint-disable */ +/** + * Given an orientation and the gyroscope data, predicts the future orientation + * of the head. This makes rendering appear faster. + * + * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf + * @param {Number} predictionTimeS time from head movement to the appearance of + * the corresponding image. + */ + +var PosePredictor = +/*#__PURE__*/ +function () { + function PosePredictor(predictionTimeS) { + this.predictionTimeS = predictionTimeS; // The quaternion corresponding to the previous state. + + this.previousQ = new MathUtil.Quaternion(); // Previous time a prediction occurred. + + this.previousTimestampS = null; // The delta quaternion that adjusts the current pose. + + this.deltaQ = new MathUtil.Quaternion(); // The output quaternion. + + this.outQ = new MathUtil.Quaternion(); + } + + var __proto = PosePredictor.prototype; + + __proto.getPrediction = function (currentQ, gyro, timestampS) { + if (!this.previousTimestampS) { + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return currentQ; + } // Calculate axis and angle based on gyroscope rotation rate data. + + + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + var angularSpeed = gyro.length(); // If we're rotating slowly, don't do prediction. + + if (angularSpeed < MathUtil.degToRad * 20) { + if (Util.isDebug()) { + console.log("Moving slowly, at %s deg/s: no prediction", (MathUtil.radToDeg * angularSpeed).toFixed(1)); + } + + this.outQ.copy(currentQ); + this.previousQ.copy(currentQ); + return this.outQ; + } // Get the predicted angle based on the time delta and latency. + + + var deltaT = timestampS - this.previousTimestampS; + var predictAngle = angularSpeed * this.predictionTimeS; + this.deltaQ.setFromAxisAngle(axis, predictAngle); + this.outQ.copy(this.previousQ); + this.outQ.multiply(this.deltaQ); + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return this.outQ; + }; + + return PosePredictor; +}(); + +var STILLNESS_THRESHOLD = 200; // millisecond + +var DeviceMotion = +/*#__PURE__*/ +function (_super) { + __extends(DeviceMotion, _super); + + function DeviceMotion() { + var _this = _super.call(this) || this; + + _this._onDeviceMotion = _this._onDeviceMotion.bind(_this); + _this._onDeviceOrientation = _this._onDeviceOrientation.bind(_this); + _this._onChromeWithoutDeviceMotion = _this._onChromeWithoutDeviceMotion.bind(_this); + _this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION; + _this.isAndroid = IS_ANDROID; + _this.stillGyroVec = vec3.create(); + _this.rawGyroVec = vec3.create(); + _this.adjustedGyroVec = vec3.create(); + _this._timer = -1; + _this.lastDevicemotionTimestamp = 0; + _this._isEnabled = false; + + _this.enable(); + + return _this; + } + + var __proto = DeviceMotion.prototype; + + __proto.enable = function () { + if (this.isAndroid) { + win.addEventListener("deviceorientation", this._onDeviceOrientation); + } + + if (this.isWithoutDeviceMotion) { + win.addEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + } else { + win.addEventListener("devicemotion", this._onDeviceMotion); + } + + this._isEnabled = true; + }; + + __proto.disable = function () { + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + win.removeEventListener("devicemotion", this._onDeviceMotion); + this._isEnabled = false; + }; + + __proto._onChromeWithoutDeviceMotion = function (e) { + var alpha = e.alpha, + beta = e.beta, + gamma = e.gamma; // There is deviceorientation event trigged with empty values + // on Headless Chrome. + + if (alpha === null) { + return; + } // convert to radian + + + alpha = (alpha || 0) * Math.PI / 180; + beta = (beta || 0) * Math.PI / 180; + gamma = (gamma || 0) * Math.PI / 180; + this.trigger(new ComponentEvent("devicemotion", { + inputEvent: { + deviceorientation: { + alpha: alpha, + beta: beta, + gamma: -gamma + } + } + })); + }; + + __proto._onDeviceOrientation = function () { + var _this = this; + + if (this._timer) { + clearTimeout(this._timer); + } + + this._timer = win.setTimeout(function () { + if (new Date().getTime() - _this.lastDevicemotionTimestamp < STILLNESS_THRESHOLD) { + vec3.copy(_this.stillGyroVec, _this.rawGyroVec); + } + }, STILLNESS_THRESHOLD); + }; + + __proto._onDeviceMotion = function (e) { + // desktop chrome triggers devicemotion event with empthy sensor values. + // Those events should ignored. + var isGyroSensorAvailable = !(e.rotationRate.alpha == null); + var isGravitySensorAvailable = !(e.accelerationIncludingGravity.x == null); + + if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) { + return; + } + + var devicemotionEvent = __assign({}, e); + + devicemotionEvent.interval = e.interval; + devicemotionEvent.timeStamp = e.timeStamp; + devicemotionEvent.type = e.type; + devicemotionEvent.rotationRate = { + alpha: e.rotationRate.alpha, + beta: e.rotationRate.beta, + gamma: e.rotationRate.gamma + }; + devicemotionEvent.accelerationIncludingGravity = { + x: e.accelerationIncludingGravity.x, + y: e.accelerationIncludingGravity.y, + z: e.accelerationIncludingGravity.z + }; + devicemotionEvent.acceleration = { + x: e.acceleration.x, + y: e.acceleration.y, + z: e.acceleration.z + }; + + if (this.isAndroid) { + vec3.set(this.rawGyroVec, e.rotationRate.alpha || 0, e.rotationRate.beta || 0, e.rotationRate.gamma || 0); + vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec); + this.lastDevicemotionTimestamp = new Date().getTime(); + devicemotionEvent.adjustedRotationRate = { + alpha: this.adjustedGyroVec[0], + beta: this.adjustedGyroVec[1], + gamma: this.adjustedGyroVec[2] + }; + } + + this.trigger(new ComponentEvent("devicemotion", { + inputEvent: devicemotionEvent + })); + }; + + return DeviceMotion; +}(Component); + +var SensorSample = +/*#__PURE__*/ +function () { + function SensorSample(sample, timestampS) { + this.set(sample, timestampS); + } + + var __proto = SensorSample.prototype; + + __proto.set = function (sample, timestampS) { + this.sample = sample; + this.timestampS = timestampS; + }; + + __proto.copy = function (sensorSample) { + this.set(sensorSample.sample, sensorSample.timestampS); + }; + + return SensorSample; +}(); + +/* eslint-disable */ +/** + * An implementation of a simple complementary filter, which fuses gyroscope and + * accelerometer data from the 'devicemotion' event. + * + * Accelerometer data is very noisy, but stable over the long term. + * Gyroscope data is smooth, but tends to drift over the long term. + * + * This fusion is relatively simple: + * 1. Get orientation estimates from accelerometer by applying a low-pass filter + * on that data. + * 2. Get orientation estimates from gyroscope by integrating over time. + * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the + * short term. + */ + +var ComplementaryFilter = +/*#__PURE__*/ +function () { + function ComplementaryFilter(kFilter) { + this.addGyroMeasurement = function (vector, timestampS) { + this.currentGyroMeasurement.set(vector, timestampS); + var deltaT = timestampS - this.previousGyroMeasurement.timestampS; + + if (Util.isTimestampDeltaValid(deltaT)) { + this.run_(); + } + + this.previousGyroMeasurement.copy(this.currentGyroMeasurement); + }; + + this.kFilter = kFilter; // Raw sensor measurements. + + this.currentAccelMeasurement = new SensorSample(); + this.currentGyroMeasurement = new SensorSample(); + this.previousGyroMeasurement = new SensorSample(); // Set default look direction to be in the correct direction. + + if (Util.isIOS()) { + this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1); + } else { + this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1); + } + + this.previousFilterQ = new MathUtil.Quaternion(); + this.previousFilterQ.copy(this.filterQ); // Orientation based on the accelerometer. + + this.accelQ = new MathUtil.Quaternion(); // Whether or not the orientation has been initialized. + + this.isOrientationInitialized = false; // Running estimate of gravity based on the current orientation. + + this.estimatedGravity = new MathUtil.Vector3(); // Measured gravity based on accelerometer. + + this.measuredGravity = new MathUtil.Vector3(); // Debug only quaternion of gyro-based orientation. + + this.gyroIntegralQ = new MathUtil.Quaternion(); + } + + var __proto = ComplementaryFilter.prototype; + + __proto.addAccelMeasurement = function (vector, timestampS) { + this.currentAccelMeasurement.set(vector, timestampS); + }; + + __proto.getOrientation = function () { + return this.filterQ; + }; + + __proto.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); + + if (Util.isDebug()) { + console.log("Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)", MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ), this.estimatedGravity.x.toFixed(1), this.estimatedGravity.y.toFixed(1), this.estimatedGravity.z.toFixed(1), this.measuredGravity.x.toFixed(1), this.measuredGravity.y.toFixed(1), this.measuredGravity.z.toFixed(1)); + } // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + }; + + __proto.accelToQuaternion_ = function (accel) { + var normAccel = new MathUtil.Vector3(); + normAccel.copy(accel); + normAccel.normalize(); + var quat = new MathUtil.Quaternion(); + quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel); + quat.inverse(); + return quat; + }; + + __proto.gyroToQuaternionDelta_ = function (gyro, dt) { + // Extract axis and angle from the gyroscope data. + var quat = new MathUtil.Quaternion(); + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + quat.setFromAxisAngle(axis, gyro.length() * dt); + return quat; + }; + + return ComplementaryFilter; +}(); + +ComplementaryFilter.prototype.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + + if (!this.isFilterQuaternionInitialized) { + this.isFilterQuaternionInitialized = true; + } +}; + +ComplementaryFilter.prototype.getOrientation = function () { + if (this.isFilterQuaternionInitialized) { + return this.filterQ; + } else { + return null; + } +}; + +var K_FILTER = 0.98; +var PREDICTION_TIME_S = 0.040; + +var FusionPoseSensor = +/*#__PURE__*/ +function (_super) { + __extends(FusionPoseSensor, _super); + + function FusionPoseSensor() { + var _this = _super.call(this) || this; + + _this.deviceMotion = new DeviceMotion(); + _this.accelerometer = new MathUtil.Vector3(); + _this.gyroscope = new MathUtil.Vector3(); + _this._onDeviceMotionChange = _this._onDeviceMotionChange.bind(_this); + _this._onScreenOrientationChange = _this._onScreenOrientationChange.bind(_this); + _this.filter = new ComplementaryFilter(K_FILTER); + _this.posePredictor = new PosePredictor(PREDICTION_TIME_S); + _this.filterToWorldQ = new MathUtil.Quaternion(); + _this.isFirefoxAndroid = Util.isFirefoxAndroid(); // This includes iPhone & iPad(both desktop and mobile mode) ref #326 + + _this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP; // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18 + + _this.isChromeUsingDegrees = CHROME_VERSION >= 66; + _this._isEnabled = false; // Set the filter to world transform, depending on OS. + + if (_this.isIOS) { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2); + } else { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2); + } + + _this.inverseWorldToScreenQ = new MathUtil.Quaternion(); + _this.worldToScreenQ = new MathUtil.Quaternion(); + _this.originalPoseAdjustQ = new MathUtil.Quaternion(); + + _this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -win.orientation * Math.PI / 180); + + _this._setScreenTransform(); // Adjust this filter for being in landscape mode. + + + if (Util.isLandscapeMode()) { + _this.filterToWorldQ.multiply(_this.inverseWorldToScreenQ); + } // Keep track of a reset transform for resetSensor. + + + _this.resetQ = new MathUtil.Quaternion(); + + _this.deviceMotion.on("devicemotion", _this._onDeviceMotionChange); + + _this.enable(); + + return _this; + } + + var __proto = FusionPoseSensor.prototype; + + __proto.enable = function () { + if (this.isEnabled()) { + return; + } + + this.deviceMotion.enable(); + this._isEnabled = true; + win.addEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.disable = function () { + if (!this.isEnabled()) { + return; + } + + this.deviceMotion.disable(); + this._isEnabled = false; + win.removeEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.isEnabled = function () { + return this._isEnabled; + }; + + __proto.destroy = function () { + this.disable(); + this.deviceMotion = null; + }; + + __proto.getOrientation = function () { + var _this = this; + + var orientation; // Hack around using deviceorientation instead of devicemotion + + if (this.deviceMotion.isWithoutDeviceMotion && this._deviceOrientationQ) { + this.deviceOrientationFixQ = this.deviceOrientationFixQ || function () { + var y = new MathUtil.Quaternion().setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -_this._alpha); + return y; + }(); + + orientation = this._deviceOrientationQ; + var out = new MathUtil.Quaternion(); + out.copy(orientation); + out.multiply(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.worldToScreenQ); + out.multiplyQuaternions(this.deviceOrientationFixQ, out); // return quaternion as glmatrix quaternion object + + var outQuat = quat.fromValues(out.x, out.y, out.z, out.w); + return quat.normalize(outQuat, outQuat); + } else { + // Convert from filter space to the the same system used by the + // deviceorientation event. + orientation = this.filter.getOrientation(); + + if (!orientation) { + return null; + } + + var out = this._convertFusionToPredicted(orientation); // return quaternion as glmatrix quaternion object + + + var outQuat = quat.fromValues(out.x, out.y, out.z, out.w); + return quat.normalize(outQuat, outQuat); + } + }; + + __proto._triggerChange = function () { + var orientation = this.getOrientation(); // if orientation is not prepared. don't trigger change event + + if (!orientation) { + return; + } + + if (!this._prevOrientation) { + this._prevOrientation = orientation; + return; + } + + if (quat.equals(this._prevOrientation, orientation)) { + return; + } + + this.trigger(new ComponentEvent("change", { + quaternion: orientation + })); + }; + + __proto._convertFusionToPredicted = function (orientation) { + // Predict orientation. + this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS); // Convert to THREE coordinate system: -Z forward, Y up, X right. + + var out = new MathUtil.Quaternion(); + out.copy(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.predictedQ); + out.multiply(this.worldToScreenQ); + return out; + }; + + __proto._onDeviceMotionChange = function (_a) { + var inputEvent = _a.inputEvent; + var deviceorientation = inputEvent.deviceorientation; + var deviceMotion = inputEvent; + var accGravity = deviceMotion.accelerationIncludingGravity; + var rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate; + var timestampS = deviceMotion.timeStamp / 1000; + + if (deviceorientation) { + if (!this._alpha) { + this._alpha = deviceorientation.alpha; + } + + this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion(); + + this._deviceOrientationQ.setFromEulerYXZ(deviceorientation.beta, deviceorientation.alpha, deviceorientation.gamma); + + this._triggerChange(); + } else { + // Firefox Android timeStamp returns one thousandth of a millisecond. + if (this.isFirefoxAndroid) { + timestampS /= 1000; + } + + this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z); + this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma); // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate` + // is reported in degrees, so we first convert to radians. + + if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) { + this.gyroscope.multiplyScalar(Math.PI / 180); + } + + this.filter.addAccelMeasurement(this.accelerometer, timestampS); + this.filter.addGyroMeasurement(this.gyroscope, timestampS); + + this._triggerChange(); + + this.previousTimestampS = timestampS; + } + }; + + __proto._onScreenOrientationChange = function () { + this._setScreenTransform(); + }; + + __proto._setScreenTransform = function () { + this.worldToScreenQ.set(0, 0, 0, 1); + var orientation = win.orientation; + + switch (orientation) { + case 0: + break; + + case 90: + case -90: + case 180: + this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI); + break; + } + + this.inverseWorldToScreenQ.copy(this.worldToScreenQ); + this.inverseWorldToScreenQ.inverse(); + }; + + return FusionPoseSensor; +}(Component); + +var getDeltaYaw = function (prvQ, curQ) { + var yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + var yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(util.extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; +}; + +var getDeltaPitch = function (prvQ, curQ) { + var pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + return pitchDelta; +}; // eslint-disable-next-line @typescript-eslint/ban-types + + +var TiltMotionInput = +/*#__PURE__*/ +function (_super) { + __extends(TiltMotionInput, _super); + + function TiltMotionInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.element = el; + _this._prevQuaternion = null; + _this._quaternion = null; + _this.fusionPoseSensor = null; + _this.options = __assign({ + scale: 1, + threshold: 0 + }, options); + _this._onPoseChange = _this._onPoseChange.bind(_this); + return _this; + } + + var __proto = TiltMotionInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this.observer) { + return this; + } + + this.observer = observer; + this.fusionPoseSensor = new FusionPoseSensor(); + this.fusionPoseSensor.enable(); + + this._attachEvent(); + + return this; + }; + + __proto.disconnect = function () { + if (!this.observer) { + return this; + } + + this._dettachEvent(); + + this.fusionPoseSensor.disable(); + this.fusionPoseSensor.destroy(); + this.fusionPoseSensor = null; + this.observer = null; + return this; + }; + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + this.options = null; + this.axes = null; + this._prevQuaternion = null; + this._quaternion = null; + }; + + __proto._onPoseChange = function (event) { + if (!this._prevQuaternion) { + this._prevQuaternion = quat.clone(event.quaternion); + this._quaternion = quat.clone(event.quaternion); + return; + } + + quat.copy(this._prevQuaternion, this._quaternion); + quat.copy(this._quaternion, event.quaternion); + this.observer.change(this, event, toAxis(this.axes, [getDeltaYaw(this._prevQuaternion, this._quaternion), getDeltaPitch(this._prevQuaternion, this._quaternion)])); + }; + + __proto._attachEvent = function () { + this.fusionPoseSensor.on("change", this._onPoseChange); + }; + + __proto._dettachEvent = function () { + this.fusionPoseSensor.off("change", this._onPoseChange); + }; + + return TiltMotionInput; +}(Component); + +var screenRotationAngleInst = null; +var refCount = 0; + +var ScreenRotationAngle = +/*#__PURE__*/ +function () { + function ScreenRotationAngle() { + refCount++; + + if (screenRotationAngleInst) { + return screenRotationAngleInst; + } + /* eslint-disable */ + + + screenRotationAngleInst = this; + /* eslint-enable */ + + this._onDeviceOrientation = this._onDeviceOrientation.bind(this); + this._onOrientationChange = this._onOrientationChange.bind(this); + this._spinR = 0; + this._screenOrientationAngle = 0; + win.addEventListener("deviceorientation", this._onDeviceOrientation); + win.addEventListener("orientationchange", this._onOrientationChange); + } + + var __proto = ScreenRotationAngle.prototype; + + __proto.getRadian = function () { + // Join with screen orientation + // this._testVal = this._spinR + ", " + this._screenOrientationAngle + ", " + window.orientation; + return this._spinR + glMatrix.toRadian(this._screenOrientationAngle); + }; + + __proto.unref = function () { + if (--refCount > 0) { + return; + } + + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("orientationchange", this._onOrientationChange); + this._spinR = 0; + this._screenOrientationAngle = 0; + /* eslint-disable */ + + screenRotationAngleInst = null; + /* eslint-enable */ + + refCount = 0; + }; + + __proto._onDeviceOrientation = function (e) { + if (e.beta === null || e.gamma === null) { + // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it. + return; + } // Radian + + + var betaR = glMatrix.toRadian(e.beta); + var gammaR = glMatrix.toRadian(e.gamma); + /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */ + + this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR)); + }; + + __proto._onOrientationChange = function () { + if (win.screen && win.screen.orientation && win.screen.orientation.angle !== undefined) { + this._screenOrientationAngle = screen.orientation.angle; + } else if (win.orientation !== undefined) { + /* iOS */ + this._screenOrientationAngle = win.orientation >= 0 ? win.orientation : 360 + win.orientation; + } + }; + + return ScreenRotationAngle; +}(); + +/** + * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle. + * + * The reason for using this function is that in VR mode, + * the roll angle is adjusted in the direction opposite to the screen rotation angle. + * + * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move. + * @extends PanInput + */ + +var RotationPanInput = +/*#__PURE__*/ +function (_super) { + __extends(RotationPanInput, _super); + /** + * Constructor + * @private + * @param {HTMLElement} el target element + * @param {Object} [options] The option object + * @param {Boolean} [options.useRotation] Whether to use rotation(or VR) + */ + + + function RotationPanInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this, el, options) || this; + + _this._useRotation = false; + _this._screenRotationAngle = null; + + _this.setUseRotation(!!(options && options.useRotation)); + + _this._userDirection = Axes.DIRECTION_ALL; + return _this; + } + + var __proto = RotationPanInput.prototype; + + __proto.setUseRotation = function (useRotation) { + this._useRotation = useRotation; + + if (this._screenRotationAngle) { + this._screenRotationAngle.unref(); + + this._screenRotationAngle = null; + } + + if (this._useRotation) { + this._screenRotationAngle = new ScreenRotationAngle(); + } + }; + + __proto.connect = function (observer) { + // User intetened direction + this._userDirection = this._direction; // In VR Mode, Use ALL direction if direction is not none + // Because horizontal and vertical is changed dynamically by screen rotation. + // this._direction is used to initialize hammerjs + + if (this._useRotation && this._direction & Axes.DIRECTION_ALL) { + this._direction = Axes.DIRECTION_HORIZONTAL; + } + + return _super.prototype.connect.call(this, observer); + }; + + __proto.destroy = function () { + if (this._useRotation && this._screenRotationAngle) { + this._screenRotationAngle.unref(); + } + + _super.prototype.destroy.call(this); + }; + + __proto._getOffset = function (properties, useDirection) { + if (this._useRotation === false) { + return _super.prototype._getOffset.call(this, properties, useDirection); + } + + var offset = _super.prototype._getOffset.call(this, properties, [true, true]); + + var newOffset = [0, 0]; + + var theta = this._screenRotationAngle.getRadian(); + + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); // RotateZ + + newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta; + newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta; // Use only user allowed direction. + + if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) { + newOffset[0] = 0; + } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) { + newOffset[1] = 0; + } + + return newOffset; + }; + + return RotationPanInput; +}(PanInput); +/** + * Override getDirectionByAngle to return DIRECTION_ALL + * Ref: https://github.com/naver/egjs-axes/issues/99 + * + * But we obey axes's rule. If axes's rule is problem, let's apply following code. + */ +// PanInput.getDirectionByAngle = function (angle, thresholdAngle) { +// return DIRECTION_ALL; +// }; + +var Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0); + +var DeviceQuaternion = +/*#__PURE__*/ +function (_super) { + __extends(DeviceQuaternion, _super); + + function DeviceQuaternion() { + var _this = _super.call(this) || this; + + _this._fusionPoseSensor = new FusionPoseSensor(); + _this._quaternion = quat.create(); + + _this._fusionPoseSensor.enable(); + + _this._fusionPoseSensor.on("change", function (e) { + _this._quaternion = e.quaternion; + + _this.trigger(new ComponentEvent("change", { + isTrusted: true + })); + }); + + return _this; + } + + var __proto = DeviceQuaternion.prototype; + + __proto.getCombinedQuaternion = function (yaw) { + var yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw)); + var conj = quat.conjugate(quat.create(), this._quaternion); // Multiply pitch quaternion -> device quaternion -> yaw quaternion + + var outQ = quat.multiply(quat.create(), conj, yawQ); + return outQ; + }; + + __proto.destroy = function () { + // detach all event handler + this.off(); + + if (this._fusionPoseSensor) { + this._fusionPoseSensor.off(); + + this._fusionPoseSensor.destroy(); + + this._fusionPoseSensor = null; + } + }; + + return DeviceQuaternion; +}(Component); + +var DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF]; +var DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF]; +var CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF]; +/** + * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates. + * @alias eg.YawPitchControl + * @extends eg.Component + * + * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + */ + +var YawPitchControl = +/*#__PURE__*/ +function (_super) { + __extends(YawPitchControl, _super); + /** + * @param {object} options The option object of the eg.YawPitch module + * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module + * @param {number} [options.yaw=0] initial yaw (degree) + * @param {number} [options.pitch=0] initial pitch (degree) + * @param {number} [options.fov=65] initial field of view (degree) + * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown + * @param {boolean} [options.useZoom=true] Indicates whether zoom is available + * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled + * @param {string} [config.gyroMode=yawPitch] Enables control through device motion. + * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move) + * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw + * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch + * @param {number[]} [options.fovRange=[30, 110] Range of FOV + * @param {number} [options.aspectRatio=1] Aspect Ratio + */ + + + function YawPitchControl(options) { + var _this = _super.call(this) || this; + + _this.options = {}; + + var opt = __assign({ + element: null, + yaw: 0, + pitch: 0, + fov: 65, + showPolePoint: false, + useZoom: true, + useKeyboard: true, + gyroMode: GYRO_MODE.YAWPITCH, + touchDirection: TOUCH_DIRECTION_ALL, + yawRange: DEFAULT_YAW_RANGE, + pitchRange: DEFAULT_PITCH_RANGE, + fovRange: [30, 110], + aspectRatio: 1 + /* TODO: Need Mandatory? */ + + }, options); + + _this._element = opt.element; + _this._initialFov = opt.fov; + _this._enabled = false; + _this._isAnimating = false; + _this._deviceQuaternion = null; + + _this._initAxes(opt); + + _this.option(opt); + + return _this; + } + /** + * Update Pan Scale + * + * Scale(Sensitivity) values of panning is related with fov and height. + * If at least one of them is changed, this function need to be called. + * @param {*} param + */ + + + var __proto = YawPitchControl.prototype; + + __proto.updatePanScale = function (param) { + if (param === void 0) { + param = {}; + } + + var fov = this._axes.get().fov; + + var areaHeight = param.height || parseInt(window.getComputedStyle(this._element).height, 10); + var scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight; + this._axesPanInput.options.scale = [scale, scale]; + this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW; + return this; + }; + /* + * Override component's option method + * to call method for updating values which is affected by option change. + * + * @param {*} args + */ + + + __proto.option = function (key, newValue) { + // Getter + if (!key) { + return this._getOptions(); + } else if (key && typeof key === "string" && typeof newValue === "undefined") { + return this._getOptions(key); + } // Setter + + + var newOptions = {}; + var changedKeyList = []; // TODO: if value is not changed, then do not push on changedKeyList. + + if (typeof key === "string") { + changedKeyList.push(key); + newOptions[key] = newValue; + } else { + var options = key; // Retrieving object here + + changedKeyList = Object.keys(options); + newOptions = __assign({}, options); + } + + this._setOptions(this._getValidatedOptions(newOptions)); + + this._applyOptions(changedKeyList); + + return this; + }; + /** + * Enable YawPitch functionality + * @method eg.YawPitch#enable + */ + + + __proto.enable = function () { + if (this._enabled) { + return this; + } + + this._enabled = true; // touchDirection is decided by parameter is valid string (Ref. Axes.connect) + + this._applyOptions(Object.keys(this.options)); // TODO: Is this code is needed? Check later. + + + this.updatePanScale(); + return this; + }; + /** + * Disable YawPitch functionality + * @method eg.YawPitch#disable + */ + + + __proto.disable = function (persistOrientation) { + if (persistOrientation === void 0) { + persistOrientation = false; + } + + if (!this._enabled) { + return this; + } // TODO: Check peristOrientation is needed! + + + if (!persistOrientation) { + this._resetOrientation(); + } + + this._axes.disconnect(); + + this._enabled = false; + return this; + }; + /** + * Set one or more of yaw, pitch, fov + * @param {Object} coordinate yaw, pitch, fov + * @param {Number} duration Animation duration. if it is above 0 then it's animated. + */ + + + __proto.lookAt = function (_a, duration) { + var yaw = _a.yaw, + pitch = _a.pitch, + fov = _a.fov; + + var pos = this._axes.get(); + + var y = yaw === undefined ? 0 : yaw - pos.yaw; + var p = pitch === undefined ? 0 : pitch - pos.pitch; + var f = fov === undefined ? 0 : fov - pos.fov; // Allow duration of animation to have more than MC_MAXIMUM_DURATION. + + this._axes.options.maximumDuration = Infinity; + + this._axes.setBy({ + yaw: y, + pitch: p, + fov: f + }, duration); + }; + + __proto.getYawPitch = function () { + var yawPitch = this._axes.get(); + + return { + yaw: yawPitch.yaw, + pitch: yawPitch.pitch + }; + }; + + __proto.getFov = function () { + return this._axes.get().fov; + }; + + __proto.getQuaternion = function () { + var pos = this._axes.get(); + + return this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + }; + + __proto.shouldRenderWithQuaternion = function () { + return this.options.gyroMode === GYRO_MODE.VR; + }; + /** + * Destroys objects + */ + + + __proto.destroy = function () { + /* eslint-disable @typescript-eslint/no-unused-expressions */ + this._axes && this._axes.destroy(); + this._axesPanInput && this._axesPanInput.destroy(); + this._axesWheelInput && this._axesWheelInput.destroy(); + this._axesTiltMotionInput && this._axesTiltMotionInput.destroy(); + this._axesPinchInput && this._axesPinchInput.destroy(); + this._axesMoveKeyInput && this._axesMoveKeyInput.destroy(); + this._deviceQuaternion && this._deviceQuaternion.destroy(); + /* eslint-enable @typescript-eslint/no-unused-expressions */ + }; + + __proto._initAxes = function (opt) { + var _this = this; + + var yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio); + + var pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint); + + var useRotation = opt.gyroMode === GYRO_MODE.VR; + this._axesPanInput = new RotationPanInput(this._element, { + useRotation: useRotation + }); + this._axesWheelInput = new WheelInput(this._element, { + scale: -4 + }); + this._axesTiltMotionInput = null; + this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, { + scale: -1 + }) : null; + this._axesMoveKeyInput = new MoveKeyInput(this._element, { + scale: [-6, 6] + }); + this._axes = new Axes({ + yaw: { + range: yRange, + circular: this._isCircular(yRange), + bounce: [0, 0] + }, + pitch: { + range: pRange, + circular: this._isCircular(pRange), + bounce: [0, 0] + }, + fov: { + range: opt.fovRange, + circular: [false, false], + bounce: [0, 0] + } + }, { + deceleration: MC_DECELERATION, + maximumDuration: MC_MAXIMUM_DURATION + }, { + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }).on({ + // TODO: change event type after Axes event type inference update + hold: function (evt) { + // Restore maximumDuration not to be spin too mush. + _this._axes.options.maximumDuration = MC_MAXIMUM_DURATION; + + _this.trigger(new ComponentEvent("hold", { + isTrusted: evt.isTrusted + })); + }, + change: function (evt) { + if (evt.delta.fov !== 0) { + _this._updateControlScale(evt); + + _this.updatePanScale(); + } + + _this._triggerChange(evt); + }, + release: function (evt) { + _this._triggerChange(evt); + }, + animationEnd: function (evt) { + _this.trigger(new ComponentEvent("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + }; + + __proto._getValidatedOptions = function (newOptions) { + if (newOptions.yawRange) { + newOptions.yawRange = this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio); + } + + if (newOptions.pitchRange) { + newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov); + } + + return newOptions; + }; + + __proto._getOptions = function (key) { + var value; + + if (typeof key === "string") { + value = this.options[key]; + } else if (arguments.length === 0) { + value = this.options; + } + + return value; + }; + + __proto._setOptions = function (options) { + for (var key in options) { + this.options[key] = options[key]; + } + }; + + __proto._applyOptions = function (keys) { + var options = this.options; + var axes = this._axes; + var isVR = options.gyroMode === GYRO_MODE.VR; + var isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH; // If it's VR mode, restrict user interaction to yaw direction only + + var touchDirection = isVR ? TOUCH_DIRECTION_YAW & options.touchDirection : options.touchDirection; // If one of below is changed, call updateControlScale() + + if (keys.some(function (key) { + return key === "showPolePoint" || key === "fov" || key === "aspectRatio" || key === "yawRange" || key === "pitchRange"; + })) { + // If fov is changed, update pan scale + if (keys.indexOf("fov") >= 0) { + axes.setTo({ + "fov": options.fov + }); + this.updatePanScale(); + } + + this._updateControlScale(); + } + + if (keys.some(function (key) { + return key === "fovRange"; + })) { + var fovRange = options.fovRange; + var prevFov = axes.get().fov; + var nextFov = axes.get().fov; + vec2.copy(axes.axis.fov.range, fovRange); + + if (nextFov < fovRange[0]) { + nextFov = fovRange[0]; + } else if (prevFov > fovRange[1]) { + nextFov = fovRange[1]; + } + + if (prevFov !== nextFov) { + axes.setTo({ + fov: nextFov + }, 0); + + this._updateControlScale(); + + this.updatePanScale(); + } + } + + if (keys.some(function (key) { + return key === "gyroMode"; + }) && SUPPORT_DEVICEMOTION) { + // Disconnect first + if (this._axesTiltMotionInput) { + this._axes.disconnect(this._axesTiltMotionInput); + + this._axesTiltMotionInput.destroy(); + + this._axesTiltMotionInput = null; + } + + if (this._deviceQuaternion) { + this._deviceQuaternion.destroy(); + + this._deviceQuaternion = null; + } + + if (isVR) { + this._initDeviceQuaternion(); + } else if (isYawPitch) { + this._axesTiltMotionInput = new TiltMotionInput(this._element); + + this._axes.connect(["yaw", "pitch"], this._axesTiltMotionInput); + } + + this._axesPanInput.setUseRotation(isVR); + } + + if (keys.some(function (key) { + return key === "useKeyboard"; + })) { + var useKeyboard = options.useKeyboard; + + if (useKeyboard) { + axes.connect(["yaw", "pitch"], this._axesMoveKeyInput); + } else { + axes.disconnect(this._axesMoveKeyInput); + } + } + + if (keys.some(function (key) { + return key === "useZoom"; + })) { + var useZoom = options.useZoom; // Disconnect first + + axes.disconnect(this._axesWheelInput); + + if (useZoom) { + axes.connect(["fov"], this._axesWheelInput); + } + } + + this._togglePinchInputByOption(options.touchDirection, options.useZoom); + + if (keys.some(function (key) { + return key === "touchDirection"; + }) && this._enabled) { + this._enableTouch(touchDirection); + } + }; + + __proto._togglePinchInputByOption = function (touchDirection, useZoom) { + if (this._axesPinchInput) { + // disconnect first + this._axes.disconnect(this._axesPinchInput); // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll. + + + if (useZoom && touchDirection === TOUCH_DIRECTION_ALL && // TODO: Get rid of using private property of axes instance. + this._axes._inputs.indexOf(this._axesPinchInput) === -1) { + this._axes.connect(["fov"], this._axesPinchInput); + } + } + }; + + __proto._enableTouch = function (direction) { + // Disconnect first + if (this._axesPanInput) { + this._axes.disconnect(this._axesPanInput); + } + + var yawEnabled = direction & TOUCH_DIRECTION_YAW ? "yaw" : null; + var pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? "pitch" : null; + + this._axes.connect([yawEnabled, pitchEnabled], this._axesPanInput); + }; + + __proto._initDeviceQuaternion = function () { + var _this = this; + + this._deviceQuaternion = new DeviceQuaternion(); + + this._deviceQuaternion.on("change", function (e) { + _this._triggerChange(e); + }); + }; + + __proto._getValidYawRange = function (newYawRange, newFov, newAspectRatio) { + var ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1); + + var fov = newFov || this._axes.get().fov; + + var horizontalFov = fov * ratio; + var isValid = newYawRange[1] - newYawRange[0] >= horizontalFov; + + if (isValid) { + return newYawRange; + } else { + return this.options.yawRange || DEFAULT_YAW_RANGE; + } + }; + + __proto._getValidPitchRange = function (newPitchRange, newFov) { + var fov = newFov || this._axes.get().fov; + + var isValid = newPitchRange[1] - newPitchRange[0] >= fov; + + if (isValid) { + return newPitchRange; + } else { + return this.options.pitchRange || DEFAULT_PITCH_RANGE; + } + }; + + __proto._isCircular = function (range) { + return range[1] - range[0] < 360 ? [false, false] : [true, true]; + }; + /** + * Update yaw/pitch min/max by 5 factor + * + * 1. showPolePoint + * 2. fov + * 3. yawRange + * 4. pitchRange + * 5. aspectRatio + * + * If one of above is changed, call this function + */ + + + __proto._updateControlScale = function (changeEvt) { + var opt = this.options; + + var fov = this._axes.get().fov; + + var pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint); + + var yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio); // TODO: If not changed!? + + + var pos = this._axes.get(); + + var y = pos.yaw; + var p = pos.pitch; + vec2.copy(this._axes.axis.yaw.range, yRange); + vec2.copy(this._axes.axis.pitch.range, pRange); + this._axes.axis.yaw.circular = this._isCircular(yRange); + this._axes.axis.pitch.circular = this._isCircular(pRange); + /** + * update yaw/pitch by it's range. + */ + + if (y < yRange[0]) { + y = yRange[0]; + } else if (y > yRange[1]) { + y = yRange[1]; + } + + if (p < pRange[0]) { + p = pRange[0]; + } else if (p > pRange[1]) { + p = pRange[1]; + } + + if (changeEvt) { + changeEvt.set({ + yaw: y, + pitch: p + }); + } + + this._axes.setTo({ + yaw: y, + pitch: p + }, 0); + + return this; + }; + + __proto._updatePitchRange = function (pitchRange, fov, showPolePoint) { + if (this.options.gyroMode === GYRO_MODE.VR) { + // Circular pitch on VR + return CIRCULAR_PITCH_RANGE; + } + + var verticalAngle = pitchRange[1] - pitchRange[0]; + var halfFov = fov / 2; + var isPanorama = verticalAngle < 180; + + if (showPolePoint && !isPanorama) { + // Use full pinch range + return pitchRange.concat(); + } // Round value as movableCood do. + + + return [pitchRange[0] + halfFov, pitchRange[1] - halfFov]; + }; + + __proto._updateYawRange = function (yawRange, fov, aspectRatio) { + if (this.options.gyroMode === GYRO_MODE.VR) { + return DEFAULT_YAW_RANGE; + } + + var horizontalAngle = yawRange[1] - yawRange[0]; + /** + * Full 360 Mode + */ + + if (horizontalAngle >= 360) { + // Don't limit yaw range on Full 360 mode. + return yawRange.concat(); + } + /** + * Panorama mode + */ + // Ref : https://github.com/naver/egjs-view360/issues/290 + + + var halfHorizontalFov = util.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))); // Round value as movableCood do. + + return [yawRange[0] + halfHorizontalFov, yawRange[1] - halfHorizontalFov]; + }; // TODO: update param type after Axes event type inference update + + + __proto._triggerChange = function (evt) { + var pos = this._axes.get(); + + var opt = this.options; + var event = { + targetElement: opt.element, + isTrusted: evt.isTrusted, + yaw: pos.yaw, + pitch: pos.pitch, + fov: pos.fov, + quaternion: null + }; + + if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) { + event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + } + + this.trigger(new ComponentEvent("change", event)); + }; // TODO: makes constant to be logic + + + __proto._adjustAspectRatio = function (input) { + var inputRange = [0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670, 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19, 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26, 2.30, 2.60, 3.00, 5.00, 6.00]; + var outputRange = [0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710, 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15, 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72, 1.82, 1.92, 2.00, 2.24, 2.30]; + var rangeIdx = -1; + + for (var i = 0; i < inputRange.length - 1; i++) { + if (inputRange[i] <= input && inputRange[i + 1] >= input) { + rangeIdx = i; + break; + } + } + + if (rangeIdx === -1) { + if (inputRange[0] > input) { + return outputRange[0]; + } else { + // FIXME: this looks definitely wrong + return outputRange[outputRange[0].length - 1]; + } + } + + var inputA = inputRange[rangeIdx]; + var inputB = inputRange[rangeIdx + 1]; + var outputA = outputRange[rangeIdx]; + var outputB = outputRange[rangeIdx + 1]; + return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA)); + }; + + __proto._lerp = function (a, b, fraction) { + return a + fraction * (b - a); + }; + + __proto._resetOrientation = function () { + var opt = this.options; + + this._axes.setTo({ + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }, 0); + + return this; + }; + + YawPitchControl.VERSION = VERSION; // Expose DeviceOrientationControls sub module for test purpose + + YawPitchControl.CONTROL_MODE_VR = CONTROL_MODE_VR; + YawPitchControl.CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH; + YawPitchControl.TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL; + YawPitchControl.TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW; + YawPitchControl.TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH; + YawPitchControl.TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE; + return YawPitchControl; +}(Component); + +/** + * Constant value for errors + * @ko 에러에 대한 상수 값 + * @namespace + * @name ERROR_TYPE + * @memberof eg.view360.PanoViewer + */ + +var ERROR_TYPE = { + /** + * Unsupported device + * @ko 미지원 기기 + * @name INVALID_DEVICE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 10 + */ + INVALID_DEVICE: 10, + + /** + * Webgl not support + * @ko WEBGL 미지원 + * @name NO_WEBGL + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 11 + */ + NO_WEBGL: 11, + + /** + * Failed to load image + * @ko 이미지 로드 실패 + * @name FAIL_IMAGE_LOAD + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 12 + */ + FAIL_IMAGE_LOAD: 12, + + /** + * Failed to bind texture + * @ko 텍스쳐 바인딩 실패 + * @name FAIL_BIND_TEXTURE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 13 + */ + FAIL_BIND_TEXTURE: 13, + + /** + * Only one resource(image or video) should be specified + * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함) + * @name INVALID_RESOURCE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 14 + */ + INVALID_RESOURCE: 14, + + /** + * WebGL context lost occurred + * @ko WebGL context lost 발생 + * @name RENDERING_CONTEXT_LOST + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 15 + */ + RENDERING_CONTEXT_LOST: 15 +}; +/** + * Constant value for events + * @ko 이벤트에 대한 상수 값 + * @namespace + * @name EVENTS + * @memberof eg.view360.PanoViewer + */ + +var PANOVIEWER_EVENTS = { + /** + * Events that is fired when PanoViewer is ready to show image and handle user interaction. + * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트 + * @name READY + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default ready + */ + READY: "ready", + + /** + * Events that is fired when direction or fov is changed. + * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트 + * @name VIEW_CHANGE + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default viewChange + */ + VIEW_CHANGE: "viewChange", + + /** + * Events that is fired when animation which is triggered by inertia is ended. + * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트 + * @name ANIMATION_END + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default animationEnd + */ + ANIMATION_END: "animationEnd", + + /** + * Events that is fired when error occurs + * @ko 에러 발생 시 발생하는 이벤트 + * @name ERROR + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default error + */ + ERROR: "error" +}; +/** + * Constant value for projection type + * @ko 프로젝션 타입 대한 상수 값 + * @namespace + * @name PROJECTION_TYPE + * @memberof eg.view360.PanoViewer + */ + +var PROJECTION_TYPE = { + /** + * Constant value for equirectangular type. + * @ko equirectangular 에 대한 상수 값. + * @name EQUIRECTANGULAR + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default equirectangular + */ + EQUIRECTANGULAR: "equirectangular", + + /** + * Constant value for cubemap type. + * @ko cubemap 에 대한 상수 값. + * @name CUBEMAP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubemap + */ + CUBEMAP: "cubemap", + + /** + * Constant value for cubestrip type. + * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC. + * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다. + * @name CUBESTRIP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubestrip + */ + CUBESTRIP: "cubestrip", + + /** + * Constant value for PANORAMA type. + * + * PANORAMA is a format for a panorma image which is taken from smartphone. + * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다. + * + * @name PANORAMA + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default panorama + */ + PANORAMA: "panorama", + + /** + * Constant value for EQUI_STEREOSCOPY type. + * + * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present. + * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다. + * + * @name STEREOSCOPIC_EQUI + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default stereoequi + */ + STEREOSCOPIC_EQUI: "stereoequi" +}; +/** + * A constant value for the format of the stereoscopic equirectangular projection type. + * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값 + * @namespace + * @name STEREO_FORMAT + * @memberof eg.view360.PanoViewer + */ + +var STEREO_FORMAT = { + /** + * A constant value for format of top bottom stereoscopic 360 equirectangular projection. + * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name TOP_BOTTOM + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dv" + */ + TOP_BOTTOM: "3dv", + + /** + * A constant value for format of left right stereoscopic 360 equirectangular projection. + * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name LEFT_RIGHT + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dh" + */ + LEFT_RIGHT: "3dh", + + /** + * A constant value specifying media is not in stereoscopic format. + * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값. + * @name NONE + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "" + */ + NONE: "" +}; // eslint-disable-next-line @typescript-eslint/no-unused-vars + +var PANOVIEWER_OPTIONS = { + image: true, + video: true, + projectionType: true, + cubemapConfig: true, + stereoFormat: true, + width: true, + height: true, + yaw: true, + pitch: true, + fov: true, + showPolePoint: true, + useZoom: true, + useKeyboard: true, + gyroMode: true, + yawRange: true, + pitchRange: true, + fovRange: true, + touchDirection: true, + canvasClass: true +}; +var DEFAULT_CANVAS_CLASS = "view360-canvas"; + +var merge = function (target) { + var srcs = []; + + for (var _i = 1; _i < arguments.length; _i++) { + srcs[_i - 1] = arguments[_i]; + } + + srcs.forEach(function (source) { + Object.keys(source).forEach(function (key) { + var value = source[key]; + + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = __spread(target[key], value); + } else { + target[key] = value; + } + }); + }); + return target; +}; +var toImageElement = function (image) { + var images = image instanceof Array ? image : [image]; + var parsedImages = images.map(function (img) { + var imgEl = img; + + if (typeof img === "string") { + imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = img; + } + + return imgEl; + }); + return parsedImages.length === 1 ? parsedImages[0] : parsedImages; +}; +var toVideoElement = function (videoCandidate) { + if (videoCandidate instanceof HTMLVideoElement) { + return videoCandidate; + } else { + // url + var video_1 = document.createElement("video"); + video_1.setAttribute("crossorigin", "anonymous"); + video_1.setAttribute("webkit-playsinline", ""); + video_1.setAttribute("playsinline", ""); + + if (videoCandidate instanceof Array) { + videoCandidate.forEach(function (v) { + return appendSourceElement(video_1, v); + }); + } else { + appendSourceElement(video_1, videoCandidate); + } + + var sourceCount = video_1.querySelectorAll("source").length; + + if (sourceCount > 0) { + if (video_1.readyState < 1) { + video_1.load(); + } + } + + return video_1; + } +}; +/** + * + * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src} + */ + +var appendSourceElement = function (video, videoUrl) { + var videoSrc; + var videoType; + + if (typeof videoUrl === "object") { + videoSrc = videoUrl.src; + videoType = videoUrl.type; + } else if (typeof videoUrl === "string") { + videoSrc = videoUrl; + } + + if (!videoSrc) { + return false; + } + + var sourceElement = document.createElement("source"); + sourceElement.src = videoSrc; + + if (videoType) { + sourceElement.type = videoType; + } + + video.appendChild(sourceElement); +}; + +var WEBGL_ERROR_CODE = { + "0": "NO_ERROR", + "1280": "INVALID_ENUM", + "1281": "INVALID_VALUE", + "1282": "INVALID_OPERATION", + "1285": "OUT_OF_MEMORY", + "1286": "INVALID_FRAMEBUFFER_OPERATION", + "37442": "CONTEXT_LOST_WEBGL" +}; +var webglAvailability = null; // eslint-disable-next-line @typescript-eslint/naming-convention + +var WebGLUtils = +/*#__PURE__*/ +function () { + function WebGLUtils() {} + + WebGLUtils.createShader = function (gl, type, source) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + + if (success) { + return shader; + } // eslint-disable-next-line + + + console.error(gl.getShaderInfoLog(shader)); + return null; + }; + + WebGLUtils.createProgram = function (gl, vertexShader, fragmentShader) { + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + var success = gl.getProgramParameter(program, gl.LINK_STATUS); + + if (success) { + return program; + } + + gl.deleteProgram(program); + return null; + }; + + WebGLUtils.initBuffer = function (gl, target + /* bind point */ + , data, itemSize, attr) { + var buffer = gl.createBuffer(); + gl.bindBuffer(target, buffer); + gl.bufferData(target, data, gl.STATIC_DRAW); + + if (buffer) { + buffer.itemSize = itemSize; + buffer.numItems = data.length / itemSize; + } + + if (attr !== undefined) { + gl.enableVertexAttribArray(attr); + gl.vertexAttribPointer(attr, buffer.itemSize, gl.FLOAT, false, 0, 0); + } + + return buffer; + }; + + WebGLUtils.getWebglContext = function (canvas, userContextAttributes) { + var e_1, _a; + + var webglIdentifiers = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + var context = null; + + var contextAttributes = __assign({ + preserveDrawingBuffer: false, + antialias: false + }, userContextAttributes); + + var onWebglcontextcreationerror = function (e) { + return e.statusMessage; + }; + + canvas.addEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + + try { + for (var webglIdentifiers_1 = __values(webglIdentifiers), webglIdentifiers_1_1 = webglIdentifiers_1.next(); !webglIdentifiers_1_1.done; webglIdentifiers_1_1 = webglIdentifiers_1.next()) { + var identifier = webglIdentifiers_1_1.value; + + try { + context = canvas.getContext(identifier, contextAttributes); + } catch (t) {} // eslint-disable-line no-empty + + + if (context) { + break; + } + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (webglIdentifiers_1_1 && !webglIdentifiers_1_1.done && (_a = webglIdentifiers_1.return)) _a.call(webglIdentifiers_1); + } finally { + if (e_1) throw e_1.error; + } + } + + canvas.removeEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + return context; + }; + + WebGLUtils.createTexture = function (gl, textureTarget) { + var texture = gl.createTexture(); + gl.bindTexture(textureTarget, texture); + gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindTexture(textureTarget, null); + return texture; + }; + /** + * Returns the webgl availability of the current browser. + * @method WebGLUtils#isWebGLAvailable + * @retuen {Boolean} isWebGLAvailable + */ + + + WebGLUtils.isWebGLAvailable = function () { + if (webglAvailability === null) { + var canvas = document.createElement("canvas"); + var webglContext = WebGLUtils.getWebglContext(canvas); + webglAvailability = !!webglContext; // webglContext Resource forced collection + + if (webglContext) { + var loseContextExtension = webglContext.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + } + + return !!webglAvailability; + }; + /** + * Returns whether webgl is stable in the current browser. + * @method WebGLUtils#isStableWebGL + * @retuen {Boolean} isStableWebGL + */ + + + WebGLUtils.isStableWebGL = function () { + var agentInfo = agent$1(); + var isStableWebgl = true; + + if (agentInfo.os.name === "android") { + var version = parseFloat(agentInfo.os.version); + + if (version <= 4.3 && version >= 1) { + isStableWebgl = false; + } else if (version === 4.4) { + if (agentInfo.browser.name !== "chrome") { + isStableWebgl = false; + } + } + } + + return isStableWebgl; + }; + + WebGLUtils.getErrorNameFromWebGLErrorCode = function (code) { + if (!(code in WEBGL_ERROR_CODE)) { + return "UNKNOWN_ERROR"; + } + + return WEBGL_ERROR_CODE[code]; + }; + /** + * This function is wrapper for texImage2D to handle exceptions on texImage2D. + * Purpose is to prevent service from being stopped by script error. + */ + + + WebGLUtils.texImage2D = function (gl, target, pixels) { + try { + gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + } catch (error) { + /* eslint-disable no-console */ + console.error("WebGLUtils.texImage2D error:", error); + /* eslint-enable no-console */ + } + }; + + WebGLUtils.getMaxTextureSize = function (gl) { + // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test + return gl.getParameter(gl.MAX_TEXTURE_SIZE); + }; + + return WebGLUtils; +}(); + +var agentInfo = agent$1(); +var isIE11 = agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11; +var EVENTS = { + ERROR: "error" +}; +/** + * + * Extends Component for firing errors occurs internally. + */ + +var Renderer = +/*#__PURE__*/ +function (_super) { + __extends(Renderer, _super); + + function Renderer() { + var _this = _super.call(this) || this; + + _this._forceDimension = null; + _this._pixelCanvas = null; + _this._pixelContext = null; + return _this; + } + + var __proto = Renderer.prototype; + + __proto.render = function (_a) { + var gl = _a.gl, + shaderProgram = _a.shaderProgram, + indexBuffer = _a.indexBuffer, + mvMatrix = _a.mvMatrix, + pMatrix = _a.pMatrix; + gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); + gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); + + if (indexBuffer) { + gl.drawElements(gl.TRIANGLES, indexBuffer.numItems, gl.UNSIGNED_SHORT, 0); + } + }; // Define interface for Renderers + + /** + * Following MUST BE DEFINED on Child of Renderer + * + * DATA + * + * - getVertexPositionData + * - getIndexData + * - getTextureCoordData + * + * SOURCE + * + * - getVertexShaderSource + * - getFragmentShaderSource + * + * TEXTURE + * + * - bindTexture + */ + + + __proto.getDimension = function (pixelSource) { + var width = pixelSource.naturalWidth || pixelSource.videoWidth; + var height = pixelSource.naturalHeight || pixelSource.videoHeight; + return { + width: width, + height: height + }; + }; + /** + * Update data used by shader + */ + + + __proto.updateShaderData = function (param) { + /* + * Update following data in implementation layer. + * If the data is not changed, it does not need to implement this function. + * + * - _VERTEX_POSITION_DATA + * - _TEXTURE_COORD_DATA + * - _INDEX_DATA + */ + }; + /** + * + * @param {HTMLImageElement | HTMLVideoElement} image + * @param {Object = {width, height}} forceDimension Forced dimension to resize + */ + + + __proto._initPixelSource = function (image, forceDimension) { + if (forceDimension === void 0) { + forceDimension = null; + } + + var isIE11Video = isIE11 && image instanceof HTMLVideoElement; + + if (isIE11Video || forceDimension) { + var _a = forceDimension || this.getDimension(image), + width = _a.width, + height = _a.height; + + this._pixelCanvas = document.createElement("canvas"); + this._pixelCanvas.width = width; + this._pixelCanvas.height = height; + this._pixelContext = this._pixelCanvas.getContext("2d"); + } + + this._forceDimension = forceDimension; + }; + + __proto._getPixelSource = function (image) { + if (!this._pixelCanvas) { + return image; + } + /** + * IE11 && Video + * or + * Dimension is forced (Image is larger than texture size.) + */ + + + var contentDimension = this.getDimension(image); + var textureDimension = this._forceDimension || contentDimension; + + if (this._pixelCanvas.width !== textureDimension.width) { + this._pixelCanvas.width = textureDimension.width; + } + + if (this._pixelCanvas.height !== textureDimension.height) { + this._pixelCanvas.height = textureDimension.height; + } + + if (this._forceDimension) { + this._pixelContext.drawImage(image, 0, 0, contentDimension.width, contentDimension.height, 0, 0, textureDimension.width, textureDimension.height); + } else { + this._pixelContext.drawImage(image, 0, 0); + } + + return this._pixelCanvas; + }; + + __proto._extractTileConfig = function (imageConfig) { + var tileConfig = Array.isArray(imageConfig.tileConfig) ? imageConfig.tileConfig : Array.apply(void 0, __spread(Array(6))).map(function () { + return imageConfig.tileConfig; + }); + tileConfig = tileConfig.map(function (config) { + return __assign({ + flipHorizontal: false, + rotation: 0 + }, config); + }); + return tileConfig; + }; + + __proto._triggerError = function (error) { + /* eslint-disable no-console */ + console.error("Renderer Error:", error); + /* eslint-enable no-console */ + + this.trigger(new ComponentEvent(EVENTS.ERROR, { + message: typeof error === "string" ? error : error.message + })); + }; + + Renderer.EVENTS = EVENTS; + return Renderer; +}(Component); + +var CubeRenderer = +/*#__PURE__*/ +function (_super) { + __extends(CubeRenderer, _super); + + function CubeRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeRenderer.prototype; + + CubeRenderer.extractOrder = function (imageConfig) { + return imageConfig.order || "RLUDBF"; + }; + + __proto.getVertexPositionData = function () { + CubeRenderer._VERTEX_POSITION_DATA = CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // top + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // bottom + 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + return CubeRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + if (CubeRenderer._INDEX_DATA) { + return CubeRenderer._INDEX_DATA; + } + + var indexData = []; + var vertexPositionData = this.getVertexPositionData(); + + for (var i = 0; i < vertexPositionData.length / 3; i += 4) { + indexData.push(i, i + 2, i + 1, i, i + 3, i + 2); + } + + CubeRenderer._INDEX_DATA = indexData; + return indexData; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; + var vertexOrder = "BFUDRL"; + var order = CubeRenderer.extractOrder(imageConfig); + var base = this.getVertexPositionData(); + + var tileConfig = this._extractTileConfig(imageConfig); + + var elemSize = 3; + var vertexPerTile = 4; + var trim = imageConfig.trim; + var texCoords = vertexOrder.split("").map(function (face) { + return tileConfig[order.indexOf(face)]; + }).map(function (config, i) { + var rotation = Math.floor(config.rotation / 90); + var ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2]; + + for (var r = 0; r < Math.abs(rotation); r++) { + if (config.flipHorizontal && rotation > 0 || !config.flipHorizontal && rotation < 0) { + ordermap.push(ordermap.shift()); + } else { + ordermap.unshift(ordermap.pop()); + } + } + + var elemPerTile = elemSize * vertexPerTile; + var tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile); + var tileTemp = []; + + for (var j = 0; j < vertexPerTile; j++) { + tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize); + } + + return tileTemp; + }).map(function (coord) { + return _this._shrinkCoord({ + image: image, + faceCoords: coord, + trim: trim + }); + }).reduce(function (acc, val) { + return __spread(acc, val.reduce(function (coords, coord) { + return __spread(coords, coord); + }, [])); + }, []); + return texCoords; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}"; + }; + + __proto.updateTexture = function (gl, image, imageConfig) { + var baseOrder = "RLUDBF"; + var order = CubeRenderer.extractOrder(imageConfig); + var orderMap = {}; + order.split("").forEach(function (v, i) { + orderMap[v] = i; + }); + + try { + if (image instanceof Array) { + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]); + } + } else { + var maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image); + + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + var tile = this.extractTileFromImage(image, tileIdx, maxCubeMapTextureSize); + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile); + } + } + } catch (e) { + this._triggerError(e); + } + }; + + __proto.bindTexture = function (gl, texture, image, imageConfig) { + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + this.updateTexture(gl, image, imageConfig); + }; + + __proto.getSourceTileSize = function (image) { + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var aspectRatio = width / height; + var inputTextureSize; + + if (aspectRatio === 1 / 6) { + inputTextureSize = width; + } else if (aspectRatio === 6) { + inputTextureSize = height; + } else if (aspectRatio === 2 / 3) { + inputTextureSize = width / 2; + } else { + inputTextureSize = width / 3; + } + + return inputTextureSize; + }; + + __proto.extractTileFromImage = function (image, tileIdx, outputTextureSize) { + var width = this.getDimension(image).width; + var inputTextureSize = this.getSourceTileSize(image); + var canvas = document.createElement("canvas"); + canvas.width = outputTextureSize; + canvas.height = outputTextureSize; + var context = canvas.getContext("2d"); + var tilePerRow = width / inputTextureSize; + var x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow); + var y = Math.floor(tileIdx / tilePerRow) * inputTextureSize; + context.drawImage(image, x, y, inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize); + return canvas; + }; + + __proto.getMaxCubeMapTextureSize = function (gl, image) { + var agentInfo = agent$1(); + var maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); + var imageWidth = this.getSourceTileSize(image); + + if (agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11) { + if (!util.isPowerOfTwo(imageWidth)) { + for (var i = 1; i < maxCubeMapTextureSize; i *= 2) { + if (i < imageWidth) { + continue; + } else { + imageWidth = i; + break; + } + } + } + } + + if (agentInfo.os.name === "ios") { + var majorVersion = agentInfo.os.majorVersion; // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다. + + if (majorVersion === 9) { + imageWidth = 1024; + } // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다. + + + if (majorVersion === 8) { + imageWidth = 512; + } + } // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수 + + + return Math.min(maxCubeMapTextureSize, imageWidth); + }; + + __proto._shrinkCoord = function (coordData) { + var image = coordData.image, + faceCoords = coordData.faceCoords, + trim = coordData.trim; + var inputTextureSize = Array.isArray(image) ? this.getDimension(image[0]).width : this.getSourceTileSize(image); // Shrink by "trim" px + + var SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize); + var axisMultipliers = [0, 1, 2].map(function (axisIndex) { + var axisDir = util.sign(faceCoords[0][axisIndex]); + var notSameDir = faceCoords.some(function (coord) { + return util.sign(coord[axisIndex]) !== axisDir; + }); + return notSameDir; + }).map(function (notSameDir) { + return notSameDir ? SHRINK_MULTIPLIER : 1; + }); + return faceCoords.map(function (coords) { + return coords.map(function (coord, axisIndex) { + return coord * axisMultipliers[axisIndex]; + }); + }); + }; + + CubeRenderer._VERTEX_POSITION_DATA = null; + CubeRenderer._INDEX_DATA = null; + return CubeRenderer; +}(Renderer); + +var CubeStripRenderer = +/*#__PURE__*/ +function (_super) { + __extends(CubeStripRenderer, _super); + + function CubeStripRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeStripRenderer.prototype; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"; + }; + + __proto.getVertexPositionData = function () { + if (!this._vertices) { + this._vertices = [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + } + + return this._vertices; + }; + + __proto.getIndexData = function () { + var _this = this; // TODO: 한번만 계산하도록 수정하기 + + + var indices = function () { + var indexData = []; + + for (var i = 0; i < _this._vertices.length / 3; i += 4) { + indexData.push(i, i + 1, i + 2, i, i + 2, i + 3); + } + + return indexData; + }(); + + return indices; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; // TODO: make it cols, rows as config. + + var cols = 3; + var rows = 2; + var textureSize = this.getDimension(image); + var trim = imageConfig.trim; + var order = imageConfig.order || "RLUDFB"; + var coords = []; // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다. + + for (var r = rows - 1; r >= 0; r--) { + for (var c = 0; c < cols; c++) { + var coord = [c / cols, r / rows, (c + 1) / cols, r / rows, (c + 1) / cols, (r + 1) / rows, c / cols, (r + 1) / rows]; + coords.push(coord); + } + } + + var tileConfigs = this._extractTileConfig(imageConfig); // Transform Coord By Flip & Rotation + + + coords = coords // shrink coord to avoid pixel bleeding + .map(function (coord) { + return _this._shrinkCoord(coord, textureSize, trim); + }).map(function (coord, i) { + return _this._transformCoord(coord, tileConfigs[i]); + }); // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치 + + return "BFUDRL".split("").map(function (face) { + return order.indexOf(face); + }).map(function (index) { + return coords[index]; + }).reduce(function (acc, val) { + return acc.concat(val); + }, []); + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto._transformCoord = function (coord, tileConfig) { + var newCoord = coord.slice(); + + if (tileConfig.flipHorizontal) { + newCoord = this._flipHorizontalCoord(newCoord); + } + + if (tileConfig.rotation) { + newCoord = this._rotateCoord(newCoord, tileConfig.rotation); + } + + return newCoord; + }; + + __proto._shrinkCoord = function (coord, textureSize, trim) { + var width = textureSize.width, + height = textureSize.height; // Shrink by "trim" px + + var SHRINK_Y = trim * (1 / height); + var SHRINK_X = trim * (1 / width); + return [coord[0] + SHRINK_X, coord[1] + SHRINK_Y, coord[2] - SHRINK_X, coord[3] + SHRINK_Y, coord[4] - SHRINK_X, coord[5] - SHRINK_Y, coord[6] + SHRINK_X, coord[7] - SHRINK_Y]; + }; + + __proto._rotateCoord = function (coord, rotationAngle) { + var SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord. + + var shiftCount = Math.floor(rotationAngle / 90) % 4; + + if (shiftCount === 0) { + return coord; + } + + var moved; + var rotatedCoord = []; + + if (shiftCount > 0) { + moved = coord.splice(0, shiftCount * SIZE); + rotatedCoord = coord.concat(moved); + } else { + moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE); + rotatedCoord = moved.concat(coord); + } + + return rotatedCoord; + }; + + __proto._flipHorizontalCoord = function (coord) { + return [coord[2], coord[3], coord[0], coord[1], coord[6], coord[7], coord[4], coord[5]]; + }; + + return CubeStripRenderer; +}(Renderer); + +var latitudeBands = 60; +var longitudeBands = 60; +var radius = 2; +var ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; +var textureCoordData = []; +var vertexPositionData = []; +var indexData = []; +var latIdx; +var lngIdx; + +for (latIdx = 0; latIdx <= latitudeBands; latIdx++) { + var theta = (latIdx / latitudeBands - 0.5) * Math.PI; + var sinTheta = Math.sin(theta); + var cosTheta = Math.cos(theta); + + for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) { + var phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + var sinPhi = Math.sin(phi); + var cosPhi = Math.cos(phi); + var x = cosPhi * cosTheta; + var y = sinTheta; + var z = sinPhi * cosTheta; + var u = lngIdx / longitudeBands; + var v = latIdx / latitudeBands; + textureCoordData.push(u, v); + vertexPositionData.push(radius * x, radius * y, radius * z); + + if (lngIdx !== longitudeBands && latIdx !== latitudeBands) { + var a = latIdx * (longitudeBands + 1) + lngIdx; + var b = a + longitudeBands + 1; + indexData.push(a, b, a + 1, b, b + 1, a + 1); + } + } +} + +var SphereRenderer = +/*#__PURE__*/ +function (_super) { + __extends(SphereRenderer, _super); + + function SphereRenderer(format) { + var _this = _super.call(this) || this; + + _this._stereoFormat = format; + return _this; + } + + var __proto = SphereRenderer.prototype; + + __proto.render = function (ctx) { + var gl = ctx.gl, + shaderProgram = ctx.shaderProgram; + var leftEyeScaleOffset; + var rightEyeScaleOffset; + + switch (this._stereoFormat) { + case STEREO_FORMAT.TOP_BOTTOM: + leftEyeScaleOffset = [1, 0.5, 0, 0]; + rightEyeScaleOffset = [1, 0.5, 0, 0.5]; + break; + + case STEREO_FORMAT.LEFT_RIGHT: + leftEyeScaleOffset = [0.5, 1, 0, 0]; + rightEyeScaleOffset = [0.5, 1, 0.5, 0]; + break; + + default: + leftEyeScaleOffset = [1, 1, 0, 0]; + rightEyeScaleOffset = [1, 1, 0, 0]; + } + + var uTexScaleOffset = gl.getUniformLocation(shaderProgram, "uTexScaleOffset"); + gl.uniform4fv(uTexScaleOffset, __spread(leftEyeScaleOffset, rightEyeScaleOffset)); + + _super.prototype.render.call(this, ctx); + }; + + __proto.getVertexPositionData = function () { + return SphereRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return SphereRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return SphereRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + SphereRenderer._VERTEX_POSITION_DATA = vertexPositionData; + SphereRenderer._TEXTURE_COORD_DATA = textureCoordData; + SphereRenderer._INDEX_DATA = indexData; + return SphereRenderer; +}(Renderer); + +var MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6; +var longitudeBands$1 = 60; +var textureCoordData$1 = []; +var vertexPositionData$1 = []; +var indexData$1 = []; + +var CylinderRenderer = +/*#__PURE__*/ +function (_super) { + __extends(CylinderRenderer, _super); + + function CylinderRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CylinderRenderer.prototype; + + __proto.getVertexPositionData = function () { + return CylinderRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return CylinderRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return CylinderRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + var resizeDimension; + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device texture limit(" + maxSize + "))"); // Request resizing texture. + + /** + * TODO: Is it need to apply on another projection type? + */ + + + resizeDimension = width > height ? { + width: maxSize, + height: maxSize * height / width + } : { + width: maxSize * width / height, + height: maxSize + }; + } // Pixel Source for IE11 & Video or resizing needed + + + this._initPixelSource(image, resizeDimension); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto.updateShaderData = function (_a) { + var _b = _a.imageAspectRatio, + imageAspectRatio = _b === void 0 ? MIN_ASPECT_RATIO_FOR_FULL_PANORAMA : _b; + var lngIdx; + var cylinderMaxRadian; + var halfCylinderY; + var rotated; + var aspectRatio; // Exception case: orientation is rotated. + + if (imageAspectRatio < 1) { + /** + * If rotated is true, we assume that image is rotated counter clockwise. + * TODO: If there's other rotation, it is need to implement by each rotation. + */ + rotated = true; + aspectRatio = 1 / imageAspectRatio; + } else { + rotated = false; + aspectRatio = imageAspectRatio; + } + + if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) { + var fov = 360 / aspectRatio; + cylinderMaxRadian = 2 * Math.PI; // 360 deg + + halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2)); + } else { + cylinderMaxRadian = aspectRatio; + halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1. + } // initialize shader data before update + + + textureCoordData$1.length = 0; + vertexPositionData$1.length = 0; + indexData$1.length = 0; + var CYLIDER_Y = [-halfCylinderY, halfCylinderY]; + var startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360) + // console.log("cylinderMaxRadian:", glMatrix.toDegree(cylinderMaxRadian), "CYLIDER_Y", CYLIDER_Y, "start angle", glMatrix.toDegree(startAngleForCenterAlign)); + + for (var yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength + /* bottom & top */ + ; yIdx++) { + for (lngIdx = 0; lngIdx <= longitudeBands$1; lngIdx++) { + var angle = startAngleForCenterAlign + lngIdx / longitudeBands$1 * cylinderMaxRadian; + var x = Math.cos(angle); + var y = CYLIDER_Y[yIdx]; + var z = Math.sin(angle); + var u = void 0; + var v = void 0; + + if (rotated) { + // Rotated 90 degree (counter clock wise) + u = 1 - yIdx; // yLength - yIdx; + + v = lngIdx / longitudeBands$1; + } else { + // // Normal case (Not rotated) + u = lngIdx / longitudeBands$1; + v = yIdx; + } + + textureCoordData$1.push(u, v); + vertexPositionData$1.push(x, y, z); + + if (yIdx === 0 && lngIdx < longitudeBands$1) { + var a = lngIdx; + var b = a + longitudeBands$1 + 1; + indexData$1.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + }; + + CylinderRenderer._VERTEX_POSITION_DATA = vertexPositionData$1; + CylinderRenderer._TEXTURE_COORD_DATA = textureCoordData$1; + CylinderRenderer._INDEX_DATA = indexData$1; + return CylinderRenderer; +}(Renderer); + +var VR_DISPLAY_PRESENT_CHANGE = "vrdisplaypresentchange"; +var DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1]; +var DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1]; +var EYES = { + LEFT: "left", + RIGHT: "right" +}; + +var VRManager = +/*#__PURE__*/ +function () { + function VRManager() { + var _this = this; + + this.destroy = function () { + var vrDisplay = _this._vrDisplay; + + _this.removeEndCallback(_this.destroy); + + if (vrDisplay && vrDisplay.isPresenting) { + void vrDisplay.exitPresent(); + } + + _this._clear(); + }; + + this._frameData = new window.VRFrameData(); + + this._clear(); + } + + var __proto = VRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._vrDisplay; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function () { + return Boolean(this._vrDisplay); + }; + + __proto.beforeRender = function (gl) { + // Render to the default backbuffer + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + }; + + __proto.afterRender = function () { + this._vrDisplay.submitFrame(); + }; + + __proto.getEyeParams = function (gl) { + var display = this._vrDisplay; + var halfWidth = gl.drawingBufferWidth * 0.5; + var height = gl.drawingBufferHeight; + var frameData = this._frameData; + display.getFrameData(frameData); + var leftMVMatrix = frameData.leftViewMatrix; + var rightMVMatrix = frameData.rightViewMatrix; + mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset); + mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset); + return [{ + viewport: [0, 0, halfWidth, height], + mvMatrix: leftMVMatrix, + pMatrix: frameData.leftProjectionMatrix + }, { + viewport: [halfWidth, 0, halfWidth, height], + mvMatrix: rightMVMatrix, + pMatrix: frameData.rightProjectionMatrix + }]; + }; + + __proto.isPresenting = function () { + return Boolean(this._vrDisplay && this._vrDisplay.isPresenting); + }; + + __proto.addEndCallback = function (callback) { + window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.removeEndCallback = function (callback) { + window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.requestPresent = function (canvas) { + var _this = this; + + return navigator.getVRDisplays().then(function (displays) { + var vrDisplay = displays.length && displays[0]; + + if (!vrDisplay) { + return Promise$1.reject(new Error("No displays available.")); + } + + if (!vrDisplay.capabilities.canPresent) { + return Promise$1.reject(new Error("Display lacking capability to present.")); + } + + return vrDisplay.requestPresent([{ + source: canvas + }]).then(function () { + var leftEye = vrDisplay.getEyeParameters(EYES.LEFT); + var rightEye = vrDisplay.getEyeParameters(EYES.RIGHT); + canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2; + canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight); + + _this._setDisplay(vrDisplay); + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setDisplay = function (vrDisplay) { + this._vrDisplay = vrDisplay; + var layers = vrDisplay.getLayers(); + + if (layers.length) { + var layer = layers[0]; + this._leftBounds = layer.leftBounds; + this._rightBounds = layer.rightBounds; + } + + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._vrDisplay = null; + this._leftBounds = DEFAULT_LEFT_BOUNDS; + this._rightBounds = DEFAULT_RIGHT_BOUNDS; + this._yawOffset = 0; + }; + + return VRManager; +}(); + +var XR_REFERENCE_SPACE = "local"; + +var XRManager = +/*#__PURE__*/ +function () { + function XRManager(options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + this.destroy = function () { + var xrSession = _this._xrSession; + + _this.removeEndCallback(_this.destroy); + + if (xrSession) { + // Capture to avoid errors + xrSession.end().then(function () { + return void 0; + }, function () { + return void 0; + }); + } + + _this._clear(); + }; + + this._clear(); + + this._options = options; + } + + var __proto = XRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._xrSession; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function (frame) { + var pose = frame.getViewerPose(this._xrRefSpace); + return Boolean(pose); + }; + + __proto.beforeRender = function (gl, frame) { + var session = frame.session; + var baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + }; // eslint-disable-next-line @typescript-eslint/no-empty-function + + + __proto.afterRender = function () {}; + + __proto.getEyeParams = function (gl, frame) { + var _this = this; + + var session = frame.session; + var pose = frame.getViewerPose(this._xrRefSpace); + + if (!pose) { + // Can't render + return null; + } + + var glLayer = session.renderState.baseLayer; + return pose.views.map(function (view) { + var viewport = glLayer.getViewport(view); + var mvMatrix = view.transform.inverse.matrix; + + if (IS_SAFARI_ON_DESKTOP) { + mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180)); + } + + mat4.rotateY(mvMatrix, mvMatrix, _this._yawOffset); + return { + viewport: [viewport.x, viewport.y, viewport.width, viewport.height], + mvMatrix: mvMatrix, + pMatrix: view.projectionMatrix + }; + }); + }; + + __proto.isPresenting = function () { + return this._presenting; + }; + + __proto.addEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.addEventListener("end", callback); + }; + + __proto.removeEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.removeEventListener("end", callback); + }; + + __proto.requestPresent = function (canvas, gl) { + return __awaiter(this, void 0, void 0, function () { + var options, attributes; + + var _this = this; + + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = merge({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + attributes = gl.getContextAttributes(); + if (!(attributes && attributes.xrCompatible !== true)) return [3 + /*break*/ + , 2]; + return [4 + /*yield*/ + , gl.makeXRCompatible()]; + + case 1: + _a.sent(); + + _a.label = 2; + + case 2: + return [2 + /*return*/ + , navigator.xr.requestSession("immersive-vr", options).then(function (session) { + var xrLayer = new window.XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + return session.requestReferenceSpace(XR_REFERENCE_SPACE).then(function (refSpace) { + _this._setSession(session, xrLayer, refSpace); + }); + })]; + } + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setSession = function (session, xrLayer, refSpace) { + this._xrSession = session; + this._xrLayer = xrLayer; + this._xrRefSpace = refSpace; + this._presenting = true; + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._xrSession = null; + this._xrLayer = null; + this._xrRefSpace = null; + this._presenting = false; + this._yawOffset = 0; + this._options = {}; + }; + + return XRManager; +}(); + +var WebGLAnimator = +/*#__PURE__*/ +function () { + function WebGLAnimator() { + var _this = this; + /** + * There can be more than 1 argument when we use XRSession's raf + */ + + + this._onLoop = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + _this._callback.apply(_this, __spread(args)); + + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + }; + /** + * MacOS X Safari Bug Fix + * This code guarantees that rendering should be occurred. + * + * In MacOS X(10.14.2), Safari (12.0.2) + * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term + * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms) + * So browser cannot render the frame and may be freezing. + */ + + + this._onLoopNextTick = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + var before = performance.now(); + + _this._callback.apply(_this, __spread(args)); + + var diff = performance.now() - before; + + if (_this._rafTimer >= 0) { + clearTimeout(_this._rafTimer); + _this._rafTimer = -1; + } + /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */ + + + if (diff < 16) { + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + } else { + /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */ + _this._rafTimer = window.setTimeout(_this._onLoop, 0); + } + }; + + this._callback = null; + this._context = window; + this._rafId = -1; + this._rafTimer = -1; + } + + var __proto = WebGLAnimator.prototype; + + __proto.setCallback = function (callback) { + this._callback = callback; + }; + + __proto.setContext = function (context) { + this._context = context; + }; + + __proto.start = function () { + var context = this._context; + var callback = this._callback; // No context / callback set + + if (!context || !callback) return; // Animation already started + + if (this._rafId >= 0 || this._rafTimer >= 0) return; + + if (IS_SAFARI_ON_DESKTOP) { + this._rafId = context.requestAnimationFrame(this._onLoopNextTick); + } else { + this._rafId = context.requestAnimationFrame(this._onLoop); + } + }; + + __proto.stop = function () { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + + this._rafId = -1; + this._rafTimer = -1; + }; + + return WebGLAnimator; +}(); + +var ImageType = PROJECTION_TYPE; // eslint-disable-next-line @typescript-eslint/naming-convention + +var DEVICE_PIXEL_RATIO = devicePixelRatio || 1; // DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다. + +if (DEVICE_PIXEL_RATIO > 2) { + DEVICE_PIXEL_RATIO = 2; +} // define custom events name + +/** + * TODO: how to manage events/errortype with PanoViewer + * + * I think renderer events should be seperated from viewer events although it has same name. + */ + + +var EVENTS$1 = { + BIND_TEXTURE: "bindTexture", + IMAGE_LOADED: "imageLoaded", + ERROR: "error", + RENDERING_CONTEXT_LOST: "renderingContextLost", + RENDERING_CONTEXT_RESTORE: "renderingContextRestore" +}; +var ERROR_TYPE$1 = { + INVALID_DEVICE: 10, + NO_WEBGL: 11, + FAIL_IMAGE_LOAD: 12, + RENDERER_ERROR: 13 +}; + +var PanoImageRenderer = +/*#__PURE__*/ +function (_super) { + __extends(PanoImageRenderer, _super); + + function PanoImageRenderer(image, width, height, isVideo, container, canvasClass, sphericalConfig, renderingContextAttributes) { + var _this = // Super constructor + _super.call(this) || this; + + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + + _this.exitVR = function () { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; + if (!vr) return; + vr.removeEndCallback(_this.exitVR); + vr.destroy(); + _this._vr = null; // Restore canvas & context on iOS + + if (IS_IOS) { + _this._restoreStyle(); + } + + _this.updateViewportDimensions(_this.width, _this.height); + + _this._updateViewport(); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + _this._bindBuffers(); + + _this._shouldForceDraw = true; + animator.stop(); + animator.setContext(window); + animator.setCallback(_this._render.bind(_this)); + animator.start(); + }; + + _this._renderStereo = function (time, frame) { + var e_1, _a; + + var vr = _this._vr; + var gl = _this.context; + var eyeParams = vr.getEyeParams(gl, frame); + if (!eyeParams) return; + vr.beforeRender(gl, frame); + + try { + // Render both eyes + for (var _b = __values([0, 1]), _c = _b.next(); !_c.done; _c = _b.next()) { + var eyeIndex = _c.value; + var eyeParam = eyeParams[eyeIndex]; + _this.mvMatrix = eyeParam.mvMatrix; + _this.pMatrix = eyeParam.pMatrix; + gl.viewport.apply(gl, __spread(eyeParam.viewport)); + gl.uniform1f(_this.shaderProgram.uEye, eyeIndex); + + _this._bindBuffers(); + + _this._draw(); + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + + vr.afterRender(); + }; + + _this._onFirstVRFrame = function (time, frame) { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; // If rendering is not ready, wait for next frame + + if (!vr.canRender(frame)) return; + var minusZDir = vec3.fromValues(0, 0, -1); + var eyeParam = vr.getEyeParams(gl, frame)[0]; // Extract only rotation + + var mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix); + var pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix); + var mvInv = mat3.invert(mat3.create(), mvMatrix); + var pInv = mat3.invert(mat3.create(), pMatrix); + var viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv); + vec3.transformMat3(viewDir, viewDir, mvInv); + var yawOffset = util.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1)); + + if (yawOffset === 0) { + // If the yawOffset is exactly 0, then device sensor is not ready + // So read it again until it has any value in it + return; + } + + vr.setYawOffset(yawOffset); + animator.setCallback(_this._renderStereo); + }; + + _this.sphericalConfig = sphericalConfig; + _this.fieldOfView = sphericalConfig.fieldOfView; + _this.width = width; + _this.height = height; + _this._lastQuaternion = null; + _this._lastYaw = null; + _this._lastPitch = null; + _this._lastFieldOfView = null; + _this.pMatrix = mat4.create(); + _this.mvMatrix = mat4.create(); // initialzie pMatrix + + mat4.perspective(_this.pMatrix, glMatrix.toRadian(_this.fieldOfView), width / height, 0.1, 100); + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + _this.canvas = _this._initCanvas(container, canvasClass, width, height); + + _this._setDefaultCanvasStyle(); + + _this._wrapper = null; // canvas wrapper + + _this._wrapperOrigStyle = null; + _this._renderingContextAttributes = renderingContextAttributes; + _this._image = null; + _this._imageConfig = null; + _this._imageIsReady = false; + _this._shouldForceDraw = false; + _this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still. + + _this._onContentLoad = _this._onContentLoad.bind(_this); + _this._onContentError = _this._onContentError.bind(_this); + _this._animator = new WebGLAnimator(); // VR/XR manager + + _this._vr = null; + + if (image) { + _this.setImage({ + image: image, + imageType: sphericalConfig.imageType, + isVideo: isVideo, + cubemapConfig: sphericalConfig.cubemapConfig + }); + } + + return _this; + } // FIXME: Please refactor me to have more loose connection to yawpitchcontrol + + + var __proto = PanoImageRenderer.prototype; + + __proto.setYawPitchControl = function (yawPitchControl) { + this._yawPitchControl = yawPitchControl; + }; + + __proto.getContent = function () { + return this._image; + }; + + __proto.setImage = function (_a) { + var image = _a.image, + imageType = _a.imageType, + _b = _a.isVideo, + isVideo = _b === void 0 ? false : _b, + cubemapConfig = _a.cubemapConfig; + this._imageIsReady = false; + this._isVideo = isVideo; + this._imageConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only */ + order: imageType === ImageType.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, cubemapConfig); + + this._setImageType(imageType); + + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._contentLoader = new ImReady().on("ready", this._onContentLoad).on("error", this._onContentError); + + if (isVideo) { + this._image = toVideoElement(image); + + this._contentLoader.check([this._image]); + + this._keepUpdate = true; + } else { + this._image = toImageElement(image); + + this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]); + + this._keepUpdate = false; + } + }; + + __proto.isImageLoaded = function () { + return !!this._image && this._imageIsReady && (!this._isVideo || this._image.readyState >= 2 + /* HAVE_CURRENT_DATA */ + ); + }; + + __proto.bindTexture = function () { + var _this = this; + + return new Promise$1(function (res, rej) { + var contentLoader = _this._contentLoader; + + if (!_this._image) { + return rej("Image is not defined"); + } + + if (!contentLoader) { + return rej("ImageLoader is not initialized"); + } + + if (contentLoader.isReady()) { + _this._bindTexture(); + + res(); + } else { + contentLoader.check(Array.isArray(_this._image) ? _this._image : [_this._image]); + contentLoader.once("ready", function (e) { + if (e.errorCount > 0) { + rej("Failed to load images."); + } else { + _this._bindTexture(); + + res(); + } + }); + } + }); + }; // 부모 엘리먼트에 canvas 를 붙임 + + + __proto.attachTo = function (parentElement) { + if (!this._hasExternalCanvas) { + this.detach(); + parentElement.appendChild(this.canvas); + } + + this._wrapper = parentElement; + }; + + __proto.forceContextLoss = function () { + if (this.hasRenderingContext()) { + var loseContextExtension = this.context.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + }; // 부모 엘리먼트에서 canvas 를 제거 + + + __proto.detach = function () { + if (!this._hasExternalCanvas && this.canvas.parentElement) { + this.canvas.parentElement.removeChild(this.canvas); + } + }; + + __proto.destroy = function () { + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._animator.stop(); + + this.detach(); + this.forceContextLoss(); + this.off(); + this.canvas.removeEventListener("webglcontextlost", this._onWebglcontextlost); + this.canvas.removeEventListener("webglcontextrestored", this._onWebglcontextrestored); + }; + + __proto.hasRenderingContext = function () { + var ctx = this.context; + + if (!ctx || ctx.isContextLost() || !ctx.getProgramParameter(this.shaderProgram, ctx.LINK_STATUS)) { + return false; + } + + return true; + }; + + __proto.updateFieldOfView = function (fieldOfView) { + this.fieldOfView = fieldOfView; + + this._updateViewport(); + }; + + __proto.updateViewportDimensions = function (width, height) { + var viewPortChanged = false; + this.width = width; + this.height = height; + var w = width * DEVICE_PIXEL_RATIO; + var h = height * DEVICE_PIXEL_RATIO; + + if (w !== this.canvas.width) { + this.canvas.width = w; + viewPortChanged = true; + } + + if (h !== this.canvas.height) { + this.canvas.height = h; + viewPortChanged = true; + } + + if (!viewPortChanged) { + return; + } + + this._updateViewport(); + + this._shouldForceDraw = true; + }; + + __proto.keepUpdate = function (doUpdate) { + if (doUpdate && this.isImageLoaded() === false) { + // Force to draw a frame after image is loaded on render() + this._shouldForceDraw = true; + } + + this._keepUpdate = doUpdate; + }; + + __proto.startRender = function () { + this._animator.setCallback(this._render.bind(this)); + + this._animator.start(); + }; + + __proto.stopRender = function () { + this._animator.stop(); + }; + + __proto.renderWithQuaternion = function (quaternion, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // updatefieldOfView only if fieldOfView is changed. + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion); + + this._draw(); + + this._lastQuaternion = quat.clone(quaternion); + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + + __proto.renderWithYawPitch = function (yaw, pitch, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastYaw !== null && this._lastYaw === yaw && this._lastPitch !== null && this._lastPitch === pitch && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출 + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + mat4.identity(this.mvMatrix); + mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch)); + mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw)); + + this._draw(); + + this._lastYaw = yaw; + this._lastPitch = pitch; + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + /** + * Returns projection renderer by each type + */ + + + __proto.getProjectionRenderer = function () { + return this._renderer; + }; + /** + * @return Promise + */ + + + __proto.enterVR = function (options) { + var vr = this._vr; + + if (!WEBXR_SUPPORTED && !navigator.getVRDisplays) { + return Promise$1.reject("VR is not available on this browser."); + } + + if (vr && vr.isPresenting()) { + return Promise$1.resolve("VR already enabled."); + } + + return this._requestPresent(options); + }; + + __proto._setImageType = function (imageType) { + var _this = this; + + if (!imageType || this._imageType === imageType) { + return; + } + + this._imageType = imageType; + this._isCubeMap = imageType === ImageType.CUBEMAP; + + if (this._renderer) { + this._renderer.off(); + } + + switch (imageType) { + case ImageType.CUBEMAP: + this._renderer = new CubeRenderer(); + break; + + case ImageType.CUBESTRIP: + this._renderer = new CubeStripRenderer(); + break; + + case ImageType.PANORAMA: + this._renderer = new CylinderRenderer(); + break; + + case ImageType.STEREOSCOPIC_EQUI: + this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat); + break; + + default: + this._renderer = new SphereRenderer(STEREO_FORMAT.NONE); + break; + } + + this._renderer.on(Renderer.EVENTS.ERROR, function (e) { + _this.trigger(new ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.RENDERER_ERROR, + message: e.message + })); + }); + + this._initWebGL(); + }; + + __proto._initCanvas = function (container, canvasClass, width, height) { + var canvasInContainer = container.querySelector("." + canvasClass); + + var canvas = canvasInContainer || this._createCanvas(canvasClass); + + this._hasExternalCanvas = !!canvasInContainer; + canvas.width = width; + canvas.height = height; + this._onWebglcontextlost = this._onWebglcontextlost.bind(this); + this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this); + canvas.addEventListener("webglcontextlost", this._onWebglcontextlost); + canvas.addEventListener("webglcontextrestored", this._onWebglcontextrestored); + return canvas; + }; + + __proto._createCanvas = function (className) { + var canvas = document.createElement("canvas"); + canvas.className = className; + return canvas; + }; + + __proto._setDefaultCanvasStyle = function () { + var canvas = this.canvas; + canvas.style.bottom = "0"; + canvas.style.left = "0"; + canvas.style.right = "0"; + canvas.style.top = "0"; + canvas.style.margin = "auto"; + canvas.style.maxHeight = "100%"; + canvas.style.maxWidth = "100%"; + canvas.style.outline = "none"; + canvas.style.position = "absolute"; + }; + + __proto._onContentError = function () { + this._imageIsReady = false; + this._image = null; + this.trigger(new ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.FAIL_IMAGE_LOAD, + message: "failed to load image" + })); + return false; + }; + + __proto._triggerContentLoad = function () { + this.trigger(new ComponentEvent(EVENTS$1.IMAGE_LOADED, { + content: this._image, + isVideo: this._isVideo, + projectionType: this._imageType + })); + }; + + __proto._onContentLoad = function (e) { + if (e.errorCount > 0) return; + this._imageIsReady = true; + + this._triggerContentLoad(); + }; + + __proto._initShaderProgram = function () { + var gl = this.context; + + if (this.shaderProgram) { + gl.deleteProgram(this.shaderProgram); + this.shaderProgram = null; + } + + var renderer = this._renderer; + var vsSource = renderer.getVertexShaderSource(); + var fsSource = renderer.getFragmentShaderSource(); + var vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource); + var fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource); + var shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader); + + if (!shaderProgram) { + throw new Error("Failed to initialize shaders: " + WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())); + } + + gl.useProgram(shaderProgram); + shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); + shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); + shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); + shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); + shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); + shaderProgram.uEye = gl.getUniformLocation(shaderProgram, "uEye"); + gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); + gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); // clear buffer + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); // Use TEXTURE0 + + gl.uniform1i(shaderProgram.samplerUniform, 0); + this.shaderProgram = shaderProgram; + }; + + __proto._onWebglcontextlost = function (e) { + e.preventDefault(); + this.trigger(new ComponentEvent(EVENTS$1.RENDERING_CONTEXT_LOST)); + }; + + __proto._onWebglcontextrestored = function () { + this._initWebGL(); + + this.trigger(new ComponentEvent(EVENTS$1.RENDERING_CONTEXT_RESTORE)); + }; + + __proto._updateViewport = function () { + mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), this.canvas.width / this.canvas.height, 0.1, 100); + this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight); + }; + + __proto._initWebGL = function () { + var gl; // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed. + + try { + this._initRenderingContext(); + + gl = this.context; + this.updateViewportDimensions(this.width, this.height); + + this._initShaderProgram(); + } catch (e) { + this.trigger(new ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.NO_WEBGL, + message: "no webgl support" + })); + this.destroy(); + console.error(e); // eslint-disable-line no-console + + return; + } // 캔버스를 투명으로 채운다. + + + gl.clearColor(0, 0, 0, 0); + var textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D; + + if (this.texture) { + gl.deleteTexture(this.texture); + } + + this.texture = WebGLUtils.createTexture(gl, textureTarget); + + if (this._imageType === ImageType.CUBESTRIP) { + // TODO: Apply following options on other projection type. + gl.enable(gl.CULL_FACE); // gl.enable(gl.DEPTH_TEST); + } + }; + + __proto._initRenderingContext = function () { + if (this.hasRenderingContext()) { + return; + } + + if (!window.WebGLRenderingContext) { + throw new Error("WebGLRenderingContext not available."); + } + + this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes); + + if (!this.context) { + throw new Error("Failed to acquire 3D rendering context"); + } + }; + + __proto._initBuffers = function () { + var image = this._image; + + var vertexPositionData = this._renderer.getVertexPositionData(); + + var indexData = this._renderer.getIndexData(); + + var textureCoordData = this._renderer.getTextureCoordData({ + image: image, + imageConfig: this._imageConfig + }); + + var gl = this.context; + this.vertexBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3, this.shaderProgram.vertexPositionAttribute); + this.indexBuffer = WebGLUtils.initBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1); + this.textureCoordBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2, this.shaderProgram.textureCoordAttribute); + + this._bindBuffers(); + }; + + __proto._bindTexture = function () { + // Detect if it is EAC Format while CUBESTRIP mode. + // We assume it is EAC if image is not 3/2 ratio. + if (this._imageType === ImageType.CUBESTRIP) { + var _a = this._renderer.getDimension(this._image), + width = _a.width, + height = _a.height; + + var isEAC = width && height && width / height !== 1.5 ? 1 : 0; + this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram, "uIsEAC"), isEAC); + } else if (this._imageType === ImageType.PANORAMA) { + var _b = this._renderer.getDimension(this._image), + width = _b.width, + height = _b.height; + + var imageAspectRatio = width && height && width / height; + + this._renderer.updateShaderData({ + imageAspectRatio: imageAspectRatio + }); + } // initialize shader buffers after image is loaded.(by updateShaderData) + // because buffer may be differ by image size.(eg. CylinderRenderer) + + + this._initBuffers(); + + this._renderer.bindTexture(this.context, this.texture, this._image, this._imageConfig); + + this._shouldForceDraw = true; + this.trigger(new ComponentEvent(EVENTS$1.BIND_TEXTURE)); + }; + + __proto._updateTexture = function () { + this._renderer.updateTexture(this.context, this._image, this._imageConfig); + }; + + __proto._render = function () { + var yawPitchControl = this._yawPitchControl; + var fov = yawPitchControl.getFov(); + + if (yawPitchControl.shouldRenderWithQuaternion()) { + var quaternion = yawPitchControl.getQuaternion(); + this.renderWithQuaternion(quaternion, fov); + } else { + var yawPitch = yawPitchControl.getYawPitch(); + this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov); + } + }; + + __proto._bindBuffers = function () { + var gl = this.context; + var program = this.shaderProgram; + var vertexBuffer = this.vertexBuffer; + var textureCoordBuffer = this.textureCoordBuffer; + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.enableVertexAttribArray(program.vertexPositionAttribute); + gl.vertexAttribPointer(program.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); + gl.enableVertexAttribArray(program.textureCoordAttribute); + gl.vertexAttribPointer(program.textureCoordAttribute, textureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); + }; + + __proto._draw = function () { + if (this._isVideo && this._keepUpdate) { + this._updateTexture(); + } + + this._renderer.render({ + gl: this.context, + shaderProgram: this.shaderProgram, + indexBuffer: this.indexBuffer, + mvMatrix: this.mvMatrix, + pMatrix: this.pMatrix + }); + }; + + __proto._requestPresent = function (options) { + var _this = this; + + var gl = this.context; + var canvas = this.canvas; + var animator = this._animator; + this._vr = WEBXR_SUPPORTED ? new XRManager(options) : new VRManager(); + var vr = this._vr; + animator.stop(); + return new Promise$1(function (resolve, reject) { + vr.requestPresent(canvas, gl).then(function () { + vr.addEndCallback(_this.exitVR); + animator.setContext(vr.context); + animator.setCallback(_this._onFirstVRFrame); + + if (IS_IOS) { + _this._setWrapperFullscreen(); + } + + _this._shouldForceDraw = true; + animator.start(); + resolve("success"); + }).catch(function (e) { + vr.destroy(); + _this._vr = null; + animator.start(); + reject(e); + }); + }); + }; + + __proto._setWrapperFullscreen = function () { + var wrapper = this._wrapper; + if (!wrapper) return; + this._wrapperOrigStyle = wrapper.getAttribute("style"); + var wrapperStyle = wrapper.style; + wrapperStyle.width = "100vw"; + wrapperStyle.height = "100vh"; + wrapperStyle.position = "fixed"; + wrapperStyle.left = "0"; + wrapperStyle.top = "0"; + wrapperStyle.zIndex = "9999"; + }; + + __proto._restoreStyle = function () { + var wrapper = this._wrapper; + var canvas = this.canvas; + if (!wrapper) return; + + if (this._wrapperOrigStyle) { + wrapper.setAttribute("style", this._wrapperOrigStyle); + } else { + wrapper.removeAttribute("style"); + } + + this._wrapperOrigStyle = null; // Restore canvas style + + canvas.removeAttribute("style"); + + this._setDefaultCanvasStyle(); + }; + + PanoImageRenderer.EVENTS = EVENTS$1; + PanoImageRenderer.ERROR_TYPE = ERROR_TYPE$1; + return PanoImageRenderer; +}(Component); + +/** + * @memberof eg.view360 + * @extends eg.Component + * PanoViewer + */ + +var PanoViewer = +/*#__PURE__*/ +function (_super) { + __extends(PanoViewer, _super); + /** + * @classdesc 360 media viewer + * @ko 360 미디어 뷰어 + * + * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트 + * @param options + * + * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
+ * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다. + * @param {Object} [options.cubemapConfig.order = "RLUDBF"(ProjectionType === CUBEMAP) | "RLUDFB" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서 + * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다. + * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다. + * @param {String} [options.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
+ * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위) + * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위) + * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위) + * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위) + * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위) + * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다 + * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다. + * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키 + * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE}
+ * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위 + * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위 + * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위 + * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
+ * @param {String} [options.canvasClass="view360-canvas"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * + * @example + * ``` + * // PanoViewer Creation + * // create PanoViewer with option + * var PanoViewer = eg.view360.PanoViewer; + * // Area where the image will be displayed(HTMLElement) + * var container = document.getElementById("myPanoViewer"); + * + * var panoViewer = new PanoViewer(container, { + * // If projectionType is not specified, the default is "equirectangular". + * // Specifies an image of the "equirectangular" type. + * image: "/path/to/image/image.jpg" + * }); + * ``` + * + * @example + * ``` + * // Cubemap Config Setting Example + * // For support Youtube EAC projection, You should set cubemapConfig as follows. + * cubemapConfig: { + * order: "LFRDBU", + * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}] + * } + * ``` + */ + + + function PanoViewer(container, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; // Raises the error event if webgl is not supported. + + + if (!WebGLUtils.isWebGLAvailable()) { + setTimeout(function () { + _this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.NO_WEBGL, + message: "no webgl support" + })); + }, 0); + return _this; + } + + if (!WebGLUtils.isStableWebGL()) { + setTimeout(function () { + _this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_DEVICE, + message: "blacklisted browser" + })); + }, 0); + return _this; + } + + if (!!options.image && !!options.video) { + setTimeout(function () { + _this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_RESOURCE, + message: "Specifying multi resouces(both image and video) is not valid." + })); + }, 0); + return _this; + } // Check XR support at not when imported, but when created. + // This is intended to make polyfills easier to use. + + + checkXRSupport(); + _this._container = container; + _this._image = options.image || options.video; + _this._isVideo = !!options.video; + _this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + _this._cubemapConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/ + order: _this._projectionType === PROJECTION_TYPE.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, options.cubemapConfig); + _this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; // If the width and height are not provided, will use the size of the container. + + _this._width = options.width || parseInt(window.getComputedStyle(container).width, 10); + _this._height = options.height || parseInt(window.getComputedStyle(container).height, 10); + /** + * Cache the direction for the performance in renderLoop + * + * This value should be updated by "change" event of YawPitchControl. + */ + + _this._yaw = options.yaw || 0; + _this._pitch = options.pitch || 0; + _this._fov = options.fov || 65; + _this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH; + _this._quaternion = null; + _this._aspectRatio = _this._height !== 0 ? _this._width / _this._height : 1; + _this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS; + var fovRange = options.fovRange || [30, 110]; + var touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ? options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL; + + var yawPitchConfig = __assign(__assign({}, options), { + element: container, + yaw: _this._yaw, + pitch: _this._pitch, + fov: _this._fov, + gyroMode: _this._gyroMode, + fovRange: fovRange, + aspectRatio: _this._aspectRatio, + touchDirection: touchDirection + }); + + _this._isReady = false; + + _this._initYawPitchControl(yawPitchConfig); + + _this._initRenderer(_this._yaw, _this._pitch, _this._fov, _this._projectionType, _this._cubemapConfig); + + return _this; + } + /** + * Check whether the current environment can execute PanoViewer + * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다. + * @return PanoViewer executable PanoViewer 실행가능 여부 + */ + + + var __proto = PanoViewer.prototype; + + PanoViewer.isSupported = function () { + return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL(); + }; + /** + * Check whether the current environment supports the WebGL + * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다. + * @return WebGL support WebGL 지원여부 + */ + + + PanoViewer.isWebGLAvailable = function () { + return WebGLUtils.isWebGLAvailable(); + }; + /** + * Check whether the current environment supports the gyro sensor. + * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다. + * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수 + */ + + + PanoViewer.isGyroSensorAvailable = function (callback) { + if (!DeviceMotionEvent && callback) { + callback(false); + return; + } + + var onDeviceMotionChange; + + var checkGyro = function () { + return new Promise$1(function (res) { + onDeviceMotionChange = function (deviceMotion) { + var isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null); + res(isGyroSensorAvailable); + }; + + window.addEventListener("devicemotion", onDeviceMotionChange); + }); + }; + + var timeout = function () { + return new Promise$1(function (res) { + setTimeout(function () { + return res(false); + }, 1000); + }); + }; + + Promise$1.race([checkGyro(), timeout()]).then(function (isGyroSensorAvailable) { + window.removeEventListener("devicemotion", onDeviceMotionChange); + + if (callback) { + callback(isGyroSensorAvailable); + } + + PanoViewer.isGyroSensorAvailable = function (fb) { + if (fb) { + fb(isGyroSensorAvailable); + } + + return isGyroSensorAvailable; + }; + }); + }; + + PanoViewer._isValidTouchDirection = function (direction) { + return direction === PanoViewer.TOUCH_DIRECTION.NONE || direction === PanoViewer.TOUCH_DIRECTION.YAW || direction === PanoViewer.TOUCH_DIRECTION.PITCH || direction === PanoViewer.TOUCH_DIRECTION.ALL; + }; + /** + * Get the video element that the viewer is currently playing. You can use this for playback. + * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다. + * @return HTMLVideoElementHTMLVideoElement + * @example + * ``` + * var videoTag = panoViewer.getVideo(); + * videoTag.play(); // play the video! + * ``` + */ + + + __proto.getVideo = function () { + if (!this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the video information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정) + * @param {object} param + * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}("equirectangular")] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setVideo("/path/to/video/video.mp4", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR + * }); + * ``` + */ + + + __proto.setVideo = function (video, param) { + if (param === void 0) { + param = {}; + } + + if (video) { + this.setImage(video, { + projectionType: param.projectionType, + isVideo: true, + cubemapConfig: param.cubemapConfig, + stereoFormat: param.stereoFormat + }); + } + + return this; + }; + /** + * Get the image information that the viewer is currently using. + * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다. + * @return Image Object이미지 객체 + * @example + * var imageObj = panoViewer.getImage(); + */ + + + __proto.getImage = function () { + if (this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the image information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.) + * @param {object} param Additional information이미지 추가 정보 + * @param {string} [param.projectionType="equirectangular"] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부 + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setImage("/path/to/image/image.png", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP + * }); + * ``` + */ + + + __proto.setImage = function (image, param) { + if (param === void 0) { + param = {}; + } + + var cubemapConfig = __assign({ + order: "RLUDBF", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, param.cubemapConfig); + + var stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; + var isVideo = !!param.isVideo; + + if (this._image && this._isVideo !== isVideo) { + /* eslint-disable no-console */ + console.warn("PanoViewer is not currently supporting content type changes. (Image <--> Video)"); + /* eslint-enable no-console */ + + return this; + } + + if (image) { + this._deactivate(); + + this._image = image; + this._isVideo = isVideo; + this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + this._cubemapConfig = cubemapConfig; + this._stereoFormat = stereoFormat; + + this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig); + } + + return this; + }; + /** + * Set whether the renderer always updates the texture and renders. + * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다. + * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.keepUpdate = function (doUpdate) { + this._photoSphereRenderer.keepUpdate(doUpdate); + + return this; + }; + /** + * Get the current projection type (equirectangular/cube) + * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다. + * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE} + */ + + + __proto.getProjectionType = function () { + return this._projectionType; + }; + /** + * Activate the device's motion sensor, and return the Promise whether the sensor is enabled + * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element. + * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다. + * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다. + */ + + + __proto.enableSensor = function () { + return new Promise$1(function (resolve, reject) { + if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === "function") { + DeviceMotionEvent.requestPermission().then(function (permissionState) { + if (permissionState === "granted") { + resolve(); + } else { + reject(new Error("permission denied")); + } + }).catch(function (e) { + // This can happen when this method wasn't triggered by user interaction + reject(e); + }); + } else { + resolve(); + } + }); + }; + /** + * Disable the device's motion sensor. + * @ko 디바이스의 모션 센서를 비활성화합니다. + * @deprecated + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.disableSensor = function () { + return this; + }; + /** + * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred). + * This method must be used in the context of user interaction, like onclick callback on the button element. + * It can be rejected when an enabling device sensor fails or image/video is still loading("ready" event not triggered). + * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다) + * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우("ready"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다. + * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요. + * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error) + */ + + + __proto.enterVR = function (options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + if (!this._isReady) { + return Promise$1.reject(new Error("PanoViewer is not ready to show image.")); + } + + return new Promise$1(function (resolve, reject) { + _this.enableSensor().then(function () { + return _this._photoSphereRenderer.enterVR(options); + }).then(function (res) { + return resolve(res); + }).catch(function (e) { + return reject(e); + }); + }); + }; + /** + * Exit VR stereo rendering mode. + * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.exitVR = function () { + this._photoSphereRenderer.exitVR(); + + return this; + }; + /** + * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}. + * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다. + * @param useZoom + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseZoom = function (useZoom) { + if (typeof useZoom === "boolean") { + this._yawPitchControl.option("useZoom", useZoom); + } + + return this; + }; + /** + * When true, enables the keyboard move key control: awsd, arrow keys + * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키) + * @param useKeyboard + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseKeyboard = function (useKeyboard) { + this._yawPitchControl.option("useKeyboard", useKeyboard); + + return this; + }; + /** + * Enables control through device motion. ("none", "yawPitch", "VR") + * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR") + * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE} + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setGyroMode("yawPitch"); + * //equivalent + * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH); + * ``` + */ + + + __proto.setGyroMode = function (gyroMode) { + this._yawPitchControl.option("gyroMode", gyroMode); + + return this; + }; + /** + * Set the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 설정합니다. + * @param range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setFovRange([50, 90]); + */ + + + __proto.setFovRange = function (range) { + this._yawPitchControl.option("fovRange", range); + + return this; + }; + /** + * Get the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 반환합니다. + * @return FOV range + * @example + * var range = panoViewer.getFovRange(); // [50, 90] + */ + + + __proto.getFovRange = function () { + return this._yawPitchControl.option("fovRange"); + }; + /** + * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size. + * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다. + * @param {object} [size] + * @param {number} [size.width=width of the container] + * @param {number} [size.height=height of the container] + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.updateViewportDimensions = function (size) { + if (size === void 0) { + size = {}; + } + + if (!this._isReady) { + return this; + } + + var containerSize; + + if (size.width === undefined || size.height === undefined) { + containerSize = window.getComputedStyle(this._container); + } + + var width = size.width || parseInt(containerSize.width, 10); + var height = size.height || parseInt(containerSize.height, 10); // Skip if viewport is not changed. + + if (width === this._width && height === this._height) { + return this; + } + + this._width = width; + this._height = height; + this._aspectRatio = width / height; + + this._photoSphereRenderer.updateViewportDimensions(width, height); + + this._yawPitchControl.option("aspectRatio", this._aspectRatio); + + this._yawPitchControl.updatePanScale({ + height: height + }); + + this.lookAt({}, 0); + return this; + }; + /** + * Get the current field of view(FOV) + * @ko 현재 field of view(FOV) 값을 반환합니다. + */ + + + __proto.getFov = function () { + return this._fov; + }; + /** + * Get current yaw value + * @ko 현재 yaw 값을 반환합니다. + */ + + + __proto.getYaw = function () { + return this._yaw; + }; + /** + * Get current pitch value + * @ko 현재 pitch 값을 반환합니다. + */ + + + __proto.getPitch = function () { + return this._pitch; + }; + /** + * Get the range of controllable Yaw values + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + */ + + + __proto.getYawRange = function () { + return this._yawPitchControl.option("yawRange"); + }; + /** + * Get the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다. + */ + + + __proto.getPitchRange = function () { + return this._yawPitchControl.option("pitchRange"); + }; + /** + * Set the range of controllable yaw + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setYawRange([-90, 90]); + */ + + + __proto.setYawRange = function (yawRange) { + this._yawPitchControl.option("yawRange", yawRange); + + return this; + }; + /** + * Set the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 설정합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setPitchRange([-40, 40]); + */ + + + __proto.setPitchRange = function (pitchRange) { + this._yawPitchControl.option("pitchRange", pitchRange); + + return this; + }; + /** + * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed. + * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다. + * @param showPolePoint + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setShowPolePoint = function (showPolePoint) { + this._yawPitchControl.option("showPolePoint", showPolePoint); + + return this; + }; + /** + * Set a new view by setting camera configuration. Any parameters not specified remain the same. + * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다. + * @param {object} orientation + * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위) + * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위) + * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위) + * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초) + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * // Change the yaw angle (absolute angle) to 30 degrees for one second. + * panoViewer.lookAt({yaw: 30}, 1000); + * ``` + */ + + + __proto.lookAt = function (orientation, duration) { + if (duration === void 0) { + duration = 0; + } + + if (!this._isReady) { + return this; + } + + var yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw; + var pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch; + + var pitchRange = this._yawPitchControl.option("pitchRange"); + + var verticalAngleOfImage = pitchRange[1] - pitchRange[0]; + var fov = orientation.fov !== undefined ? orientation.fov : this._fov; + + if (verticalAngleOfImage < fov) { + fov = verticalAngleOfImage; + } + + this._yawPitchControl.lookAt({ + yaw: yaw, + pitch: pitch, + fov: fov + }, duration); + + if (duration === 0) { + this._photoSphereRenderer.renderWithYawPitch(yaw, pitch, fov); + } + + return this; + }; + /** + * Set touch direction by which user can control. + * @ko 사용자가 조작가능한 터치 방향을 지정합니다. + * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @return PanoViewer instance + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Limit the touch direction to the yaw direction only. + * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW); + * ``` + */ + + + __proto.setTouchDirection = function (direction) { + if (PanoViewer._isValidTouchDirection(direction)) { + this._yawPitchControl.option("touchDirection", direction); + } + + return this; + }; + /** + * Returns touch direction by which user can control + * @ko 사용자가 조작가능한 터치 방향을 반환한다. + * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Returns the current touch direction. + * var dir = panoViewer.getTouchDirection(); + * ``` + */ + + + __proto.getTouchDirection = function () { + return this._yawPitchControl.option("touchDirection"); + }; + /** + * Destroy viewer. Remove all registered event listeners and remove viewer canvas. + * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.destroy = function () { + this._deactivate(); + + if (this._yawPitchControl) { + this._yawPitchControl.destroy(); + + this._yawPitchControl = null; + } + + return this; + }; // TODO: Remove parameters as they're just using private values + + + __proto._initRenderer = function (yaw, pitch, fov, projectionType, cubemapConfig) { + var _this = this; + + this._photoSphereRenderer = new PanoImageRenderer(this._image, this._width, this._height, this._isVideo, this._container, this._canvasClass, { + initialYaw: yaw, + initialPitch: pitch, + fieldOfView: fov, + imageType: projectionType, + cubemapConfig: cubemapConfig, + stereoFormat: this._stereoFormat + }); + + this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl); + + this._bindRendererHandler(); + + this._photoSphereRenderer.bindTexture().then(function () { + return _this._activate(); + }).catch(function () { + _this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.FAIL_BIND_TEXTURE, + message: "failed to bind texture" + })); + }); + }; + /** + * @private + * update values of YawPitchControl if needed. + * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image. + * + * This function should be called after isReady status is true. + */ + + + __proto._updateYawPitchIfNeeded = function () { + if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) { + // update fov by aspect ratio + var image = this._photoSphereRenderer.getContent(); + + var imageAspectRatio = image.naturalWidth / image.naturalHeight; + var yawSize = void 0; + var maxFov = void 0; // If height is larger than width, then we assume it's rotated by 90 degree. + + if (imageAspectRatio < 1) { + // So inverse the aspect ratio. + imageAspectRatio = 1 / imageAspectRatio; + } + + if (imageAspectRatio < 6) { + yawSize = util.toDegree(imageAspectRatio); // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5 + + maxFov = util.toDegree(Math.atan(0.5)) * 2; + } else { + yawSize = 360; + maxFov = 360 / imageAspectRatio; // Make it 5 fixed as axes does. + } // console.log("_updateYawPitchIfNeeded", maxFov, "aspectRatio", image.naturalWidth, image.naturalHeight, "yawSize", yawSize); + + + var minFov = this._yawPitchControl.option("fovRange")[0]; // this option should be called after fov is set. + + + this._yawPitchControl.option({ + "fov": maxFov, + "yawRange": [-yawSize / 2, yawSize / 2], + "pitchRange": [-maxFov / 2, maxFov / 2], + "fovRange": [minFov, maxFov] + }); + + this.lookAt({ + fov: maxFov + }); + } + }; + + __proto._bindRendererHandler = function () { + var _this = this; + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.ERROR, function (e) { + _this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.ERROR, e)); + }); + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, function () { + _this._deactivate(); + + _this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.RENDERING_CONTEXT_LOST, + message: "webgl rendering context lost" + })); + }); + }; + + __proto._initYawPitchControl = function (yawPitchConfig) { + var _this = this; + + this._yawPitchControl = new YawPitchControl(yawPitchConfig); + + this._yawPitchControl.on(PANOVIEWER_EVENTS.ANIMATION_END, function (e) { + _this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.ANIMATION_END, e)); + }); + + this._yawPitchControl.on("change", function (e) { + _this._yaw = e.yaw; + _this._pitch = e.pitch; + _this._fov = e.fov; + _this._quaternion = e.quaternion; + + _this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.VIEW_CHANGE, { + yaw: e.yaw, + pitch: e.pitch, + fov: e.fov, + quaternion: e.quaternion, + isTrusted: e.isTrusted + })); + }); + }; + + __proto._activate = function () { + this._photoSphereRenderer.attachTo(this._container); + + this._yawPitchControl.enable(); + + this.updateViewportDimensions(); + this._isReady = true; // update yawPitchControl after isReady status is true. + + this._updateYawPitchIfNeeded(); + + this.trigger(new ComponentEvent(PANOVIEWER_EVENTS.READY)); + + this._photoSphereRenderer.startRender(); + }; + /** + * Destroy webgl context and block user interaction and stop rendering + */ + + + __proto._deactivate = function () { + // Turn off the video if it has one + var video = this.getVideo(); + + if (video) { + video.pause(); + } + + if (this._isReady) { + this._photoSphereRenderer.stopRender(); + + this._yawPitchControl.disable(); + + this._isReady = false; + } + + if (this._photoSphereRenderer) { + this._photoSphereRenderer.destroy(); + + this._photoSphereRenderer = null; + } + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @type {String} + * @example + * eg.view360.PanoViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.PanoViewer + */ + + + PanoViewer.VERSION = VERSION; + PanoViewer.ERROR_TYPE = ERROR_TYPE; + PanoViewer.EVENTS = PANOVIEWER_EVENTS; + PanoViewer.PROJECTION_TYPE = PROJECTION_TYPE; + PanoViewer.GYRO_MODE = GYRO_MODE; // This should be deprecated! + // eslint-disable-next-line @typescript-eslint/naming-convention + + PanoViewer.ProjectionType = PROJECTION_TYPE; + PanoViewer.STEREO_FORMAT = STEREO_FORMAT; + /** + * Constant value for touch directions + * @ko 터치 방향에 대한 상수 값. + * @namespace + * @name TOUCH_DIRECTION + */ + + PanoViewer.TOUCH_DIRECTION = { + /** + * Constant value for none direction. + * @ko none 방향에 대한 상수 값. + * @name NONE + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 1 + */ + NONE: YawPitchControl.TOUCH_DIRECTION_NONE, + + /** + * Constant value for horizontal(yaw) direction. + * @ko horizontal(yaw) 방향에 대한 상수 값. + * @name YAW + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 6 + */ + YAW: YawPitchControl.TOUCH_DIRECTION_YAW, + + /** + * Constant value for vertical direction. + * @ko vertical(pitch) 방향에 대한 상수 값. + * @name PITCH + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 24 + */ + PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH, + + /** + * Constant value for all direction. + * @ko all 방향에 대한 상수 값. + * @name ALL + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 30 + */ + ALL: YawPitchControl.TOUCH_DIRECTION_ALL + }; + return PanoViewer; +}(Component); + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +var SPINVIEWER_OPTIONS = { + imageUrl: true, + rowCount: true, + colCount: true, + width: true, + height: true, + autoHeight: true, + colRow: true, + scale: true, + frameIndex: true, + wrapperClass: true, + imageClass: true +}; +var SPINVIEWER_EVENTS = { + LOAD: "load", + IMAGE_ERROR: "imageError", + CHANGE: "change", + ANIMATION_END: "animationEnd" +}; +var DEFAULT_WRAPPER_CLASS = "view360-wrapper"; +var DEFAULT_IMAGE_CLASS = "view360-image"; + +/** + * @memberof eg.view360 + * @extends eg.Component + * SpriteImage + */ + +var SpriteImage = +/*#__PURE__*/ +function (_super) { + __extends(SpriteImage, _super); + /** + * @class eg.view360.SpriteImage + * @classdesc A module that displays a single or continuous image of any one of the "sprite images". SpinViewer internally uses SpriteImage to show each frame of the sprite image. + * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다. + * @extends eg.Component + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the "Sprite image". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
+ * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * + * // Initialize SpriteImage + * + * var el = document.getElementById("image-div"); + * var sprites = new eg.view360.SpriteImage(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 + * }); + */ + + + function SpriteImage(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + var opt = options || {}; + _this._el = element; + _this._rowCount = opt.rowCount || 1; + _this._colCount = opt.colCount || 1; + _this._totalCount = _this._rowCount * _this._colCount; // total frames + + _this._width = opt.width || "auto"; + _this._height = opt.height || "auto"; + _this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten. + + _this._colRow = [0, 0]; + + if (opt.colRow) { + _this._colRow = opt.colRow; + } else if (opt.frameIndex) { + _this.setFrameIndex(opt.frameIndex); + } + + _this._el.style.width = SpriteImage._getSizeString(_this._width); + _this._el.style.height = SpriteImage._getSizeString(_this._height); + var wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS; + var imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS; + + if (!opt.imageUrl) { + setTimeout(function () { + _this.trigger(new ComponentEvent("imageError", { + imageUrl: opt.imageUrl + })); + }, 0); + return _this; + } + + var imageInContainer = element.querySelector("." + imageClass); + var wrapperInContainer = element.querySelector("." + wrapperClass); + + if (wrapperInContainer && imageInContainer) { + // Set it to invisible to prevent wrapper being resized + imageInContainer.style.display = "none"; + } + + _this._image = imageInContainer || new Image(); + /** + * Event + */ + + var image = _this._image; + + image.onload = function () { + if (wrapperInContainer && imageInContainer) { + imageInContainer.style.display = ""; + } + + _this._bg = SpriteImage._createBgDiv(wrapperInContainer, image, _this._rowCount, _this._colCount, _this._autoHeight); + + _this._el.appendChild(_this._bg); + + _this.setColRow(_this._colRow[0], _this._colRow[1]); + + _this.trigger(new ComponentEvent("load", { + target: _this._el, + bgElement: _this._bg + })); + + if (_this._autoPlayReservedInfo) { + _this.play(_this._autoPlayReservedInfo); + + _this._autoPlayReservedInfo = null; + } + }; + + image.onerror = function () { + _this.trigger(new ComponentEvent("imageError", { + imageUrl: opt.imageUrl + })); + }; + + image.src = opt.imageUrl; + return _this; + } + + var __proto = SpriteImage.prototype; + + SpriteImage._createBgDiv = function (wrapperInContainer, img, rowCount, colCount, autoHeight) { + var el = wrapperInContainer || document.createElement("div"); + el.style.position = "relative"; + el.style.overflow = "hidden"; + img.style.position = "absolute"; + img.style.width = colCount * 100 + "%"; + img.style.height = rowCount * 100 + "%"; + /** Prevent image from being dragged on IE10, IE11, Safari especially */ + + img.ondragstart = function () { + return false; + }; // img.style.pointerEvents = "none"; + // Use hardware accelerator if available + + + if (SUPPORT_WILLCHANGE) { + img.style.willChange = "transform"; + } + + el.appendChild(img); + var unitWidth = img.naturalWidth / colCount; + var unitHeight = img.naturalHeight / rowCount; + + if (autoHeight) { + var r = unitHeight / unitWidth; + el.style.paddingBottom = r * 100 + "%"; + } else { + el.style.height = "100%"; + } + + return el; + }; + + SpriteImage._getSizeString = function (size) { + if (typeof size === "number") { + return size + "px"; + } + + return size; + }; + /** + * Specifies the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정 + * @method eg.view360.SpriteImage#setFrameIndex + * @param {Number} frameIndex frame index of a frame프레임의 인덱스 + * + * @example + * + * sprites.setFrameIndex(0, 1);// col = 0, row = 1 + */ + + + __proto.setFrameIndex = function (index) { + var colRow = this.toColRow(index); + this.setColRow(colRow[0], colRow[1]); + }; + /** + * Returns the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환 + * @method eg.view360.SpriteImage#getFrameIndex + * @return {Number} frame index frame 인덱스 + * + * @example + * + * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1 + * + */ + + + __proto.getFrameIndex = function () { + return this._colRow[1] * this._colCount + this._colRow[0]; + }; + /** + * Specifies the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정 + * @method eg.view360.SpriteImage#setColRow + * @param {Number} col Column number of a frame프레임의 행값 + * @param {Number} row Row number of a frame프레임의 열값 + * + * @example + * + * sprites.setlColRow(1, 2); // col = 1, row = 2 + */ + + + __proto.setColRow = function (col, row) { + if (row > this._rowCount - 1 || col > this._colCount - 1) { + return; + } + + if (this._image && TRANSFORM) { + // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser? + this._image.style[TRANSFORM] = "translate(" + -(col / this._colCount * 100) + "%, " + -(row / this._rowCount * 100) + "%)"; + } + + this._colRow = [col, row]; + }; + /** + * Returns the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환 + * @method eg.view360.SpriteImage#gelColRow + * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열 + * + * @example + * + * var colRow = sprites.getlColRow(); + * // colRow = [1, 2] - index of col is 1, index of row is 2 + * + */ + + + __proto.getColRow = function () { + return this._colRow; + }; + /** + * Stop playing + * @ko play 되고 있던 프레임 재생을 중지합니다. + * @method eg.view360.SpriteImage#stop + * + * @example + * + * viewer.stop(); + * + */ + + + __proto.stop = function () { + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + }; + /** + * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'. + * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다. + * @method eg.view360.SpriteImage#play + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위 + * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복 + * + * @example + * + * viewer.play({angle: 16, playCount: 1}); + * + */ + + + __proto.play = function (_a) { + var _this = this; + + var _b = _a === void 0 ? { + interval: 1000 / this._totalCount, + playCount: 0 + } : _a, + interval = _b.interval, + playCount = _b.playCount; + + if (!this._bg) { + this._autoPlayReservedInfo = { + interval: interval, + playCount: playCount + }; + return; + } + + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + + var frameIndex = this.getFrameIndex(); + var count = 0; + var frameCount = 0; // for checking 1 cycle + + this._autoPlayTimer = window.setInterval(function () { + frameIndex %= _this._totalCount; + + var colRow = _this.toColRow(frameIndex); + + _this.setColRow(colRow[0], colRow[1]); + + frameIndex++; // Done 1 Cycle? + + if (++frameCount === _this._totalCount) { + frameCount = 0; + count++; + } + + if (playCount > 0 && count === playCount) { + clearInterval(_this._autoPlayTimer); + } + }, interval); + }; + + __proto.toColRow = function (frameIndex) { + var colCount = this._colCount; + var rowCount = this._rowCount; + + if (frameIndex < 0) { + return [0, 0]; + } else if (frameIndex >= this._totalCount) { + return [colCount - 1, rowCount - 1]; + } + + var col = frameIndex % colCount; + var row = Math.floor(frameIndex / colCount); // console.log(frameIndex, col, row); + + return [col, row]; + }; + + SpriteImage.VERSION = VERSION; + return SpriteImage; +}(Component); + +var DEFAULT_PAN_SCALE = 0.21; +/** + * @memberof eg.view360 + * @extends eg.Component + * SpinViewer + */ + +var SpinViewer = +/*#__PURE__*/ +function (_super) { + __extends(SpinViewer, _super); + /** + * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object. + * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다. + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값 + * @param {String} [options.wrapperClass="view360-wrapper"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @param {String} [options.imageClass="view360-image"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * ``` + * // Initialize SpinViewer + * var el = document.getElementById("product-360"); + * var viewer = new eg.view360.SpinViewer(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 //required + * }); + * ``` + */ + + + function SpinViewer(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this._el = element; + + var opt = __assign({}, options); + + var colCount = opt.colCount || 1; + var rowCount = opt.rowCount || 1; + _this._scale = opt.scale || 1; + _this._panScale = _this._scale * DEFAULT_PAN_SCALE; + _this._frameCount = colCount * rowCount; // Init SpriteImage + + _this._sprites = new SpriteImage(element, opt).on({ + "load": function (evt) { + _this.trigger(new ComponentEvent("load", evt)); + }, + "imageError": function (evt) { + _this.trigger(new ComponentEvent("imageError", { + imageUrl: evt.imageUrl + })); + } + }); // Init Axes + + _this._panInput = new PanInput(_this._el, { + scale: [_this._panScale, _this._panScale] + }); + _this._axes = new Axes({ + angle: { + range: [0, 359], + circular: true + } + }).on({ + "change": function (evt) { + var curr = Math.floor(evt.pos.angle / (360 / _this._frameCount)); + var frameIndex = _this._frameCount - curr - 1; + + _this._sprites.setFrameIndex(frameIndex); + + _this.trigger(new ComponentEvent("change", { + frameIndex: frameIndex, + colRow: _this._sprites.getColRow(), + angle: evt.pos.angle + })); + }, + "animationEnd": function (evt) { + _this.trigger(new ComponentEvent("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + + _this._axes.connect("angle", _this._panInput); + + return _this; + } + /** + * Set spin scale + * @ko scale 을 조정할 수 있는 함수 + * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.setScale(2);// It moves twice as much. + */ + + + var __proto = SpinViewer.prototype; + + __proto.setScale = function (scale) { + if (isNaN(scale) || scale < 0) { + return this; + } + + this._scale = scale; + this._panScale = scale * DEFAULT_PAN_SCALE; + this._panInput.options.scale = [this._panScale, this._panScale]; + return this; + }; + /** + * Get spin scale + * @ko scale 값을 반환한다. + * + * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @example + * viewer.getScale();// It returns number + */ + + + __proto.getScale = function () { + return this._scale; + }; + /** + * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle. + * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle상대적 회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinBy(720, {duration: 500}); + */ + + + __proto.spinBy = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setBy({ + angle: angle + }, param.duration); + + return this; + }; + /** + * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle). + * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinTo(30, {duration:100}); + */ + + + __proto.spinTo = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setTo({ + angle: angle + }, param.duration); + + return this; + }; + /** + * Returns current angles + * @ko 현재 각도를 반환한다. + * + * @return {Number} Current angle 현재 각도 + */ + + + __proto.getAngle = function () { + return this._axes.get().angle || 0; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @static + * @example + * eg.view360.SpinViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.SpinViewer + */ + + + SpinViewer.VERSION = VERSION; + return SpinViewer; +}(Component); + +var withMethods = function (component, prototype, vanillaInstance) { + [Component.prototype, component.prototype].forEach(function (proto) { + Object.getOwnPropertyNames(proto).filter(function (name) { + return !prototype[name] && !name.startsWith("_") && name !== "constructor"; + }).forEach(function (name) { + var descriptor = Object.getOwnPropertyDescriptor(proto, name); + + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function () { + var _a; + + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + return (_a = descriptor.value).call.apply(_a, __spread([this[vanillaInstance]], args)); + } + }); + } else { + var getterDescriptor = {}; + + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + + return (_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[vanillaInstance]); + }; + } + + if (descriptor.set) { + getterDescriptor.set = function () { + var _a; + + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spread([this[vanillaInstance]], args)); + }; + } + + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); +}; + +var withPanoViewerMethods = function (prototype, name) { + withMethods(PanoViewer, prototype, name); +}; + +var withSpinViewerMethods = function (prototype, name) { + withMethods(SpinViewer, prototype, name); +}; + +var updatePanoViewer = (function (panoViewer, newProps, prevProps) { + if (isPropChanged(newProps.image, prevProps.image)) { + panoViewer.setImage(newProps.image, { + projectionType: newProps.projectionType, + cubemapConfig: newProps.cubemapConfig, + stereoFormat: newProps.stereoFormat, + isVideo: false + }); + } else if (isPropChanged(newProps.video, prevProps.video)) { + panoViewer.setVideo(newProps.video, { + projectionType: newProps.projectionType, + cubemapConfig: newProps.cubemapConfig, + stereoFormat: newProps.stereoFormat + }); + } + + var singleUpdateOptions = ["fovRange", "gyroMode", "pitchRange", "showPolePoint", "touchDirection", "useKeyboard", "useZoom", "yawRange"]; + singleUpdateOptions.forEach(function (optionName) { + updateOption(panoViewer, optionName, newProps, prevProps); + }); +}); + +var isPropChanged = function (val, prevVal) { + return val != null && val !== prevVal; +}; + +var updateOption = function (panoViewer, optionName, newProps, prevProps) { + if (isPropChanged(newProps[optionName], prevProps[optionName])) { + panoViewer["set" + optionName[0].toUpperCase() + optionName.slice(1)](newProps[optionName]); + } +}; + +var getValidProps = function (propsObj) { + return Object.keys(propsObj).reduce(function (props, propName) { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + + return props; + }, {}); +}; +var generateCanvasKey = function (oldKey) { + var newKey; + + do { + var array = new Uint32Array(1); + crypto.getRandomValues(array); + newKey = array[0]; + } while (newKey === oldKey); + + return newKey; +}; + +export { DEFAULT_CANVAS_CLASS, DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS, ERROR_TYPE, GYRO_MODE, PANOVIEWER_EVENTS, PANOVIEWER_OPTIONS, PROJECTION_TYPE, PanoViewer, SPINVIEWER_EVENTS, SPINVIEWER_OPTIONS, STEREO_FORMAT, SpinViewer, SpriteImage, VERSION, generateCanvasKey, getValidProps, updatePanoViewer, withMethods, withPanoViewerMethods, withSpinViewerMethods }; diff --git a/dist/view360.js b/dist/view360.js new file mode 100644 index 000000000..1c1d735f0 --- /dev/null +++ b/dist/view360.js @@ -0,0 +1,7411 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@egjs/component'), require('promise-polyfill'), require('@egjs/agent'), require('@egjs/axes'), require('gl-matrix'), require('@egjs/imready')) : + typeof define === 'function' && define.amd ? define(['@egjs/component', 'promise-polyfill', '@egjs/agent', '@egjs/axes', 'gl-matrix', '@egjs/imready'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.eg = global.eg || {}, global.eg.view360 = factory(global.eg.Component, global.Promise, global.eg.agent, global.eg.Axes, global.glMatrix, global.eg.ImReady))); +}(this, (function (Component, Promise$1, agent$1, Axes, glMatrix, ImReady) { 'use strict'; + + var VERSION = "3.6.3"; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); + }; + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + function __generator(thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }, + f, + y, + t, + g; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; + + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + + switch (op[0]) { + case 0: + case 1: + t = op; + break; + + case 4: + _.label++; + return { + value: op[1], + done: false + }; + + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + + case 7: + op = _.ops.pop(); + + _.trys.pop(); + + continue; + + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + + if (t && _.label < t[2]) { + _.label = t[2]; + + _.ops.push(op); + + break; + } + + if (t[2]) _.ops.pop(); + + _.trys.pop(); + + continue; + } + + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; + } + } + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + + return ar; + } + + /* eslint-disable @typescript-eslint/no-implied-eval */ + /* eslint-disable no-new-func, no-nested-ternary */ + + var win = typeof window !== "undefined" && window.Math === Math ? window : typeof self !== "undefined" && self.Math === Math ? self : Function("return this")(); + /* eslint-enable no-new-func, no-nested-ternary */ + + var doc = win.document; + var nav = win.navigator; + var agent = agent$1(); + var osName = agent.os.name; + var browserName = agent.browser.name; + var IS_IOS = osName === "ios"; + var IS_SAFARI_ON_DESKTOP = osName === "mac" && browserName === "safari"; + + /* eslint-disable @typescript-eslint/naming-convention */ + win.Float32Array = typeof win.Float32Array !== "undefined" ? win.Float32Array : win.Array; + var Float32Array$1 = win.Float32Array; + var getComputedStyle = win.getComputedStyle; + var userAgent = win.navigator && win.navigator.userAgent; + var SUPPORT_TOUCH = ("ontouchstart" in win); + var SUPPORT_DEVICEMOTION = ("ondevicemotion" in win); + var DeviceMotionEvent = win.DeviceMotionEvent; + var devicePixelRatio = win.devicePixelRatio; + + var TRANSFORM = function () { + var _a; + + var docStyle = (_a = doc === null || doc === void 0 ? void 0 : doc.documentElement.style) !== null && _a !== void 0 ? _a : {}; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in docStyle) { + return target[i]; + } + } + + return ""; + }(); // check for will-change support + + + var SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports && win.CSS.supports("will-change", "transform"); + var WEBXR_SUPPORTED = false; + + var checkXRSupport = function () { + var navigator = window.navigator; + + if (!navigator.xr) { + return; + } + + if (navigator.xr.isSessionSupported) { + navigator.xr.isSessionSupported("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } else if (navigator.xr.supportsSession) { + navigator.xr.supportsSession("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } + }; + + /** + * Original Code + * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js + * Math Util + * modified by egjs + */ + + var quatToVec3 = function (quaternion) { + var baseV = glMatrix.vec3.fromValues(0, 0, 1); + glMatrix.vec3.transformQuat(baseV, baseV, quaternion); + return baseV; + }; + + var toDegree = function (a) { + return a * 180 / Math.PI; + }; + + var util = {}; + + util.isPowerOfTwo = function (n) { + return n && (n & n - 1) === 0; + }; + + util.extractPitchFromQuat = function (quaternion) { + var baseV = quatToVec3(quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + }; + + util.hypot = Math.hypot || function (x, y) { + return Math.sqrt(x * x + y * y); + }; // implement reference + // the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식 + // calculating angle between two vectors : http://darkpgmr.tistory.com/121 + + + var ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] + }; + + var getRotationDelta = function (prevQ, curQ, rotateKind) { + var targetAxis = glMatrix.vec3.fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + var meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + var prevQuaternion = glMatrix.quat.clone(prevQ); + var curQuaternion = glMatrix.quat.clone(curQ); + glMatrix.quat.normalize(prevQuaternion, prevQuaternion); + glMatrix.quat.normalize(curQuaternion, curQuaternion); + var prevPoint = glMatrix.vec3.fromValues(0, 0, 1); + var curPoint = glMatrix.vec3.fromValues(0, 0, 1); + glMatrix.vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + glMatrix.vec3.transformQuat(curPoint, curPoint, curQuaternion); + glMatrix.vec3.transformQuat(targetAxis, targetAxis, curQuaternion); + var rotateDistance = glMatrix.vec3.dot(targetAxis, glMatrix.vec3.cross(glMatrix.vec3.create(), prevPoint, curPoint)); + var rotateDirection = rotateDistance > 0 ? 1 : -1; // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + + var meshPoint2 = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + var meshPoint3; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = glMatrix.vec3.fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = glMatrix.vec3.fromValues(rotateDirection, 0, 0); + } + + glMatrix.vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion); + glMatrix.vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion); + var vecU = meshPoint2; + var vecV = meshPoint3; + var vecN = glMatrix.vec3.create(); + glMatrix.vec3.cross(vecN, vecU, vecV); + glMatrix.vec3.normalize(vecN, vecN); + var coefficientA = vecN[0]; + var coefficientB = vecN[1]; + var coefficientC = vecN[2]; // const coefficientD = -1 * vec3.dot(vecN, meshPoint1); + // a point on the plane + + curPoint = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + glMatrix.vec3.transformQuat(curPoint, curPoint, curQuaternion); // a point should project on the plane + + prevPoint = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + glMatrix.vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); // distance between prevPoint and the plane + + var distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + var projectedPrevPoint = glMatrix.vec3.create(); + glMatrix.vec3.subtract(projectedPrevPoint, prevPoint, glMatrix.vec3.scale(glMatrix.vec3.create(), vecN, distance)); + var trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (glMatrix.vec3.length(projectedPrevPoint) * glMatrix.vec3.length(curPoint)); // defensive block + + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + + var theta = Math.acos(trigonometricRatio); + var crossVec = glMatrix.vec3.cross(glMatrix.vec3.create(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + var thetaDirection; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + + var deltaRadian = theta * thetaDirection * rotateDirection; + return toDegree(deltaRadian); + }; + + var angleBetweenVec2 = function (v1, v2) { + var det = v1[0] * v2[1] - v2[0] * v1[1]; + var theta = -Math.atan2(det, glMatrix.vec2.dot(v1, v2)); + return theta; + }; + + util.yawOffsetBetween = function (viewDir, targetDir) { + var viewDirXZ = glMatrix.vec2.fromValues(viewDir[0], viewDir[2]); + var targetDirXZ = glMatrix.vec2.fromValues(targetDir[0], targetDir[2]); + glMatrix.vec2.normalize(viewDirXZ, viewDirXZ); + glMatrix.vec2.normalize(targetDirXZ, targetDirXZ); + var theta = -angleBetweenVec2(viewDirXZ, targetDirXZ); + return theta; + }; + + util.sign = function (x) { + return Math.sign ? Math.sign(x) : Number(x > 0) - Number(x < 0) || +x; + }; + + util.toDegree = toDegree; + util.getRotationDelta = getRotationDelta; + util.angleBetweenVec2 = angleBetweenVec2; + + var toAxis = function (source, offset) { + return offset.reduce(function (acc, v, i) { + if (source[i]) { + acc[source[i]] = v; + } + + return acc; + }, {}); + }; + + /** + * Returns a number value indiciating the version of Chrome being used, + * or otherwise `null` if not on Chrome. + * + * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19 + */ + + /** + * In Chrome m65, `devicemotion` events are broken but subsequently fixed + * in 65.0.3325.148. Since many browsers use Chromium, ensure that + * we scope this detection by branch and build numbers to provide + * a proper fallback. + * https://github.com/immersive-web/webvr-polyfill/issues/307 + */ + + var version = -1; // It should not be null because it will be compared with number + + var branch = null; + var build = null; + var match = /Chrome\/([0-9]+)\.(?:[0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(userAgent); + + if (match) { + version = parseInt(match[1], 10); + branch = match[2]; + build = match[3]; + } + + var CHROME_VERSION = version; + var IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === "3325" && parseInt(build, 10) < 148; + var IS_ANDROID = /Android/i.test(userAgent); + var CONTROL_MODE_VR = 1; + var CONTROL_MODE_YAWPITCH = 2; + var TOUCH_DIRECTION_NONE = 1; + var TOUCH_DIRECTION_YAW = 2; + var TOUCH_DIRECTION_PITCH = 4; + var TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH; + /* Const for MovableCoord */ + + var MC_DECELERATION = 0.0014; + var MC_MAXIMUM_DURATION = 1000; + var MC_BIND_SCALE = [0.20, 0.20]; + var MAX_FIELD_OF_VIEW = 110; + var PAN_SCALE = 320; // const DELTA_THRESHOLD = 0.015; + + var YAW_RANGE_HALF = 180; + var PITCH_RANGE_HALF = 90; + var CIRCULAR_PITCH_RANGE_HALF = 180; + var GYRO_MODE = { + NONE: "none", + YAWPITCH: "yawPitch", + VR: "VR" + }; + + /* eslint-disable */ + var MathUtil = win.MathUtil || {}; + MathUtil.degToRad = Math.PI / 180; + MathUtil.radToDeg = 180 / Math.PI; // Some minimal math functionality borrowed from THREE.Math and stripped down + // for the purposes of this library. + + MathUtil.Vector2 = function (x, y) { + this.x = x || 0; + this.y = y || 0; + }; + + MathUtil.Vector2.prototype = { + constructor: MathUtil.Vector2, + set: function (x, y) { + this.x = x; + this.y = y; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + return this; + }, + subVectors: function (a, b) { + this.x = a.x - b.x; + this.y = a.y - b.y; + return this; + } + }; + + MathUtil.Vector3 = function (x, y, z) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + }; + + MathUtil.Vector3.prototype = { + constructor: MathUtil.Vector3, + set: function (x, y, z) { + this.x = x; + this.y = y; + this.z = z; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + return this; + }, + length: function () { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + }, + normalize: function () { + var scalar = this.length(); + + if (scalar !== 0) { + var invScalar = 1 / scalar; + this.multiplyScalar(invScalar); + } else { + this.x = 0; + this.y = 0; + this.z = 0; + } + + return this; + }, + multiplyScalar: function (scalar) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + }, + applyQuaternion: function (q) { + var x = this.x; + var y = this.y; + var z = this.z; + var qx = q.x; + var qy = q.y; + var qz = q.z; + var qw = q.w; // calculate quat * vector + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + + this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return this; + }, + dot: function (v) { + return this.x * v.x + this.y * v.y + this.z * v.z; + }, + crossVectors: function (a, b) { + var ax = a.x; + var ay = a.y; + var az = a.z; + var bx = b.x; + var by = b.y; + var bz = b.z; + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; + return this; + } + }; + + MathUtil.Quaternion = function (x, y, z, w) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w !== undefined ? w : 1; + }; + + MathUtil.Quaternion.prototype = { + constructor: MathUtil.Quaternion, + set: function (x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + return this; + }, + copy: function (quaternion) { + this.x = quaternion.x; + this.y = quaternion.y; + this.z = quaternion.z; + this.w = quaternion.w; + return this; + }, + setFromEulerXYZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + return this; + }, + setFromEulerYXZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + return this; + }, + setFromAxisAngle: function (axis, angle) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // assumes axis is normalized + var halfAngle = angle / 2; + var s = Math.sin(halfAngle); + this.x = axis.x * s; + this.y = axis.y * s; + this.z = axis.z * s; + this.w = Math.cos(halfAngle); + return this; + }, + multiply: function (q) { + return this.multiplyQuaternions(this, q); + }, + multiplyQuaternions: function (a, b) { + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + var qax = a.x; + var qay = a.y; + var qaz = a.z; + var qaw = a.w; + var qbx = b.x; + var qby = b.y; + var qbz = b.z; + var qbw = b.w; + this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; + return this; + }, + inverse: function () { + this.x *= -1; + this.y *= -1; + this.z *= -1; + this.normalize(); + return this; + }, + normalize: function () { + var l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + + if (l === 0) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 1; + } else { + l = 1 / l; + this.x = this.x * l; + this.y = this.y * l; + this.z = this.z * l; + this.w = this.w * l; + } + + return this; + }, + slerp: function (qb, t) { + if (t === 0) return this; + if (t === 1) return this.copy(qb); + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + + var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z; + + if (cosHalfTheta < 0) { + this.w = -qb.w; + this.x = -qb.x; + this.y = -qb.y; + this.z = -qb.z; + cosHalfTheta = -cosHalfTheta; + } else { + this.copy(qb); + } + + if (cosHalfTheta >= 1.0) { + this.w = w; + this.x = x; + this.y = y; + this.z = z; + return this; + } + + var halfTheta = Math.acos(cosHalfTheta); + var sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta); + + if (Math.abs(sinHalfTheta) < 0.001) { + this.w = 0.5 * (w + this.w); + this.x = 0.5 * (x + this.x); + this.y = 0.5 * (y + this.y); + this.z = 0.5 * (z + this.z); + return this; + } + + var ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta; + var ratioB = Math.sin(t * halfTheta) / sinHalfTheta; + this.w = w * ratioA + this.w * ratioB; + this.x = x * ratioA + this.x * ratioB; + this.y = y * ratioA + this.y * ratioB; + this.z = z * ratioA + this.z * ratioB; + return this; + }, + setFromUnitVectors: function () { + // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final + // assumes direction vectors vFrom and vTo are normalized + var v1; + var r; + var EPS = 0.000001; + return function (vFrom, vTo) { + if (v1 === undefined) v1 = new MathUtil.Vector3(); + r = vFrom.dot(vTo) + 1; + + if (r < EPS) { + r = 0; + + if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { + v1.set(-vFrom.y, vFrom.x, 0); + } else { + v1.set(0, -vFrom.z, vFrom.y); + } + } else { + v1.crossVectors(vFrom, vTo); + } + + this.x = v1.x; + this.y = v1.y; + this.z = v1.z; + this.w = r; + this.normalize(); + return this; + }; + }() + }; + + /* eslint-disable */ + + /* + * Copyright 2015 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + var _a; // tslint:disable: only-arrow-functions + var userAgent$1 = (_a = nav === null || nav === void 0 ? void 0 : nav.userAgent) !== null && _a !== void 0 ? _a : ""; + var Util = win.Util || {}; + Util.MIN_TIMESTEP = 0.001; + Util.MAX_TIMESTEP = 1; + + Util.base64 = function (mimeType, base64) { + return "data:" + mimeType + ";base64," + base64; + }; + + Util.clamp = function (value, min, max) { + return Math.min(Math.max(min, value), max); + }; + + Util.lerp = function (a, b, t) { + return a + (b - a) * t; + }; + + Util.isIOS = function () { + var isIOS = /iPad|iPhone|iPod/.test(nav === null || nav === void 0 ? void 0 : nav.platform); + return function () { + return isIOS; + }; + }(); + + Util.isWebViewAndroid = function () { + var isWebViewAndroid = userAgent$1.indexOf("Version") !== -1 && userAgent$1.indexOf("Android") !== -1 && userAgent$1.indexOf("Chrome") !== -1; + return function () { + return isWebViewAndroid; + }; + }(); + + Util.isSafari = function () { + var isSafari = /^((?!chrome|android).)*safari/i.test(userAgent$1); + return function () { + return isSafari; + }; + }(); + + Util.isFirefoxAndroid = function () { + var isFirefoxAndroid = userAgent$1.indexOf("Firefox") !== -1 && userAgent$1.indexOf("Android") !== -1; + return function () { + return isFirefoxAndroid; + }; + }(); + + Util.isR7 = function () { + var isR7 = userAgent$1.indexOf("R7 Build") !== -1; + return function () { + return isR7; + }; + }(); + + Util.isLandscapeMode = function () { + var rtn = win.orientation === 90 || win.orientation === -90; + return Util.isR7() ? !rtn : rtn; + }; // Helper method to validate the time steps of sensor timestamps. + + + Util.isTimestampDeltaValid = function (timestampDeltaS) { + if (isNaN(timestampDeltaS)) { + return false; + } + + if (timestampDeltaS <= Util.MIN_TIMESTEP) { + return false; + } + + if (timestampDeltaS > Util.MAX_TIMESTEP) { + return false; + } + + return true; + }; + + Util.getScreenWidth = function () { + return Math.max(win.screen.width, win.screen.height) * win.devicePixelRatio; + }; + + Util.getScreenHeight = function () { + return Math.min(win.screen.width, win.screen.height) * win.devicePixelRatio; + }; + + Util.requestFullscreen = function (element) { + if (Util.isWebViewAndroid()) { + return false; + } + + if (element.requestFullscreen) { + element.requestFullscreen(); + } else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } else { + return false; + } + + return true; + }; + + Util.exitFullscreen = function () { + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else if (doc.webkitExitFullscreen) { + doc.webkitExitFullscreen(); + } else if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } else { + return false; + } + + return true; + }; + + Util.getFullscreenElement = function () { + return doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement; + }; + + Util.linkProgram = function (gl, vertexSource, fragmentSource, attribLocationMap) { + // No error checking for brevity. + var vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vertexSource); + gl.compileShader(vertexShader); + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + for (var attribName in attribLocationMap) gl.bindAttribLocation(program, attribLocationMap[attribName], attribName); + + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + return program; + }; + + Util.getProgramUniforms = function (gl, program) { + var uniforms = {}; + var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + var uniformName = ""; + + for (var i = 0; i < uniformCount; i++) { + var uniformInfo = gl.getActiveUniform(program, i); + uniformName = uniformInfo.name.replace("[0]", ""); + uniforms[uniformName] = gl.getUniformLocation(program, uniformName); + } + + return uniforms; + }; + + Util.orthoMatrix = function (out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 2 * nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = (far + near) * nf; + out[15] = 1; + return out; + }; + + Util.copyArray = function (source, dest) { + for (var i = 0, n = source.length; i < n; i++) { + dest[i] = source[i]; + } + }; + + Util.isMobile = function () { + var check = false; + + (function (a) { + if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; + })(userAgent$1 || (nav === null || nav === void 0 ? void 0 : nav.vendor) || win.opera); + + return check; + }; + + Util.extend = function (dest, src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dest[key] = src[key]; + } + } + + return dest; + }; + + Util.safariCssSizeWorkaround = function (canvas) { + // TODO(smus): Remove this workaround when Safari for iOS is fixed. + // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556). + // + // "To the last I grapple with thee; + // from hell's heart I stab at thee; + // for hate's sake I spit my last breath at thee." + // -- Moby Dick, by Herman Melville + if (Util.isIOS()) { + var width_1 = canvas.style.width; + var height_1 = canvas.style.height; + canvas.style.width = parseInt(width_1) + 1 + "px"; + canvas.style.height = parseInt(height_1) + "px"; + setTimeout(function () { + canvas.style.width = width_1; + canvas.style.height = height_1; + }, 100); + } // Debug only. + + + win.Util = Util; + win.canvas = canvas; + }; + + Util.isDebug = function () { + return Util.getQueryParameter("debug"); + }; + + Util.getQueryParameter = function (name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"); + var results = regex.exec(location.search); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); + }; + + Util.frameDataFromPose = function () { + var piOver180 = Math.PI / 180.0; + var rad45 = Math.PI * 0.25; // Borrowed from glMatrix. + + function mat4_perspectiveFromFieldOfView(out, fov, near, far) { + var upTan = Math.tan(fov ? fov.upDegrees * piOver180 : rad45); + var downTan = Math.tan(fov ? fov.downDegrees * piOver180 : rad45); + var leftTan = Math.tan(fov ? fov.leftDegrees * piOver180 : rad45); + var rightTan = Math.tan(fov ? fov.rightDegrees * piOver180 : rad45); + var xScale = 2.0 / (leftTan + rightTan); + var yScale = 2.0 / (upTan + downTan); + out[0] = xScale; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + out[4] = 0.0; + out[5] = yScale; + out[6] = 0.0; + out[7] = 0.0; + out[8] = -((leftTan - rightTan) * xScale * 0.5); + out[9] = (upTan - downTan) * yScale * 0.5; + out[10] = far / (near - far); + out[11] = -1.0; + out[12] = 0.0; + out[13] = 0.0; + out[14] = far * near / (near - far); + out[15] = 0.0; + return out; + } + + function mat4_fromRotationTranslation(out, q, v) { + // Quaternion math + var x = q[0]; + var y = q[1]; + var z = q[2]; + var w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - (yy + zz); + out[1] = xy + wz; + out[2] = xz - wy; + out[3] = 0; + out[4] = xy - wz; + out[5] = 1 - (xx + zz); + out[6] = yz + wx; + out[7] = 0; + out[8] = xz + wy; + out[9] = yz - wx; + out[10] = 1 - (xx + yy); + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + + function mat4_translate(out, a, v) { + var x = v[0]; + var y = v[1]; + var z = v[2]; + var a00; + var a01; + var a02; + var a03; + var a10; + var a11; + var a12; + var a13; + var a20; + var a21; + var a22; + var a23; + + if (a === out) { + out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; + out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; + out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; + out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; + } else { + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a03; + out[4] = a10; + out[5] = a11; + out[6] = a12; + out[7] = a13; + out[8] = a20; + out[9] = a21; + out[10] = a22; + out[11] = a23; + out[12] = a00 * x + a10 * y + a20 * z + a[12]; + out[13] = a01 * x + a11 * y + a21 * z + a[13]; + out[14] = a02 * x + a12 * y + a22 * z + a[14]; + out[15] = a03 * x + a13 * y + a23 * z + a[15]; + } + + return out; + } + + function mat4_invert(out, a) { + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + var a30 = a[12]; + var a31 = a[13]; + var a32 = a[14]; + var a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + return out; + } + + var defaultOrientation = new Float32Array([0, 0, 0, 1]); + var defaultPosition = new Float32Array([0, 0, 0]); + + function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) { + mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar); + var orientation = pose.orientation || defaultOrientation; + var position = pose.position || defaultPosition; + mat4_fromRotationTranslation(view, orientation, position); + if (parameters) mat4_translate(view, view, parameters.offset); + mat4_invert(view, view); + } + + return function (frameData, pose, vrDisplay) { + if (!frameData || !pose) return false; + frameData.pose = pose; + frameData.timestamp = pose.timestamp; + updateEyeMatrices(frameData.leftProjectionMatrix, frameData.leftViewMatrix, pose, vrDisplay.getEyeParameters("left"), vrDisplay); + updateEyeMatrices(frameData.rightProjectionMatrix, frameData.rightViewMatrix, pose, vrDisplay.getEyeParameters("right"), vrDisplay); + return true; + }; + }(); + + Util.isInsideCrossDomainIFrame = function () { + var isFramed = win.self !== win.top; + var refDomain = Util.getDomainFromUrl(doc.referrer); + var thisDomain = Util.getDomainFromUrl(win.location.href); + return isFramed && refDomain !== thisDomain; + }; // From http://stackoverflow.com/a/23945027. + + + Util.getDomainFromUrl = function (url) { + var domain; // Find & remove protocol (http, ftp, etc.) and get domain. + + if (url.indexOf("://") > -1) { + domain = url.split("/")[2]; + } else { + domain = url.split("/")[0]; + } // find & remove port number + + + domain = domain.split(":")[0]; + return domain; + }; + + /* eslint-disable */ + /** + * Given an orientation and the gyroscope data, predicts the future orientation + * of the head. This makes rendering appear faster. + * + * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf + * @param {Number} predictionTimeS time from head movement to the appearance of + * the corresponding image. + */ + + var PosePredictor = + /*#__PURE__*/ + function () { + function PosePredictor(predictionTimeS) { + this.predictionTimeS = predictionTimeS; // The quaternion corresponding to the previous state. + + this.previousQ = new MathUtil.Quaternion(); // Previous time a prediction occurred. + + this.previousTimestampS = null; // The delta quaternion that adjusts the current pose. + + this.deltaQ = new MathUtil.Quaternion(); // The output quaternion. + + this.outQ = new MathUtil.Quaternion(); + } + + var __proto = PosePredictor.prototype; + + __proto.getPrediction = function (currentQ, gyro, timestampS) { + if (!this.previousTimestampS) { + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return currentQ; + } // Calculate axis and angle based on gyroscope rotation rate data. + + + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + var angularSpeed = gyro.length(); // If we're rotating slowly, don't do prediction. + + if (angularSpeed < MathUtil.degToRad * 20) { + if (Util.isDebug()) { + console.log("Moving slowly, at %s deg/s: no prediction", (MathUtil.radToDeg * angularSpeed).toFixed(1)); + } + + this.outQ.copy(currentQ); + this.previousQ.copy(currentQ); + return this.outQ; + } // Get the predicted angle based on the time delta and latency. + + + var deltaT = timestampS - this.previousTimestampS; + var predictAngle = angularSpeed * this.predictionTimeS; + this.deltaQ.setFromAxisAngle(axis, predictAngle); + this.outQ.copy(this.previousQ); + this.outQ.multiply(this.deltaQ); + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return this.outQ; + }; + + return PosePredictor; + }(); + + var STILLNESS_THRESHOLD = 200; // millisecond + + var DeviceMotion = + /*#__PURE__*/ + function (_super) { + __extends(DeviceMotion, _super); + + function DeviceMotion() { + var _this = _super.call(this) || this; + + _this._onDeviceMotion = _this._onDeviceMotion.bind(_this); + _this._onDeviceOrientation = _this._onDeviceOrientation.bind(_this); + _this._onChromeWithoutDeviceMotion = _this._onChromeWithoutDeviceMotion.bind(_this); + _this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION; + _this.isAndroid = IS_ANDROID; + _this.stillGyroVec = glMatrix.vec3.create(); + _this.rawGyroVec = glMatrix.vec3.create(); + _this.adjustedGyroVec = glMatrix.vec3.create(); + _this._timer = -1; + _this.lastDevicemotionTimestamp = 0; + _this._isEnabled = false; + + _this.enable(); + + return _this; + } + + var __proto = DeviceMotion.prototype; + + __proto.enable = function () { + if (this.isAndroid) { + win.addEventListener("deviceorientation", this._onDeviceOrientation); + } + + if (this.isWithoutDeviceMotion) { + win.addEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + } else { + win.addEventListener("devicemotion", this._onDeviceMotion); + } + + this._isEnabled = true; + }; + + __proto.disable = function () { + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + win.removeEventListener("devicemotion", this._onDeviceMotion); + this._isEnabled = false; + }; + + __proto._onChromeWithoutDeviceMotion = function (e) { + var alpha = e.alpha, + beta = e.beta, + gamma = e.gamma; // There is deviceorientation event trigged with empty values + // on Headless Chrome. + + if (alpha === null) { + return; + } // convert to radian + + + alpha = (alpha || 0) * Math.PI / 180; + beta = (beta || 0) * Math.PI / 180; + gamma = (gamma || 0) * Math.PI / 180; + this.trigger(new Component.ComponentEvent("devicemotion", { + inputEvent: { + deviceorientation: { + alpha: alpha, + beta: beta, + gamma: -gamma + } + } + })); + }; + + __proto._onDeviceOrientation = function () { + var _this = this; + + if (this._timer) { + clearTimeout(this._timer); + } + + this._timer = win.setTimeout(function () { + if (new Date().getTime() - _this.lastDevicemotionTimestamp < STILLNESS_THRESHOLD) { + glMatrix.vec3.copy(_this.stillGyroVec, _this.rawGyroVec); + } + }, STILLNESS_THRESHOLD); + }; + + __proto._onDeviceMotion = function (e) { + // desktop chrome triggers devicemotion event with empthy sensor values. + // Those events should ignored. + var isGyroSensorAvailable = !(e.rotationRate.alpha == null); + var isGravitySensorAvailable = !(e.accelerationIncludingGravity.x == null); + + if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) { + return; + } + + var devicemotionEvent = __assign({}, e); + + devicemotionEvent.interval = e.interval; + devicemotionEvent.timeStamp = e.timeStamp; + devicemotionEvent.type = e.type; + devicemotionEvent.rotationRate = { + alpha: e.rotationRate.alpha, + beta: e.rotationRate.beta, + gamma: e.rotationRate.gamma + }; + devicemotionEvent.accelerationIncludingGravity = { + x: e.accelerationIncludingGravity.x, + y: e.accelerationIncludingGravity.y, + z: e.accelerationIncludingGravity.z + }; + devicemotionEvent.acceleration = { + x: e.acceleration.x, + y: e.acceleration.y, + z: e.acceleration.z + }; + + if (this.isAndroid) { + glMatrix.vec3.set(this.rawGyroVec, e.rotationRate.alpha || 0, e.rotationRate.beta || 0, e.rotationRate.gamma || 0); + glMatrix.vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec); + this.lastDevicemotionTimestamp = new Date().getTime(); + devicemotionEvent.adjustedRotationRate = { + alpha: this.adjustedGyroVec[0], + beta: this.adjustedGyroVec[1], + gamma: this.adjustedGyroVec[2] + }; + } + + this.trigger(new Component.ComponentEvent("devicemotion", { + inputEvent: devicemotionEvent + })); + }; + + return DeviceMotion; + }(Component); + + var SensorSample = + /*#__PURE__*/ + function () { + function SensorSample(sample, timestampS) { + this.set(sample, timestampS); + } + + var __proto = SensorSample.prototype; + + __proto.set = function (sample, timestampS) { + this.sample = sample; + this.timestampS = timestampS; + }; + + __proto.copy = function (sensorSample) { + this.set(sensorSample.sample, sensorSample.timestampS); + }; + + return SensorSample; + }(); + + /* eslint-disable */ + /** + * An implementation of a simple complementary filter, which fuses gyroscope and + * accelerometer data from the 'devicemotion' event. + * + * Accelerometer data is very noisy, but stable over the long term. + * Gyroscope data is smooth, but tends to drift over the long term. + * + * This fusion is relatively simple: + * 1. Get orientation estimates from accelerometer by applying a low-pass filter + * on that data. + * 2. Get orientation estimates from gyroscope by integrating over time. + * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the + * short term. + */ + + var ComplementaryFilter = + /*#__PURE__*/ + function () { + function ComplementaryFilter(kFilter) { + this.addGyroMeasurement = function (vector, timestampS) { + this.currentGyroMeasurement.set(vector, timestampS); + var deltaT = timestampS - this.previousGyroMeasurement.timestampS; + + if (Util.isTimestampDeltaValid(deltaT)) { + this.run_(); + } + + this.previousGyroMeasurement.copy(this.currentGyroMeasurement); + }; + + this.kFilter = kFilter; // Raw sensor measurements. + + this.currentAccelMeasurement = new SensorSample(); + this.currentGyroMeasurement = new SensorSample(); + this.previousGyroMeasurement = new SensorSample(); // Set default look direction to be in the correct direction. + + if (Util.isIOS()) { + this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1); + } else { + this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1); + } + + this.previousFilterQ = new MathUtil.Quaternion(); + this.previousFilterQ.copy(this.filterQ); // Orientation based on the accelerometer. + + this.accelQ = new MathUtil.Quaternion(); // Whether or not the orientation has been initialized. + + this.isOrientationInitialized = false; // Running estimate of gravity based on the current orientation. + + this.estimatedGravity = new MathUtil.Vector3(); // Measured gravity based on accelerometer. + + this.measuredGravity = new MathUtil.Vector3(); // Debug only quaternion of gyro-based orientation. + + this.gyroIntegralQ = new MathUtil.Quaternion(); + } + + var __proto = ComplementaryFilter.prototype; + + __proto.addAccelMeasurement = function (vector, timestampS) { + this.currentAccelMeasurement.set(vector, timestampS); + }; + + __proto.getOrientation = function () { + return this.filterQ; + }; + + __proto.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); + + if (Util.isDebug()) { + console.log("Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)", MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ), this.estimatedGravity.x.toFixed(1), this.estimatedGravity.y.toFixed(1), this.estimatedGravity.z.toFixed(1), this.measuredGravity.x.toFixed(1), this.measuredGravity.y.toFixed(1), this.measuredGravity.z.toFixed(1)); + } // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + }; + + __proto.accelToQuaternion_ = function (accel) { + var normAccel = new MathUtil.Vector3(); + normAccel.copy(accel); + normAccel.normalize(); + var quat = new MathUtil.Quaternion(); + quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel); + quat.inverse(); + return quat; + }; + + __proto.gyroToQuaternionDelta_ = function (gyro, dt) { + // Extract axis and angle from the gyroscope data. + var quat = new MathUtil.Quaternion(); + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + quat.setFromAxisAngle(axis, gyro.length() * dt); + return quat; + }; + + return ComplementaryFilter; + }(); + + ComplementaryFilter.prototype.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + + if (!this.isFilterQuaternionInitialized) { + this.isFilterQuaternionInitialized = true; + } + }; + + ComplementaryFilter.prototype.getOrientation = function () { + if (this.isFilterQuaternionInitialized) { + return this.filterQ; + } else { + return null; + } + }; + + var K_FILTER = 0.98; + var PREDICTION_TIME_S = 0.040; + + var FusionPoseSensor = + /*#__PURE__*/ + function (_super) { + __extends(FusionPoseSensor, _super); + + function FusionPoseSensor() { + var _this = _super.call(this) || this; + + _this.deviceMotion = new DeviceMotion(); + _this.accelerometer = new MathUtil.Vector3(); + _this.gyroscope = new MathUtil.Vector3(); + _this._onDeviceMotionChange = _this._onDeviceMotionChange.bind(_this); + _this._onScreenOrientationChange = _this._onScreenOrientationChange.bind(_this); + _this.filter = new ComplementaryFilter(K_FILTER); + _this.posePredictor = new PosePredictor(PREDICTION_TIME_S); + _this.filterToWorldQ = new MathUtil.Quaternion(); + _this.isFirefoxAndroid = Util.isFirefoxAndroid(); // This includes iPhone & iPad(both desktop and mobile mode) ref #326 + + _this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP; // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18 + + _this.isChromeUsingDegrees = CHROME_VERSION >= 66; + _this._isEnabled = false; // Set the filter to world transform, depending on OS. + + if (_this.isIOS) { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2); + } else { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2); + } + + _this.inverseWorldToScreenQ = new MathUtil.Quaternion(); + _this.worldToScreenQ = new MathUtil.Quaternion(); + _this.originalPoseAdjustQ = new MathUtil.Quaternion(); + + _this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -win.orientation * Math.PI / 180); + + _this._setScreenTransform(); // Adjust this filter for being in landscape mode. + + + if (Util.isLandscapeMode()) { + _this.filterToWorldQ.multiply(_this.inverseWorldToScreenQ); + } // Keep track of a reset transform for resetSensor. + + + _this.resetQ = new MathUtil.Quaternion(); + + _this.deviceMotion.on("devicemotion", _this._onDeviceMotionChange); + + _this.enable(); + + return _this; + } + + var __proto = FusionPoseSensor.prototype; + + __proto.enable = function () { + if (this.isEnabled()) { + return; + } + + this.deviceMotion.enable(); + this._isEnabled = true; + win.addEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.disable = function () { + if (!this.isEnabled()) { + return; + } + + this.deviceMotion.disable(); + this._isEnabled = false; + win.removeEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.isEnabled = function () { + return this._isEnabled; + }; + + __proto.destroy = function () { + this.disable(); + this.deviceMotion = null; + }; + + __proto.getOrientation = function () { + var _this = this; + + var orientation; // Hack around using deviceorientation instead of devicemotion + + if (this.deviceMotion.isWithoutDeviceMotion && this._deviceOrientationQ) { + this.deviceOrientationFixQ = this.deviceOrientationFixQ || function () { + var y = new MathUtil.Quaternion().setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -_this._alpha); + return y; + }(); + + orientation = this._deviceOrientationQ; + var out = new MathUtil.Quaternion(); + out.copy(orientation); + out.multiply(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.worldToScreenQ); + out.multiplyQuaternions(this.deviceOrientationFixQ, out); // return quaternion as glmatrix quaternion object + + var outQuat = glMatrix.quat.fromValues(out.x, out.y, out.z, out.w); + return glMatrix.quat.normalize(outQuat, outQuat); + } else { + // Convert from filter space to the the same system used by the + // deviceorientation event. + orientation = this.filter.getOrientation(); + + if (!orientation) { + return null; + } + + var out = this._convertFusionToPredicted(orientation); // return quaternion as glmatrix quaternion object + + + var outQuat = glMatrix.quat.fromValues(out.x, out.y, out.z, out.w); + return glMatrix.quat.normalize(outQuat, outQuat); + } + }; + + __proto._triggerChange = function () { + var orientation = this.getOrientation(); // if orientation is not prepared. don't trigger change event + + if (!orientation) { + return; + } + + if (!this._prevOrientation) { + this._prevOrientation = orientation; + return; + } + + if (glMatrix.quat.equals(this._prevOrientation, orientation)) { + return; + } + + this.trigger(new Component.ComponentEvent("change", { + quaternion: orientation + })); + }; + + __proto._convertFusionToPredicted = function (orientation) { + // Predict orientation. + this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS); // Convert to THREE coordinate system: -Z forward, Y up, X right. + + var out = new MathUtil.Quaternion(); + out.copy(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.predictedQ); + out.multiply(this.worldToScreenQ); + return out; + }; + + __proto._onDeviceMotionChange = function (_a) { + var inputEvent = _a.inputEvent; + var deviceorientation = inputEvent.deviceorientation; + var deviceMotion = inputEvent; + var accGravity = deviceMotion.accelerationIncludingGravity; + var rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate; + var timestampS = deviceMotion.timeStamp / 1000; + + if (deviceorientation) { + if (!this._alpha) { + this._alpha = deviceorientation.alpha; + } + + this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion(); + + this._deviceOrientationQ.setFromEulerYXZ(deviceorientation.beta, deviceorientation.alpha, deviceorientation.gamma); + + this._triggerChange(); + } else { + // Firefox Android timeStamp returns one thousandth of a millisecond. + if (this.isFirefoxAndroid) { + timestampS /= 1000; + } + + this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z); + this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma); // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate` + // is reported in degrees, so we first convert to radians. + + if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) { + this.gyroscope.multiplyScalar(Math.PI / 180); + } + + this.filter.addAccelMeasurement(this.accelerometer, timestampS); + this.filter.addGyroMeasurement(this.gyroscope, timestampS); + + this._triggerChange(); + + this.previousTimestampS = timestampS; + } + }; + + __proto._onScreenOrientationChange = function () { + this._setScreenTransform(); + }; + + __proto._setScreenTransform = function () { + this.worldToScreenQ.set(0, 0, 0, 1); + var orientation = win.orientation; + + switch (orientation) { + case 0: + break; + + case 90: + case -90: + case 180: + this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI); + break; + } + + this.inverseWorldToScreenQ.copy(this.worldToScreenQ); + this.inverseWorldToScreenQ.inverse(); + }; + + return FusionPoseSensor; + }(Component); + + var getDeltaYaw = function (prvQ, curQ) { + var yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + var yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(util.extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + }; + + var getDeltaPitch = function (prvQ, curQ) { + var pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + return pitchDelta; + }; // eslint-disable-next-line @typescript-eslint/ban-types + + + var TiltMotionInput = + /*#__PURE__*/ + function (_super) { + __extends(TiltMotionInput, _super); + + function TiltMotionInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.element = el; + _this._prevQuaternion = null; + _this._quaternion = null; + _this.fusionPoseSensor = null; + _this.options = __assign({ + scale: 1, + threshold: 0 + }, options); + _this._onPoseChange = _this._onPoseChange.bind(_this); + return _this; + } + + var __proto = TiltMotionInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this.observer) { + return this; + } + + this.observer = observer; + this.fusionPoseSensor = new FusionPoseSensor(); + this.fusionPoseSensor.enable(); + + this._attachEvent(); + + return this; + }; + + __proto.disconnect = function () { + if (!this.observer) { + return this; + } + + this._dettachEvent(); + + this.fusionPoseSensor.disable(); + this.fusionPoseSensor.destroy(); + this.fusionPoseSensor = null; + this.observer = null; + return this; + }; + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + this.options = null; + this.axes = null; + this._prevQuaternion = null; + this._quaternion = null; + }; + + __proto._onPoseChange = function (event) { + if (!this._prevQuaternion) { + this._prevQuaternion = glMatrix.quat.clone(event.quaternion); + this._quaternion = glMatrix.quat.clone(event.quaternion); + return; + } + + glMatrix.quat.copy(this._prevQuaternion, this._quaternion); + glMatrix.quat.copy(this._quaternion, event.quaternion); + this.observer.change(this, event, toAxis(this.axes, [getDeltaYaw(this._prevQuaternion, this._quaternion), getDeltaPitch(this._prevQuaternion, this._quaternion)])); + }; + + __proto._attachEvent = function () { + this.fusionPoseSensor.on("change", this._onPoseChange); + }; + + __proto._dettachEvent = function () { + this.fusionPoseSensor.off("change", this._onPoseChange); + }; + + return TiltMotionInput; + }(Component); + + var screenRotationAngleInst = null; + var refCount = 0; + + var ScreenRotationAngle = + /*#__PURE__*/ + function () { + function ScreenRotationAngle() { + refCount++; + + if (screenRotationAngleInst) { + return screenRotationAngleInst; + } + /* eslint-disable */ + + + screenRotationAngleInst = this; + /* eslint-enable */ + + this._onDeviceOrientation = this._onDeviceOrientation.bind(this); + this._onOrientationChange = this._onOrientationChange.bind(this); + this._spinR = 0; + this._screenOrientationAngle = 0; + win.addEventListener("deviceorientation", this._onDeviceOrientation); + win.addEventListener("orientationchange", this._onOrientationChange); + } + + var __proto = ScreenRotationAngle.prototype; + + __proto.getRadian = function () { + // Join with screen orientation + // this._testVal = this._spinR + ", " + this._screenOrientationAngle + ", " + window.orientation; + return this._spinR + glMatrix.glMatrix.toRadian(this._screenOrientationAngle); + }; + + __proto.unref = function () { + if (--refCount > 0) { + return; + } + + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("orientationchange", this._onOrientationChange); + this._spinR = 0; + this._screenOrientationAngle = 0; + /* eslint-disable */ + + screenRotationAngleInst = null; + /* eslint-enable */ + + refCount = 0; + }; + + __proto._onDeviceOrientation = function (e) { + if (e.beta === null || e.gamma === null) { + // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it. + return; + } // Radian + + + var betaR = glMatrix.glMatrix.toRadian(e.beta); + var gammaR = glMatrix.glMatrix.toRadian(e.gamma); + /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */ + + this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR)); + }; + + __proto._onOrientationChange = function () { + if (win.screen && win.screen.orientation && win.screen.orientation.angle !== undefined) { + this._screenOrientationAngle = screen.orientation.angle; + } else if (win.orientation !== undefined) { + /* iOS */ + this._screenOrientationAngle = win.orientation >= 0 ? win.orientation : 360 + win.orientation; + } + }; + + return ScreenRotationAngle; + }(); + + /** + * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle. + * + * The reason for using this function is that in VR mode, + * the roll angle is adjusted in the direction opposite to the screen rotation angle. + * + * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move. + * @extends PanInput + */ + + var RotationPanInput = + /*#__PURE__*/ + function (_super) { + __extends(RotationPanInput, _super); + /** + * Constructor + * @private + * @param {HTMLElement} el target element + * @param {Object} [options] The option object + * @param {Boolean} [options.useRotation] Whether to use rotation(or VR) + */ + + + function RotationPanInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this, el, options) || this; + + _this._useRotation = false; + _this._screenRotationAngle = null; + + _this.setUseRotation(!!(options && options.useRotation)); + + _this._userDirection = Axes.DIRECTION_ALL; + return _this; + } + + var __proto = RotationPanInput.prototype; + + __proto.setUseRotation = function (useRotation) { + this._useRotation = useRotation; + + if (this._screenRotationAngle) { + this._screenRotationAngle.unref(); + + this._screenRotationAngle = null; + } + + if (this._useRotation) { + this._screenRotationAngle = new ScreenRotationAngle(); + } + }; + + __proto.connect = function (observer) { + // User intetened direction + this._userDirection = this._direction; // In VR Mode, Use ALL direction if direction is not none + // Because horizontal and vertical is changed dynamically by screen rotation. + // this._direction is used to initialize hammerjs + + if (this._useRotation && this._direction & Axes.DIRECTION_ALL) { + this._direction = Axes.DIRECTION_HORIZONTAL; + } + + return _super.prototype.connect.call(this, observer); + }; + + __proto.destroy = function () { + if (this._useRotation && this._screenRotationAngle) { + this._screenRotationAngle.unref(); + } + + _super.prototype.destroy.call(this); + }; + + __proto._getOffset = function (properties, useDirection) { + if (this._useRotation === false) { + return _super.prototype._getOffset.call(this, properties, useDirection); + } + + var offset = _super.prototype._getOffset.call(this, properties, [true, true]); + + var newOffset = [0, 0]; + + var theta = this._screenRotationAngle.getRadian(); + + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); // RotateZ + + newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta; + newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta; // Use only user allowed direction. + + if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) { + newOffset[0] = 0; + } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) { + newOffset[1] = 0; + } + + return newOffset; + }; + + return RotationPanInput; + }(Axes.PanInput); + /** + * Override getDirectionByAngle to return DIRECTION_ALL + * Ref: https://github.com/naver/egjs-axes/issues/99 + * + * But we obey axes's rule. If axes's rule is problem, let's apply following code. + */ + // PanInput.getDirectionByAngle = function (angle, thresholdAngle) { + // return DIRECTION_ALL; + // }; + + var Y_AXIS_VECTOR = glMatrix.vec3.fromValues(0, 1, 0); + + var DeviceQuaternion = + /*#__PURE__*/ + function (_super) { + __extends(DeviceQuaternion, _super); + + function DeviceQuaternion() { + var _this = _super.call(this) || this; + + _this._fusionPoseSensor = new FusionPoseSensor(); + _this._quaternion = glMatrix.quat.create(); + + _this._fusionPoseSensor.enable(); + + _this._fusionPoseSensor.on("change", function (e) { + _this._quaternion = e.quaternion; + + _this.trigger(new Component.ComponentEvent("change", { + isTrusted: true + })); + }); + + return _this; + } + + var __proto = DeviceQuaternion.prototype; + + __proto.getCombinedQuaternion = function (yaw) { + var yawQ = glMatrix.quat.setAxisAngle(glMatrix.quat.create(), Y_AXIS_VECTOR, glMatrix.glMatrix.toRadian(-yaw)); + var conj = glMatrix.quat.conjugate(glMatrix.quat.create(), this._quaternion); // Multiply pitch quaternion -> device quaternion -> yaw quaternion + + var outQ = glMatrix.quat.multiply(glMatrix.quat.create(), conj, yawQ); + return outQ; + }; + + __proto.destroy = function () { + // detach all event handler + this.off(); + + if (this._fusionPoseSensor) { + this._fusionPoseSensor.off(); + + this._fusionPoseSensor.destroy(); + + this._fusionPoseSensor = null; + } + }; + + return DeviceQuaternion; + }(Component); + + var DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF]; + var DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF]; + var CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF]; + /** + * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates. + * @alias eg.YawPitchControl + * @extends eg.Component + * + * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + */ + + var YawPitchControl = + /*#__PURE__*/ + function (_super) { + __extends(YawPitchControl, _super); + /** + * @param {object} options The option object of the eg.YawPitch module + * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module + * @param {number} [options.yaw=0] initial yaw (degree) + * @param {number} [options.pitch=0] initial pitch (degree) + * @param {number} [options.fov=65] initial field of view (degree) + * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown + * @param {boolean} [options.useZoom=true] Indicates whether zoom is available + * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled + * @param {string} [config.gyroMode=yawPitch] Enables control through device motion. + * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move) + * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw + * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch + * @param {number[]} [options.fovRange=[30, 110] Range of FOV + * @param {number} [options.aspectRatio=1] Aspect Ratio + */ + + + function YawPitchControl(options) { + var _this = _super.call(this) || this; + + _this.options = {}; + + var opt = __assign({ + element: null, + yaw: 0, + pitch: 0, + fov: 65, + showPolePoint: false, + useZoom: true, + useKeyboard: true, + gyroMode: GYRO_MODE.YAWPITCH, + touchDirection: TOUCH_DIRECTION_ALL, + yawRange: DEFAULT_YAW_RANGE, + pitchRange: DEFAULT_PITCH_RANGE, + fovRange: [30, 110], + aspectRatio: 1 + /* TODO: Need Mandatory? */ + + }, options); + + _this._element = opt.element; + _this._initialFov = opt.fov; + _this._enabled = false; + _this._isAnimating = false; + _this._deviceQuaternion = null; + + _this._initAxes(opt); + + _this.option(opt); + + return _this; + } + /** + * Update Pan Scale + * + * Scale(Sensitivity) values of panning is related with fov and height. + * If at least one of them is changed, this function need to be called. + * @param {*} param + */ + + + var __proto = YawPitchControl.prototype; + + __proto.updatePanScale = function (param) { + if (param === void 0) { + param = {}; + } + + var fov = this._axes.get().fov; + + var areaHeight = param.height || parseInt(window.getComputedStyle(this._element).height, 10); + var scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight; + this._axesPanInput.options.scale = [scale, scale]; + this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW; + return this; + }; + /* + * Override component's option method + * to call method for updating values which is affected by option change. + * + * @param {*} args + */ + + + __proto.option = function (key, newValue) { + // Getter + if (!key) { + return this._getOptions(); + } else if (key && typeof key === "string" && typeof newValue === "undefined") { + return this._getOptions(key); + } // Setter + + + var newOptions = {}; + var changedKeyList = []; // TODO: if value is not changed, then do not push on changedKeyList. + + if (typeof key === "string") { + changedKeyList.push(key); + newOptions[key] = newValue; + } else { + var options = key; // Retrieving object here + + changedKeyList = Object.keys(options); + newOptions = __assign({}, options); + } + + this._setOptions(this._getValidatedOptions(newOptions)); + + this._applyOptions(changedKeyList); + + return this; + }; + /** + * Enable YawPitch functionality + * @method eg.YawPitch#enable + */ + + + __proto.enable = function () { + if (this._enabled) { + return this; + } + + this._enabled = true; // touchDirection is decided by parameter is valid string (Ref. Axes.connect) + + this._applyOptions(Object.keys(this.options)); // TODO: Is this code is needed? Check later. + + + this.updatePanScale(); + return this; + }; + /** + * Disable YawPitch functionality + * @method eg.YawPitch#disable + */ + + + __proto.disable = function (persistOrientation) { + if (persistOrientation === void 0) { + persistOrientation = false; + } + + if (!this._enabled) { + return this; + } // TODO: Check peristOrientation is needed! + + + if (!persistOrientation) { + this._resetOrientation(); + } + + this._axes.disconnect(); + + this._enabled = false; + return this; + }; + /** + * Set one or more of yaw, pitch, fov + * @param {Object} coordinate yaw, pitch, fov + * @param {Number} duration Animation duration. if it is above 0 then it's animated. + */ + + + __proto.lookAt = function (_a, duration) { + var yaw = _a.yaw, + pitch = _a.pitch, + fov = _a.fov; + + var pos = this._axes.get(); + + var y = yaw === undefined ? 0 : yaw - pos.yaw; + var p = pitch === undefined ? 0 : pitch - pos.pitch; + var f = fov === undefined ? 0 : fov - pos.fov; // Allow duration of animation to have more than MC_MAXIMUM_DURATION. + + this._axes.options.maximumDuration = Infinity; + + this._axes.setBy({ + yaw: y, + pitch: p, + fov: f + }, duration); + }; + + __proto.getYawPitch = function () { + var yawPitch = this._axes.get(); + + return { + yaw: yawPitch.yaw, + pitch: yawPitch.pitch + }; + }; + + __proto.getFov = function () { + return this._axes.get().fov; + }; + + __proto.getQuaternion = function () { + var pos = this._axes.get(); + + return this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + }; + + __proto.shouldRenderWithQuaternion = function () { + return this.options.gyroMode === GYRO_MODE.VR; + }; + /** + * Destroys objects + */ + + + __proto.destroy = function () { + /* eslint-disable @typescript-eslint/no-unused-expressions */ + this._axes && this._axes.destroy(); + this._axesPanInput && this._axesPanInput.destroy(); + this._axesWheelInput && this._axesWheelInput.destroy(); + this._axesTiltMotionInput && this._axesTiltMotionInput.destroy(); + this._axesPinchInput && this._axesPinchInput.destroy(); + this._axesMoveKeyInput && this._axesMoveKeyInput.destroy(); + this._deviceQuaternion && this._deviceQuaternion.destroy(); + /* eslint-enable @typescript-eslint/no-unused-expressions */ + }; + + __proto._initAxes = function (opt) { + var _this = this; + + var yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio); + + var pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint); + + var useRotation = opt.gyroMode === GYRO_MODE.VR; + this._axesPanInput = new RotationPanInput(this._element, { + useRotation: useRotation + }); + this._axesWheelInput = new Axes.WheelInput(this._element, { + scale: -4 + }); + this._axesTiltMotionInput = null; + this._axesPinchInput = SUPPORT_TOUCH ? new Axes.PinchInput(this._element, { + scale: -1 + }) : null; + this._axesMoveKeyInput = new Axes.MoveKeyInput(this._element, { + scale: [-6, 6] + }); + this._axes = new Axes({ + yaw: { + range: yRange, + circular: this._isCircular(yRange), + bounce: [0, 0] + }, + pitch: { + range: pRange, + circular: this._isCircular(pRange), + bounce: [0, 0] + }, + fov: { + range: opt.fovRange, + circular: [false, false], + bounce: [0, 0] + } + }, { + deceleration: MC_DECELERATION, + maximumDuration: MC_MAXIMUM_DURATION + }, { + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }).on({ + // TODO: change event type after Axes event type inference update + hold: function (evt) { + // Restore maximumDuration not to be spin too mush. + _this._axes.options.maximumDuration = MC_MAXIMUM_DURATION; + + _this.trigger(new Component.ComponentEvent("hold", { + isTrusted: evt.isTrusted + })); + }, + change: function (evt) { + if (evt.delta.fov !== 0) { + _this._updateControlScale(evt); + + _this.updatePanScale(); + } + + _this._triggerChange(evt); + }, + release: function (evt) { + _this._triggerChange(evt); + }, + animationEnd: function (evt) { + _this.trigger(new Component.ComponentEvent("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + }; + + __proto._getValidatedOptions = function (newOptions) { + if (newOptions.yawRange) { + newOptions.yawRange = this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio); + } + + if (newOptions.pitchRange) { + newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov); + } + + return newOptions; + }; + + __proto._getOptions = function (key) { + var value; + + if (typeof key === "string") { + value = this.options[key]; + } else if (arguments.length === 0) { + value = this.options; + } + + return value; + }; + + __proto._setOptions = function (options) { + for (var key in options) { + this.options[key] = options[key]; + } + }; + + __proto._applyOptions = function (keys) { + var options = this.options; + var axes = this._axes; + var isVR = options.gyroMode === GYRO_MODE.VR; + var isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH; // If it's VR mode, restrict user interaction to yaw direction only + + var touchDirection = isVR ? TOUCH_DIRECTION_YAW & options.touchDirection : options.touchDirection; // If one of below is changed, call updateControlScale() + + if (keys.some(function (key) { + return key === "showPolePoint" || key === "fov" || key === "aspectRatio" || key === "yawRange" || key === "pitchRange"; + })) { + // If fov is changed, update pan scale + if (keys.indexOf("fov") >= 0) { + axes.setTo({ + "fov": options.fov + }); + this.updatePanScale(); + } + + this._updateControlScale(); + } + + if (keys.some(function (key) { + return key === "fovRange"; + })) { + var fovRange = options.fovRange; + var prevFov = axes.get().fov; + var nextFov = axes.get().fov; + glMatrix.vec2.copy(axes.axis.fov.range, fovRange); + + if (nextFov < fovRange[0]) { + nextFov = fovRange[0]; + } else if (prevFov > fovRange[1]) { + nextFov = fovRange[1]; + } + + if (prevFov !== nextFov) { + axes.setTo({ + fov: nextFov + }, 0); + + this._updateControlScale(); + + this.updatePanScale(); + } + } + + if (keys.some(function (key) { + return key === "gyroMode"; + }) && SUPPORT_DEVICEMOTION) { + // Disconnect first + if (this._axesTiltMotionInput) { + this._axes.disconnect(this._axesTiltMotionInput); + + this._axesTiltMotionInput.destroy(); + + this._axesTiltMotionInput = null; + } + + if (this._deviceQuaternion) { + this._deviceQuaternion.destroy(); + + this._deviceQuaternion = null; + } + + if (isVR) { + this._initDeviceQuaternion(); + } else if (isYawPitch) { + this._axesTiltMotionInput = new TiltMotionInput(this._element); + + this._axes.connect(["yaw", "pitch"], this._axesTiltMotionInput); + } + + this._axesPanInput.setUseRotation(isVR); + } + + if (keys.some(function (key) { + return key === "useKeyboard"; + })) { + var useKeyboard = options.useKeyboard; + + if (useKeyboard) { + axes.connect(["yaw", "pitch"], this._axesMoveKeyInput); + } else { + axes.disconnect(this._axesMoveKeyInput); + } + } + + if (keys.some(function (key) { + return key === "useZoom"; + })) { + var useZoom = options.useZoom; // Disconnect first + + axes.disconnect(this._axesWheelInput); + + if (useZoom) { + axes.connect(["fov"], this._axesWheelInput); + } + } + + this._togglePinchInputByOption(options.touchDirection, options.useZoom); + + if (keys.some(function (key) { + return key === "touchDirection"; + }) && this._enabled) { + this._enableTouch(touchDirection); + } + }; + + __proto._togglePinchInputByOption = function (touchDirection, useZoom) { + if (this._axesPinchInput) { + // disconnect first + this._axes.disconnect(this._axesPinchInput); // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll. + + + if (useZoom && touchDirection === TOUCH_DIRECTION_ALL && // TODO: Get rid of using private property of axes instance. + this._axes._inputs.indexOf(this._axesPinchInput) === -1) { + this._axes.connect(["fov"], this._axesPinchInput); + } + } + }; + + __proto._enableTouch = function (direction) { + // Disconnect first + if (this._axesPanInput) { + this._axes.disconnect(this._axesPanInput); + } + + var yawEnabled = direction & TOUCH_DIRECTION_YAW ? "yaw" : null; + var pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? "pitch" : null; + + this._axes.connect([yawEnabled, pitchEnabled], this._axesPanInput); + }; + + __proto._initDeviceQuaternion = function () { + var _this = this; + + this._deviceQuaternion = new DeviceQuaternion(); + + this._deviceQuaternion.on("change", function (e) { + _this._triggerChange(e); + }); + }; + + __proto._getValidYawRange = function (newYawRange, newFov, newAspectRatio) { + var ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1); + + var fov = newFov || this._axes.get().fov; + + var horizontalFov = fov * ratio; + var isValid = newYawRange[1] - newYawRange[0] >= horizontalFov; + + if (isValid) { + return newYawRange; + } else { + return this.options.yawRange || DEFAULT_YAW_RANGE; + } + }; + + __proto._getValidPitchRange = function (newPitchRange, newFov) { + var fov = newFov || this._axes.get().fov; + + var isValid = newPitchRange[1] - newPitchRange[0] >= fov; + + if (isValid) { + return newPitchRange; + } else { + return this.options.pitchRange || DEFAULT_PITCH_RANGE; + } + }; + + __proto._isCircular = function (range) { + return range[1] - range[0] < 360 ? [false, false] : [true, true]; + }; + /** + * Update yaw/pitch min/max by 5 factor + * + * 1. showPolePoint + * 2. fov + * 3. yawRange + * 4. pitchRange + * 5. aspectRatio + * + * If one of above is changed, call this function + */ + + + __proto._updateControlScale = function (changeEvt) { + var opt = this.options; + + var fov = this._axes.get().fov; + + var pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint); + + var yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio); // TODO: If not changed!? + + + var pos = this._axes.get(); + + var y = pos.yaw; + var p = pos.pitch; + glMatrix.vec2.copy(this._axes.axis.yaw.range, yRange); + glMatrix.vec2.copy(this._axes.axis.pitch.range, pRange); + this._axes.axis.yaw.circular = this._isCircular(yRange); + this._axes.axis.pitch.circular = this._isCircular(pRange); + /** + * update yaw/pitch by it's range. + */ + + if (y < yRange[0]) { + y = yRange[0]; + } else if (y > yRange[1]) { + y = yRange[1]; + } + + if (p < pRange[0]) { + p = pRange[0]; + } else if (p > pRange[1]) { + p = pRange[1]; + } + + if (changeEvt) { + changeEvt.set({ + yaw: y, + pitch: p + }); + } + + this._axes.setTo({ + yaw: y, + pitch: p + }, 0); + + return this; + }; + + __proto._updatePitchRange = function (pitchRange, fov, showPolePoint) { + if (this.options.gyroMode === GYRO_MODE.VR) { + // Circular pitch on VR + return CIRCULAR_PITCH_RANGE; + } + + var verticalAngle = pitchRange[1] - pitchRange[0]; + var halfFov = fov / 2; + var isPanorama = verticalAngle < 180; + + if (showPolePoint && !isPanorama) { + // Use full pinch range + return pitchRange.concat(); + } // Round value as movableCood do. + + + return [pitchRange[0] + halfFov, pitchRange[1] - halfFov]; + }; + + __proto._updateYawRange = function (yawRange, fov, aspectRatio) { + if (this.options.gyroMode === GYRO_MODE.VR) { + return DEFAULT_YAW_RANGE; + } + + var horizontalAngle = yawRange[1] - yawRange[0]; + /** + * Full 360 Mode + */ + + if (horizontalAngle >= 360) { + // Don't limit yaw range on Full 360 mode. + return yawRange.concat(); + } + /** + * Panorama mode + */ + // Ref : https://github.com/naver/egjs-view360/issues/290 + + + var halfHorizontalFov = util.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.glMatrix.toRadian(fov / 2)))); // Round value as movableCood do. + + return [yawRange[0] + halfHorizontalFov, yawRange[1] - halfHorizontalFov]; + }; // TODO: update param type after Axes event type inference update + + + __proto._triggerChange = function (evt) { + var pos = this._axes.get(); + + var opt = this.options; + var event = { + targetElement: opt.element, + isTrusted: evt.isTrusted, + yaw: pos.yaw, + pitch: pos.pitch, + fov: pos.fov, + quaternion: null + }; + + if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) { + event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + } + + this.trigger(new Component.ComponentEvent("change", event)); + }; // TODO: makes constant to be logic + + + __proto._adjustAspectRatio = function (input) { + var inputRange = [0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670, 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19, 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26, 2.30, 2.60, 3.00, 5.00, 6.00]; + var outputRange = [0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710, 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15, 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72, 1.82, 1.92, 2.00, 2.24, 2.30]; + var rangeIdx = -1; + + for (var i = 0; i < inputRange.length - 1; i++) { + if (inputRange[i] <= input && inputRange[i + 1] >= input) { + rangeIdx = i; + break; + } + } + + if (rangeIdx === -1) { + if (inputRange[0] > input) { + return outputRange[0]; + } else { + // FIXME: this looks definitely wrong + return outputRange[outputRange[0].length - 1]; + } + } + + var inputA = inputRange[rangeIdx]; + var inputB = inputRange[rangeIdx + 1]; + var outputA = outputRange[rangeIdx]; + var outputB = outputRange[rangeIdx + 1]; + return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA)); + }; + + __proto._lerp = function (a, b, fraction) { + return a + fraction * (b - a); + }; + + __proto._resetOrientation = function () { + var opt = this.options; + + this._axes.setTo({ + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }, 0); + + return this; + }; + + YawPitchControl.VERSION = VERSION; // Expose DeviceOrientationControls sub module for test purpose + + YawPitchControl.CONTROL_MODE_VR = CONTROL_MODE_VR; + YawPitchControl.CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH; + YawPitchControl.TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL; + YawPitchControl.TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW; + YawPitchControl.TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH; + YawPitchControl.TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE; + return YawPitchControl; + }(Component); + + /** + * Constant value for errors + * @ko 에러에 대한 상수 값 + * @namespace + * @name ERROR_TYPE + * @memberof eg.view360.PanoViewer + */ + + var ERROR_TYPE = { + /** + * Unsupported device + * @ko 미지원 기기 + * @name INVALID_DEVICE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 10 + */ + INVALID_DEVICE: 10, + + /** + * Webgl not support + * @ko WEBGL 미지원 + * @name NO_WEBGL + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 11 + */ + NO_WEBGL: 11, + + /** + * Failed to load image + * @ko 이미지 로드 실패 + * @name FAIL_IMAGE_LOAD + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 12 + */ + FAIL_IMAGE_LOAD: 12, + + /** + * Failed to bind texture + * @ko 텍스쳐 바인딩 실패 + * @name FAIL_BIND_TEXTURE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 13 + */ + FAIL_BIND_TEXTURE: 13, + + /** + * Only one resource(image or video) should be specified + * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함) + * @name INVALID_RESOURCE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 14 + */ + INVALID_RESOURCE: 14, + + /** + * WebGL context lost occurred + * @ko WebGL context lost 발생 + * @name RENDERING_CONTEXT_LOST + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 15 + */ + RENDERING_CONTEXT_LOST: 15 + }; + /** + * Constant value for events + * @ko 이벤트에 대한 상수 값 + * @namespace + * @name EVENTS + * @memberof eg.view360.PanoViewer + */ + + var PANOVIEWER_EVENTS = { + /** + * Events that is fired when PanoViewer is ready to show image and handle user interaction. + * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트 + * @name READY + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default ready + */ + READY: "ready", + + /** + * Events that is fired when direction or fov is changed. + * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트 + * @name VIEW_CHANGE + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default viewChange + */ + VIEW_CHANGE: "viewChange", + + /** + * Events that is fired when animation which is triggered by inertia is ended. + * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트 + * @name ANIMATION_END + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default animationEnd + */ + ANIMATION_END: "animationEnd", + + /** + * Events that is fired when error occurs + * @ko 에러 발생 시 발생하는 이벤트 + * @name ERROR + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default error + */ + ERROR: "error" + }; + /** + * Constant value for projection type + * @ko 프로젝션 타입 대한 상수 값 + * @namespace + * @name PROJECTION_TYPE + * @memberof eg.view360.PanoViewer + */ + + var PROJECTION_TYPE = { + /** + * Constant value for equirectangular type. + * @ko equirectangular 에 대한 상수 값. + * @name EQUIRECTANGULAR + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default equirectangular + */ + EQUIRECTANGULAR: "equirectangular", + + /** + * Constant value for cubemap type. + * @ko cubemap 에 대한 상수 값. + * @name CUBEMAP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubemap + */ + CUBEMAP: "cubemap", + + /** + * Constant value for cubestrip type. + * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC. + * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다. + * @name CUBESTRIP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubestrip + */ + CUBESTRIP: "cubestrip", + + /** + * Constant value for PANORAMA type. + * + * PANORAMA is a format for a panorma image which is taken from smartphone. + * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다. + * + * @name PANORAMA + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default panorama + */ + PANORAMA: "panorama", + + /** + * Constant value for EQUI_STEREOSCOPY type. + * + * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present. + * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다. + * + * @name STEREOSCOPIC_EQUI + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default stereoequi + */ + STEREOSCOPIC_EQUI: "stereoequi" + }; + /** + * A constant value for the format of the stereoscopic equirectangular projection type. + * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값 + * @namespace + * @name STEREO_FORMAT + * @memberof eg.view360.PanoViewer + */ + + var STEREO_FORMAT = { + /** + * A constant value for format of top bottom stereoscopic 360 equirectangular projection. + * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name TOP_BOTTOM + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dv" + */ + TOP_BOTTOM: "3dv", + + /** + * A constant value for format of left right stereoscopic 360 equirectangular projection. + * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name LEFT_RIGHT + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dh" + */ + LEFT_RIGHT: "3dh", + + /** + * A constant value specifying media is not in stereoscopic format. + * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값. + * @name NONE + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "" + */ + NONE: "" + }; // eslint-disable-next-line @typescript-eslint/no-unused-vars + + var PANOVIEWER_OPTIONS = { + image: true, + video: true, + projectionType: true, + cubemapConfig: true, + stereoFormat: true, + width: true, + height: true, + yaw: true, + pitch: true, + fov: true, + showPolePoint: true, + useZoom: true, + useKeyboard: true, + gyroMode: true, + yawRange: true, + pitchRange: true, + fovRange: true, + touchDirection: true, + canvasClass: true + }; + var DEFAULT_CANVAS_CLASS = "view360-canvas"; + + var merge = function (target) { + var srcs = []; + + for (var _i = 1; _i < arguments.length; _i++) { + srcs[_i - 1] = arguments[_i]; + } + + srcs.forEach(function (source) { + Object.keys(source).forEach(function (key) { + var value = source[key]; + + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = __spread(target[key], value); + } else { + target[key] = value; + } + }); + }); + return target; + }; + var toImageElement = function (image) { + var images = image instanceof Array ? image : [image]; + var parsedImages = images.map(function (img) { + var imgEl = img; + + if (typeof img === "string") { + imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = img; + } + + return imgEl; + }); + return parsedImages.length === 1 ? parsedImages[0] : parsedImages; + }; + var toVideoElement = function (videoCandidate) { + if (videoCandidate instanceof HTMLVideoElement) { + return videoCandidate; + } else { + // url + var video_1 = document.createElement("video"); + video_1.setAttribute("crossorigin", "anonymous"); + video_1.setAttribute("webkit-playsinline", ""); + video_1.setAttribute("playsinline", ""); + + if (videoCandidate instanceof Array) { + videoCandidate.forEach(function (v) { + return appendSourceElement(video_1, v); + }); + } else { + appendSourceElement(video_1, videoCandidate); + } + + var sourceCount = video_1.querySelectorAll("source").length; + + if (sourceCount > 0) { + if (video_1.readyState < 1) { + video_1.load(); + } + } + + return video_1; + } + }; + /** + * + * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src} + */ + + var appendSourceElement = function (video, videoUrl) { + var videoSrc; + var videoType; + + if (typeof videoUrl === "object") { + videoSrc = videoUrl.src; + videoType = videoUrl.type; + } else if (typeof videoUrl === "string") { + videoSrc = videoUrl; + } + + if (!videoSrc) { + return false; + } + + var sourceElement = document.createElement("source"); + sourceElement.src = videoSrc; + + if (videoType) { + sourceElement.type = videoType; + } + + video.appendChild(sourceElement); + }; + + var WEBGL_ERROR_CODE = { + "0": "NO_ERROR", + "1280": "INVALID_ENUM", + "1281": "INVALID_VALUE", + "1282": "INVALID_OPERATION", + "1285": "OUT_OF_MEMORY", + "1286": "INVALID_FRAMEBUFFER_OPERATION", + "37442": "CONTEXT_LOST_WEBGL" + }; + var webglAvailability = null; // eslint-disable-next-line @typescript-eslint/naming-convention + + var WebGLUtils = + /*#__PURE__*/ + function () { + function WebGLUtils() {} + + WebGLUtils.createShader = function (gl, type, source) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + + if (success) { + return shader; + } // eslint-disable-next-line + + + console.error(gl.getShaderInfoLog(shader)); + return null; + }; + + WebGLUtils.createProgram = function (gl, vertexShader, fragmentShader) { + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + var success = gl.getProgramParameter(program, gl.LINK_STATUS); + + if (success) { + return program; + } + + gl.deleteProgram(program); + return null; + }; + + WebGLUtils.initBuffer = function (gl, target + /* bind point */ + , data, itemSize, attr) { + var buffer = gl.createBuffer(); + gl.bindBuffer(target, buffer); + gl.bufferData(target, data, gl.STATIC_DRAW); + + if (buffer) { + buffer.itemSize = itemSize; + buffer.numItems = data.length / itemSize; + } + + if (attr !== undefined) { + gl.enableVertexAttribArray(attr); + gl.vertexAttribPointer(attr, buffer.itemSize, gl.FLOAT, false, 0, 0); + } + + return buffer; + }; + + WebGLUtils.getWebglContext = function (canvas, userContextAttributes) { + var e_1, _a; + + var webglIdentifiers = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + var context = null; + + var contextAttributes = __assign({ + preserveDrawingBuffer: false, + antialias: false + }, userContextAttributes); + + var onWebglcontextcreationerror = function (e) { + return e.statusMessage; + }; + + canvas.addEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + + try { + for (var webglIdentifiers_1 = __values(webglIdentifiers), webglIdentifiers_1_1 = webglIdentifiers_1.next(); !webglIdentifiers_1_1.done; webglIdentifiers_1_1 = webglIdentifiers_1.next()) { + var identifier = webglIdentifiers_1_1.value; + + try { + context = canvas.getContext(identifier, contextAttributes); + } catch (t) {} // eslint-disable-line no-empty + + + if (context) { + break; + } + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (webglIdentifiers_1_1 && !webglIdentifiers_1_1.done && (_a = webglIdentifiers_1.return)) _a.call(webglIdentifiers_1); + } finally { + if (e_1) throw e_1.error; + } + } + + canvas.removeEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + return context; + }; + + WebGLUtils.createTexture = function (gl, textureTarget) { + var texture = gl.createTexture(); + gl.bindTexture(textureTarget, texture); + gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindTexture(textureTarget, null); + return texture; + }; + /** + * Returns the webgl availability of the current browser. + * @method WebGLUtils#isWebGLAvailable + * @retuen {Boolean} isWebGLAvailable + */ + + + WebGLUtils.isWebGLAvailable = function () { + if (webglAvailability === null) { + var canvas = document.createElement("canvas"); + var webglContext = WebGLUtils.getWebglContext(canvas); + webglAvailability = !!webglContext; // webglContext Resource forced collection + + if (webglContext) { + var loseContextExtension = webglContext.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + } + + return !!webglAvailability; + }; + /** + * Returns whether webgl is stable in the current browser. + * @method WebGLUtils#isStableWebGL + * @retuen {Boolean} isStableWebGL + */ + + + WebGLUtils.isStableWebGL = function () { + var agentInfo = agent$1(); + var isStableWebgl = true; + + if (agentInfo.os.name === "android") { + var version = parseFloat(agentInfo.os.version); + + if (version <= 4.3 && version >= 1) { + isStableWebgl = false; + } else if (version === 4.4) { + if (agentInfo.browser.name !== "chrome") { + isStableWebgl = false; + } + } + } + + return isStableWebgl; + }; + + WebGLUtils.getErrorNameFromWebGLErrorCode = function (code) { + if (!(code in WEBGL_ERROR_CODE)) { + return "UNKNOWN_ERROR"; + } + + return WEBGL_ERROR_CODE[code]; + }; + /** + * This function is wrapper for texImage2D to handle exceptions on texImage2D. + * Purpose is to prevent service from being stopped by script error. + */ + + + WebGLUtils.texImage2D = function (gl, target, pixels) { + try { + gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + } catch (error) { + /* eslint-disable no-console */ + console.error("WebGLUtils.texImage2D error:", error); + /* eslint-enable no-console */ + } + }; + + WebGLUtils.getMaxTextureSize = function (gl) { + // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test + return gl.getParameter(gl.MAX_TEXTURE_SIZE); + }; + + return WebGLUtils; + }(); + + var agentInfo = agent$1(); + var isIE11 = agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11; + var EVENTS = { + ERROR: "error" + }; + /** + * + * Extends Component for firing errors occurs internally. + */ + + var Renderer = + /*#__PURE__*/ + function (_super) { + __extends(Renderer, _super); + + function Renderer() { + var _this = _super.call(this) || this; + + _this._forceDimension = null; + _this._pixelCanvas = null; + _this._pixelContext = null; + return _this; + } + + var __proto = Renderer.prototype; + + __proto.render = function (_a) { + var gl = _a.gl, + shaderProgram = _a.shaderProgram, + indexBuffer = _a.indexBuffer, + mvMatrix = _a.mvMatrix, + pMatrix = _a.pMatrix; + gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); + gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); + + if (indexBuffer) { + gl.drawElements(gl.TRIANGLES, indexBuffer.numItems, gl.UNSIGNED_SHORT, 0); + } + }; // Define interface for Renderers + + /** + * Following MUST BE DEFINED on Child of Renderer + * + * DATA + * + * - getVertexPositionData + * - getIndexData + * - getTextureCoordData + * + * SOURCE + * + * - getVertexShaderSource + * - getFragmentShaderSource + * + * TEXTURE + * + * - bindTexture + */ + + + __proto.getDimension = function (pixelSource) { + var width = pixelSource.naturalWidth || pixelSource.videoWidth; + var height = pixelSource.naturalHeight || pixelSource.videoHeight; + return { + width: width, + height: height + }; + }; + /** + * Update data used by shader + */ + + + __proto.updateShaderData = function (param) { + /* + * Update following data in implementation layer. + * If the data is not changed, it does not need to implement this function. + * + * - _VERTEX_POSITION_DATA + * - _TEXTURE_COORD_DATA + * - _INDEX_DATA + */ + }; + /** + * + * @param {HTMLImageElement | HTMLVideoElement} image + * @param {Object = {width, height}} forceDimension Forced dimension to resize + */ + + + __proto._initPixelSource = function (image, forceDimension) { + if (forceDimension === void 0) { + forceDimension = null; + } + + var isIE11Video = isIE11 && image instanceof HTMLVideoElement; + + if (isIE11Video || forceDimension) { + var _a = forceDimension || this.getDimension(image), + width = _a.width, + height = _a.height; + + this._pixelCanvas = document.createElement("canvas"); + this._pixelCanvas.width = width; + this._pixelCanvas.height = height; + this._pixelContext = this._pixelCanvas.getContext("2d"); + } + + this._forceDimension = forceDimension; + }; + + __proto._getPixelSource = function (image) { + if (!this._pixelCanvas) { + return image; + } + /** + * IE11 && Video + * or + * Dimension is forced (Image is larger than texture size.) + */ + + + var contentDimension = this.getDimension(image); + var textureDimension = this._forceDimension || contentDimension; + + if (this._pixelCanvas.width !== textureDimension.width) { + this._pixelCanvas.width = textureDimension.width; + } + + if (this._pixelCanvas.height !== textureDimension.height) { + this._pixelCanvas.height = textureDimension.height; + } + + if (this._forceDimension) { + this._pixelContext.drawImage(image, 0, 0, contentDimension.width, contentDimension.height, 0, 0, textureDimension.width, textureDimension.height); + } else { + this._pixelContext.drawImage(image, 0, 0); + } + + return this._pixelCanvas; + }; + + __proto._extractTileConfig = function (imageConfig) { + var tileConfig = Array.isArray(imageConfig.tileConfig) ? imageConfig.tileConfig : Array.apply(void 0, __spread(Array(6))).map(function () { + return imageConfig.tileConfig; + }); + tileConfig = tileConfig.map(function (config) { + return __assign({ + flipHorizontal: false, + rotation: 0 + }, config); + }); + return tileConfig; + }; + + __proto._triggerError = function (error) { + /* eslint-disable no-console */ + console.error("Renderer Error:", error); + /* eslint-enable no-console */ + + this.trigger(new Component.ComponentEvent(EVENTS.ERROR, { + message: typeof error === "string" ? error : error.message + })); + }; + + Renderer.EVENTS = EVENTS; + return Renderer; + }(Component); + + var CubeRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CubeRenderer, _super); + + function CubeRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeRenderer.prototype; + + CubeRenderer.extractOrder = function (imageConfig) { + return imageConfig.order || "RLUDBF"; + }; + + __proto.getVertexPositionData = function () { + CubeRenderer._VERTEX_POSITION_DATA = CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // top + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // bottom + 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + return CubeRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + if (CubeRenderer._INDEX_DATA) { + return CubeRenderer._INDEX_DATA; + } + + var indexData = []; + var vertexPositionData = this.getVertexPositionData(); + + for (var i = 0; i < vertexPositionData.length / 3; i += 4) { + indexData.push(i, i + 2, i + 1, i, i + 3, i + 2); + } + + CubeRenderer._INDEX_DATA = indexData; + return indexData; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; + var vertexOrder = "BFUDRL"; + var order = CubeRenderer.extractOrder(imageConfig); + var base = this.getVertexPositionData(); + + var tileConfig = this._extractTileConfig(imageConfig); + + var elemSize = 3; + var vertexPerTile = 4; + var trim = imageConfig.trim; + var texCoords = vertexOrder.split("").map(function (face) { + return tileConfig[order.indexOf(face)]; + }).map(function (config, i) { + var rotation = Math.floor(config.rotation / 90); + var ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2]; + + for (var r = 0; r < Math.abs(rotation); r++) { + if (config.flipHorizontal && rotation > 0 || !config.flipHorizontal && rotation < 0) { + ordermap.push(ordermap.shift()); + } else { + ordermap.unshift(ordermap.pop()); + } + } + + var elemPerTile = elemSize * vertexPerTile; + var tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile); + var tileTemp = []; + + for (var j = 0; j < vertexPerTile; j++) { + tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize); + } + + return tileTemp; + }).map(function (coord) { + return _this._shrinkCoord({ + image: image, + faceCoords: coord, + trim: trim + }); + }).reduce(function (acc, val) { + return __spread(acc, val.reduce(function (coords, coord) { + return __spread(coords, coord); + }, [])); + }, []); + return texCoords; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}"; + }; + + __proto.updateTexture = function (gl, image, imageConfig) { + var baseOrder = "RLUDBF"; + var order = CubeRenderer.extractOrder(imageConfig); + var orderMap = {}; + order.split("").forEach(function (v, i) { + orderMap[v] = i; + }); + + try { + if (image instanceof Array) { + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]); + } + } else { + var maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image); + + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + var tile = this.extractTileFromImage(image, tileIdx, maxCubeMapTextureSize); + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile); + } + } + } catch (e) { + this._triggerError(e); + } + }; + + __proto.bindTexture = function (gl, texture, image, imageConfig) { + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + this.updateTexture(gl, image, imageConfig); + }; + + __proto.getSourceTileSize = function (image) { + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var aspectRatio = width / height; + var inputTextureSize; + + if (aspectRatio === 1 / 6) { + inputTextureSize = width; + } else if (aspectRatio === 6) { + inputTextureSize = height; + } else if (aspectRatio === 2 / 3) { + inputTextureSize = width / 2; + } else { + inputTextureSize = width / 3; + } + + return inputTextureSize; + }; + + __proto.extractTileFromImage = function (image, tileIdx, outputTextureSize) { + var width = this.getDimension(image).width; + var inputTextureSize = this.getSourceTileSize(image); + var canvas = document.createElement("canvas"); + canvas.width = outputTextureSize; + canvas.height = outputTextureSize; + var context = canvas.getContext("2d"); + var tilePerRow = width / inputTextureSize; + var x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow); + var y = Math.floor(tileIdx / tilePerRow) * inputTextureSize; + context.drawImage(image, x, y, inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize); + return canvas; + }; + + __proto.getMaxCubeMapTextureSize = function (gl, image) { + var agentInfo = agent$1(); + var maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); + var imageWidth = this.getSourceTileSize(image); + + if (agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11) { + if (!util.isPowerOfTwo(imageWidth)) { + for (var i = 1; i < maxCubeMapTextureSize; i *= 2) { + if (i < imageWidth) { + continue; + } else { + imageWidth = i; + break; + } + } + } + } + + if (agentInfo.os.name === "ios") { + var majorVersion = agentInfo.os.majorVersion; // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다. + + if (majorVersion === 9) { + imageWidth = 1024; + } // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다. + + + if (majorVersion === 8) { + imageWidth = 512; + } + } // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수 + + + return Math.min(maxCubeMapTextureSize, imageWidth); + }; + + __proto._shrinkCoord = function (coordData) { + var image = coordData.image, + faceCoords = coordData.faceCoords, + trim = coordData.trim; + var inputTextureSize = Array.isArray(image) ? this.getDimension(image[0]).width : this.getSourceTileSize(image); // Shrink by "trim" px + + var SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize); + var axisMultipliers = [0, 1, 2].map(function (axisIndex) { + var axisDir = util.sign(faceCoords[0][axisIndex]); + var notSameDir = faceCoords.some(function (coord) { + return util.sign(coord[axisIndex]) !== axisDir; + }); + return notSameDir; + }).map(function (notSameDir) { + return notSameDir ? SHRINK_MULTIPLIER : 1; + }); + return faceCoords.map(function (coords) { + return coords.map(function (coord, axisIndex) { + return coord * axisMultipliers[axisIndex]; + }); + }); + }; + + CubeRenderer._VERTEX_POSITION_DATA = null; + CubeRenderer._INDEX_DATA = null; + return CubeRenderer; + }(Renderer); + + var CubeStripRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CubeStripRenderer, _super); + + function CubeStripRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeStripRenderer.prototype; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"; + }; + + __proto.getVertexPositionData = function () { + if (!this._vertices) { + this._vertices = [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + } + + return this._vertices; + }; + + __proto.getIndexData = function () { + var _this = this; // TODO: 한번만 계산하도록 수정하기 + + + var indices = function () { + var indexData = []; + + for (var i = 0; i < _this._vertices.length / 3; i += 4) { + indexData.push(i, i + 1, i + 2, i, i + 2, i + 3); + } + + return indexData; + }(); + + return indices; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; // TODO: make it cols, rows as config. + + var cols = 3; + var rows = 2; + var textureSize = this.getDimension(image); + var trim = imageConfig.trim; + var order = imageConfig.order || "RLUDFB"; + var coords = []; // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다. + + for (var r = rows - 1; r >= 0; r--) { + for (var c = 0; c < cols; c++) { + var coord = [c / cols, r / rows, (c + 1) / cols, r / rows, (c + 1) / cols, (r + 1) / rows, c / cols, (r + 1) / rows]; + coords.push(coord); + } + } + + var tileConfigs = this._extractTileConfig(imageConfig); // Transform Coord By Flip & Rotation + + + coords = coords // shrink coord to avoid pixel bleeding + .map(function (coord) { + return _this._shrinkCoord(coord, textureSize, trim); + }).map(function (coord, i) { + return _this._transformCoord(coord, tileConfigs[i]); + }); // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치 + + return "BFUDRL".split("").map(function (face) { + return order.indexOf(face); + }).map(function (index) { + return coords[index]; + }).reduce(function (acc, val) { + return acc.concat(val); + }, []); + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto._transformCoord = function (coord, tileConfig) { + var newCoord = coord.slice(); + + if (tileConfig.flipHorizontal) { + newCoord = this._flipHorizontalCoord(newCoord); + } + + if (tileConfig.rotation) { + newCoord = this._rotateCoord(newCoord, tileConfig.rotation); + } + + return newCoord; + }; + + __proto._shrinkCoord = function (coord, textureSize, trim) { + var width = textureSize.width, + height = textureSize.height; // Shrink by "trim" px + + var SHRINK_Y = trim * (1 / height); + var SHRINK_X = trim * (1 / width); + return [coord[0] + SHRINK_X, coord[1] + SHRINK_Y, coord[2] - SHRINK_X, coord[3] + SHRINK_Y, coord[4] - SHRINK_X, coord[5] - SHRINK_Y, coord[6] + SHRINK_X, coord[7] - SHRINK_Y]; + }; + + __proto._rotateCoord = function (coord, rotationAngle) { + var SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord. + + var shiftCount = Math.floor(rotationAngle / 90) % 4; + + if (shiftCount === 0) { + return coord; + } + + var moved; + var rotatedCoord = []; + + if (shiftCount > 0) { + moved = coord.splice(0, shiftCount * SIZE); + rotatedCoord = coord.concat(moved); + } else { + moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE); + rotatedCoord = moved.concat(coord); + } + + return rotatedCoord; + }; + + __proto._flipHorizontalCoord = function (coord) { + return [coord[2], coord[3], coord[0], coord[1], coord[6], coord[7], coord[4], coord[5]]; + }; + + return CubeStripRenderer; + }(Renderer); + + var latitudeBands = 60; + var longitudeBands = 60; + var radius = 2; + var ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + var textureCoordData = []; + var vertexPositionData = []; + var indexData = []; + var latIdx; + var lngIdx; + + for (latIdx = 0; latIdx <= latitudeBands; latIdx++) { + var theta = (latIdx / latitudeBands - 0.5) * Math.PI; + var sinTheta = Math.sin(theta); + var cosTheta = Math.cos(theta); + + for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) { + var phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + var sinPhi = Math.sin(phi); + var cosPhi = Math.cos(phi); + var x = cosPhi * cosTheta; + var y = sinTheta; + var z = sinPhi * cosTheta; + var u = lngIdx / longitudeBands; + var v = latIdx / latitudeBands; + textureCoordData.push(u, v); + vertexPositionData.push(radius * x, radius * y, radius * z); + + if (lngIdx !== longitudeBands && latIdx !== latitudeBands) { + var a = latIdx * (longitudeBands + 1) + lngIdx; + var b = a + longitudeBands + 1; + indexData.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + + var SphereRenderer = + /*#__PURE__*/ + function (_super) { + __extends(SphereRenderer, _super); + + function SphereRenderer(format) { + var _this = _super.call(this) || this; + + _this._stereoFormat = format; + return _this; + } + + var __proto = SphereRenderer.prototype; + + __proto.render = function (ctx) { + var gl = ctx.gl, + shaderProgram = ctx.shaderProgram; + var leftEyeScaleOffset; + var rightEyeScaleOffset; + + switch (this._stereoFormat) { + case STEREO_FORMAT.TOP_BOTTOM: + leftEyeScaleOffset = [1, 0.5, 0, 0]; + rightEyeScaleOffset = [1, 0.5, 0, 0.5]; + break; + + case STEREO_FORMAT.LEFT_RIGHT: + leftEyeScaleOffset = [0.5, 1, 0, 0]; + rightEyeScaleOffset = [0.5, 1, 0.5, 0]; + break; + + default: + leftEyeScaleOffset = [1, 1, 0, 0]; + rightEyeScaleOffset = [1, 1, 0, 0]; + } + + var uTexScaleOffset = gl.getUniformLocation(shaderProgram, "uTexScaleOffset"); + gl.uniform4fv(uTexScaleOffset, __spread(leftEyeScaleOffset, rightEyeScaleOffset)); + + _super.prototype.render.call(this, ctx); + }; + + __proto.getVertexPositionData = function () { + return SphereRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return SphereRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return SphereRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + SphereRenderer._VERTEX_POSITION_DATA = vertexPositionData; + SphereRenderer._TEXTURE_COORD_DATA = textureCoordData; + SphereRenderer._INDEX_DATA = indexData; + return SphereRenderer; + }(Renderer); + + var MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6; + var longitudeBands$1 = 60; + var textureCoordData$1 = []; + var vertexPositionData$1 = []; + var indexData$1 = []; + + var CylinderRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CylinderRenderer, _super); + + function CylinderRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CylinderRenderer.prototype; + + __proto.getVertexPositionData = function () { + return CylinderRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return CylinderRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return CylinderRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + var resizeDimension; + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device texture limit(" + maxSize + "))"); // Request resizing texture. + + /** + * TODO: Is it need to apply on another projection type? + */ + + + resizeDimension = width > height ? { + width: maxSize, + height: maxSize * height / width + } : { + width: maxSize * width / height, + height: maxSize + }; + } // Pixel Source for IE11 & Video or resizing needed + + + this._initPixelSource(image, resizeDimension); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto.updateShaderData = function (_a) { + var _b = _a.imageAspectRatio, + imageAspectRatio = _b === void 0 ? MIN_ASPECT_RATIO_FOR_FULL_PANORAMA : _b; + var lngIdx; + var cylinderMaxRadian; + var halfCylinderY; + var rotated; + var aspectRatio; // Exception case: orientation is rotated. + + if (imageAspectRatio < 1) { + /** + * If rotated is true, we assume that image is rotated counter clockwise. + * TODO: If there's other rotation, it is need to implement by each rotation. + */ + rotated = true; + aspectRatio = 1 / imageAspectRatio; + } else { + rotated = false; + aspectRatio = imageAspectRatio; + } + + if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) { + var fov = 360 / aspectRatio; + cylinderMaxRadian = 2 * Math.PI; // 360 deg + + halfCylinderY = Math.tan(glMatrix.glMatrix.toRadian(fov / 2)); + } else { + cylinderMaxRadian = aspectRatio; + halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1. + } // initialize shader data before update + + + textureCoordData$1.length = 0; + vertexPositionData$1.length = 0; + indexData$1.length = 0; + var CYLIDER_Y = [-halfCylinderY, halfCylinderY]; + var startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360) + // console.log("cylinderMaxRadian:", glMatrix.toDegree(cylinderMaxRadian), "CYLIDER_Y", CYLIDER_Y, "start angle", glMatrix.toDegree(startAngleForCenterAlign)); + + for (var yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength + /* bottom & top */ + ; yIdx++) { + for (lngIdx = 0; lngIdx <= longitudeBands$1; lngIdx++) { + var angle = startAngleForCenterAlign + lngIdx / longitudeBands$1 * cylinderMaxRadian; + var x = Math.cos(angle); + var y = CYLIDER_Y[yIdx]; + var z = Math.sin(angle); + var u = void 0; + var v = void 0; + + if (rotated) { + // Rotated 90 degree (counter clock wise) + u = 1 - yIdx; // yLength - yIdx; + + v = lngIdx / longitudeBands$1; + } else { + // // Normal case (Not rotated) + u = lngIdx / longitudeBands$1; + v = yIdx; + } + + textureCoordData$1.push(u, v); + vertexPositionData$1.push(x, y, z); + + if (yIdx === 0 && lngIdx < longitudeBands$1) { + var a = lngIdx; + var b = a + longitudeBands$1 + 1; + indexData$1.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + }; + + CylinderRenderer._VERTEX_POSITION_DATA = vertexPositionData$1; + CylinderRenderer._TEXTURE_COORD_DATA = textureCoordData$1; + CylinderRenderer._INDEX_DATA = indexData$1; + return CylinderRenderer; + }(Renderer); + + var VR_DISPLAY_PRESENT_CHANGE = "vrdisplaypresentchange"; + var DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1]; + var DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1]; + var EYES = { + LEFT: "left", + RIGHT: "right" + }; + + var VRManager = + /*#__PURE__*/ + function () { + function VRManager() { + var _this = this; + + this.destroy = function () { + var vrDisplay = _this._vrDisplay; + + _this.removeEndCallback(_this.destroy); + + if (vrDisplay && vrDisplay.isPresenting) { + void vrDisplay.exitPresent(); + } + + _this._clear(); + }; + + this._frameData = new window.VRFrameData(); + + this._clear(); + } + + var __proto = VRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._vrDisplay; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function () { + return Boolean(this._vrDisplay); + }; + + __proto.beforeRender = function (gl) { + // Render to the default backbuffer + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + }; + + __proto.afterRender = function () { + this._vrDisplay.submitFrame(); + }; + + __proto.getEyeParams = function (gl) { + var display = this._vrDisplay; + var halfWidth = gl.drawingBufferWidth * 0.5; + var height = gl.drawingBufferHeight; + var frameData = this._frameData; + display.getFrameData(frameData); + var leftMVMatrix = frameData.leftViewMatrix; + var rightMVMatrix = frameData.rightViewMatrix; + glMatrix.mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset); + glMatrix.mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset); + return [{ + viewport: [0, 0, halfWidth, height], + mvMatrix: leftMVMatrix, + pMatrix: frameData.leftProjectionMatrix + }, { + viewport: [halfWidth, 0, halfWidth, height], + mvMatrix: rightMVMatrix, + pMatrix: frameData.rightProjectionMatrix + }]; + }; + + __proto.isPresenting = function () { + return Boolean(this._vrDisplay && this._vrDisplay.isPresenting); + }; + + __proto.addEndCallback = function (callback) { + window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.removeEndCallback = function (callback) { + window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.requestPresent = function (canvas) { + var _this = this; + + return navigator.getVRDisplays().then(function (displays) { + var vrDisplay = displays.length && displays[0]; + + if (!vrDisplay) { + return Promise$1.reject(new Error("No displays available.")); + } + + if (!vrDisplay.capabilities.canPresent) { + return Promise$1.reject(new Error("Display lacking capability to present.")); + } + + return vrDisplay.requestPresent([{ + source: canvas + }]).then(function () { + var leftEye = vrDisplay.getEyeParameters(EYES.LEFT); + var rightEye = vrDisplay.getEyeParameters(EYES.RIGHT); + canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2; + canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight); + + _this._setDisplay(vrDisplay); + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setDisplay = function (vrDisplay) { + this._vrDisplay = vrDisplay; + var layers = vrDisplay.getLayers(); + + if (layers.length) { + var layer = layers[0]; + this._leftBounds = layer.leftBounds; + this._rightBounds = layer.rightBounds; + } + + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._vrDisplay = null; + this._leftBounds = DEFAULT_LEFT_BOUNDS; + this._rightBounds = DEFAULT_RIGHT_BOUNDS; + this._yawOffset = 0; + }; + + return VRManager; + }(); + + var XR_REFERENCE_SPACE = "local"; + + var XRManager = + /*#__PURE__*/ + function () { + function XRManager(options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + this.destroy = function () { + var xrSession = _this._xrSession; + + _this.removeEndCallback(_this.destroy); + + if (xrSession) { + // Capture to avoid errors + xrSession.end().then(function () { + return void 0; + }, function () { + return void 0; + }); + } + + _this._clear(); + }; + + this._clear(); + + this._options = options; + } + + var __proto = XRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._xrSession; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function (frame) { + var pose = frame.getViewerPose(this._xrRefSpace); + return Boolean(pose); + }; + + __proto.beforeRender = function (gl, frame) { + var session = frame.session; + var baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + }; // eslint-disable-next-line @typescript-eslint/no-empty-function + + + __proto.afterRender = function () {}; + + __proto.getEyeParams = function (gl, frame) { + var _this = this; + + var session = frame.session; + var pose = frame.getViewerPose(this._xrRefSpace); + + if (!pose) { + // Can't render + return null; + } + + var glLayer = session.renderState.baseLayer; + return pose.views.map(function (view) { + var viewport = glLayer.getViewport(view); + var mvMatrix = view.transform.inverse.matrix; + + if (IS_SAFARI_ON_DESKTOP) { + glMatrix.mat4.rotateX(mvMatrix, mvMatrix, glMatrix.glMatrix.toRadian(180)); + } + + glMatrix.mat4.rotateY(mvMatrix, mvMatrix, _this._yawOffset); + return { + viewport: [viewport.x, viewport.y, viewport.width, viewport.height], + mvMatrix: mvMatrix, + pMatrix: view.projectionMatrix + }; + }); + }; + + __proto.isPresenting = function () { + return this._presenting; + }; + + __proto.addEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.addEventListener("end", callback); + }; + + __proto.removeEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.removeEventListener("end", callback); + }; + + __proto.requestPresent = function (canvas, gl) { + return __awaiter(this, void 0, void 0, function () { + var options, attributes; + + var _this = this; + + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = merge({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + attributes = gl.getContextAttributes(); + if (!(attributes && attributes.xrCompatible !== true)) return [3 + /*break*/ + , 2]; + return [4 + /*yield*/ + , gl.makeXRCompatible()]; + + case 1: + _a.sent(); + + _a.label = 2; + + case 2: + return [2 + /*return*/ + , navigator.xr.requestSession("immersive-vr", options).then(function (session) { + var xrLayer = new window.XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + return session.requestReferenceSpace(XR_REFERENCE_SPACE).then(function (refSpace) { + _this._setSession(session, xrLayer, refSpace); + }); + })]; + } + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setSession = function (session, xrLayer, refSpace) { + this._xrSession = session; + this._xrLayer = xrLayer; + this._xrRefSpace = refSpace; + this._presenting = true; + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._xrSession = null; + this._xrLayer = null; + this._xrRefSpace = null; + this._presenting = false; + this._yawOffset = 0; + this._options = {}; + }; + + return XRManager; + }(); + + var WebGLAnimator = + /*#__PURE__*/ + function () { + function WebGLAnimator() { + var _this = this; + /** + * There can be more than 1 argument when we use XRSession's raf + */ + + + this._onLoop = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + _this._callback.apply(_this, __spread(args)); + + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + }; + /** + * MacOS X Safari Bug Fix + * This code guarantees that rendering should be occurred. + * + * In MacOS X(10.14.2), Safari (12.0.2) + * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term + * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms) + * So browser cannot render the frame and may be freezing. + */ + + + this._onLoopNextTick = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + var before = performance.now(); + + _this._callback.apply(_this, __spread(args)); + + var diff = performance.now() - before; + + if (_this._rafTimer >= 0) { + clearTimeout(_this._rafTimer); + _this._rafTimer = -1; + } + /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */ + + + if (diff < 16) { + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + } else { + /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */ + _this._rafTimer = window.setTimeout(_this._onLoop, 0); + } + }; + + this._callback = null; + this._context = window; + this._rafId = -1; + this._rafTimer = -1; + } + + var __proto = WebGLAnimator.prototype; + + __proto.setCallback = function (callback) { + this._callback = callback; + }; + + __proto.setContext = function (context) { + this._context = context; + }; + + __proto.start = function () { + var context = this._context; + var callback = this._callback; // No context / callback set + + if (!context || !callback) return; // Animation already started + + if (this._rafId >= 0 || this._rafTimer >= 0) return; + + if (IS_SAFARI_ON_DESKTOP) { + this._rafId = context.requestAnimationFrame(this._onLoopNextTick); + } else { + this._rafId = context.requestAnimationFrame(this._onLoop); + } + }; + + __proto.stop = function () { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + + this._rafId = -1; + this._rafTimer = -1; + }; + + return WebGLAnimator; + }(); + + var ImageType = PROJECTION_TYPE; // eslint-disable-next-line @typescript-eslint/naming-convention + + var DEVICE_PIXEL_RATIO = devicePixelRatio || 1; // DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다. + + if (DEVICE_PIXEL_RATIO > 2) { + DEVICE_PIXEL_RATIO = 2; + } // define custom events name + + /** + * TODO: how to manage events/errortype with PanoViewer + * + * I think renderer events should be seperated from viewer events although it has same name. + */ + + + var EVENTS$1 = { + BIND_TEXTURE: "bindTexture", + IMAGE_LOADED: "imageLoaded", + ERROR: "error", + RENDERING_CONTEXT_LOST: "renderingContextLost", + RENDERING_CONTEXT_RESTORE: "renderingContextRestore" + }; + var ERROR_TYPE$1 = { + INVALID_DEVICE: 10, + NO_WEBGL: 11, + FAIL_IMAGE_LOAD: 12, + RENDERER_ERROR: 13 + }; + + var PanoImageRenderer = + /*#__PURE__*/ + function (_super) { + __extends(PanoImageRenderer, _super); + + function PanoImageRenderer(image, width, height, isVideo, container, canvasClass, sphericalConfig, renderingContextAttributes) { + var _this = // Super constructor + _super.call(this) || this; + + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + + _this.exitVR = function () { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; + if (!vr) return; + vr.removeEndCallback(_this.exitVR); + vr.destroy(); + _this._vr = null; // Restore canvas & context on iOS + + if (IS_IOS) { + _this._restoreStyle(); + } + + _this.updateViewportDimensions(_this.width, _this.height); + + _this._updateViewport(); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + _this._bindBuffers(); + + _this._shouldForceDraw = true; + animator.stop(); + animator.setContext(window); + animator.setCallback(_this._render.bind(_this)); + animator.start(); + }; + + _this._renderStereo = function (time, frame) { + var e_1, _a; + + var vr = _this._vr; + var gl = _this.context; + var eyeParams = vr.getEyeParams(gl, frame); + if (!eyeParams) return; + vr.beforeRender(gl, frame); + + try { + // Render both eyes + for (var _b = __values([0, 1]), _c = _b.next(); !_c.done; _c = _b.next()) { + var eyeIndex = _c.value; + var eyeParam = eyeParams[eyeIndex]; + _this.mvMatrix = eyeParam.mvMatrix; + _this.pMatrix = eyeParam.pMatrix; + gl.viewport.apply(gl, __spread(eyeParam.viewport)); + gl.uniform1f(_this.shaderProgram.uEye, eyeIndex); + + _this._bindBuffers(); + + _this._draw(); + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + + vr.afterRender(); + }; + + _this._onFirstVRFrame = function (time, frame) { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; // If rendering is not ready, wait for next frame + + if (!vr.canRender(frame)) return; + var minusZDir = glMatrix.vec3.fromValues(0, 0, -1); + var eyeParam = vr.getEyeParams(gl, frame)[0]; // Extract only rotation + + var mvMatrix = glMatrix.mat3.fromMat4(glMatrix.mat3.create(), eyeParam.mvMatrix); + var pMatrix = glMatrix.mat3.fromMat4(glMatrix.mat3.create(), eyeParam.pMatrix); + var mvInv = glMatrix.mat3.invert(glMatrix.mat3.create(), mvMatrix); + var pInv = glMatrix.mat3.invert(glMatrix.mat3.create(), pMatrix); + var viewDir = glMatrix.vec3.transformMat3(glMatrix.vec3.create(), minusZDir, pInv); + glMatrix.vec3.transformMat3(viewDir, viewDir, mvInv); + var yawOffset = util.yawOffsetBetween(viewDir, glMatrix.vec3.fromValues(0, 0, 1)); + + if (yawOffset === 0) { + // If the yawOffset is exactly 0, then device sensor is not ready + // So read it again until it has any value in it + return; + } + + vr.setYawOffset(yawOffset); + animator.setCallback(_this._renderStereo); + }; + + _this.sphericalConfig = sphericalConfig; + _this.fieldOfView = sphericalConfig.fieldOfView; + _this.width = width; + _this.height = height; + _this._lastQuaternion = null; + _this._lastYaw = null; + _this._lastPitch = null; + _this._lastFieldOfView = null; + _this.pMatrix = glMatrix.mat4.create(); + _this.mvMatrix = glMatrix.mat4.create(); // initialzie pMatrix + + glMatrix.mat4.perspective(_this.pMatrix, glMatrix.glMatrix.toRadian(_this.fieldOfView), width / height, 0.1, 100); + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + _this.canvas = _this._initCanvas(container, canvasClass, width, height); + + _this._setDefaultCanvasStyle(); + + _this._wrapper = null; // canvas wrapper + + _this._wrapperOrigStyle = null; + _this._renderingContextAttributes = renderingContextAttributes; + _this._image = null; + _this._imageConfig = null; + _this._imageIsReady = false; + _this._shouldForceDraw = false; + _this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still. + + _this._onContentLoad = _this._onContentLoad.bind(_this); + _this._onContentError = _this._onContentError.bind(_this); + _this._animator = new WebGLAnimator(); // VR/XR manager + + _this._vr = null; + + if (image) { + _this.setImage({ + image: image, + imageType: sphericalConfig.imageType, + isVideo: isVideo, + cubemapConfig: sphericalConfig.cubemapConfig + }); + } + + return _this; + } // FIXME: Please refactor me to have more loose connection to yawpitchcontrol + + + var __proto = PanoImageRenderer.prototype; + + __proto.setYawPitchControl = function (yawPitchControl) { + this._yawPitchControl = yawPitchControl; + }; + + __proto.getContent = function () { + return this._image; + }; + + __proto.setImage = function (_a) { + var image = _a.image, + imageType = _a.imageType, + _b = _a.isVideo, + isVideo = _b === void 0 ? false : _b, + cubemapConfig = _a.cubemapConfig; + this._imageIsReady = false; + this._isVideo = isVideo; + this._imageConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only */ + order: imageType === ImageType.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, cubemapConfig); + + this._setImageType(imageType); + + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._contentLoader = new ImReady().on("ready", this._onContentLoad).on("error", this._onContentError); + + if (isVideo) { + this._image = toVideoElement(image); + + this._contentLoader.check([this._image]); + + this._keepUpdate = true; + } else { + this._image = toImageElement(image); + + this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]); + + this._keepUpdate = false; + } + }; + + __proto.isImageLoaded = function () { + return !!this._image && this._imageIsReady && (!this._isVideo || this._image.readyState >= 2 + /* HAVE_CURRENT_DATA */ + ); + }; + + __proto.bindTexture = function () { + var _this = this; + + return new Promise$1(function (res, rej) { + var contentLoader = _this._contentLoader; + + if (!_this._image) { + return rej("Image is not defined"); + } + + if (!contentLoader) { + return rej("ImageLoader is not initialized"); + } + + if (contentLoader.isReady()) { + _this._bindTexture(); + + res(); + } else { + contentLoader.check(Array.isArray(_this._image) ? _this._image : [_this._image]); + contentLoader.once("ready", function (e) { + if (e.errorCount > 0) { + rej("Failed to load images."); + } else { + _this._bindTexture(); + + res(); + } + }); + } + }); + }; // 부모 엘리먼트에 canvas 를 붙임 + + + __proto.attachTo = function (parentElement) { + if (!this._hasExternalCanvas) { + this.detach(); + parentElement.appendChild(this.canvas); + } + + this._wrapper = parentElement; + }; + + __proto.forceContextLoss = function () { + if (this.hasRenderingContext()) { + var loseContextExtension = this.context.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + }; // 부모 엘리먼트에서 canvas 를 제거 + + + __proto.detach = function () { + if (!this._hasExternalCanvas && this.canvas.parentElement) { + this.canvas.parentElement.removeChild(this.canvas); + } + }; + + __proto.destroy = function () { + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._animator.stop(); + + this.detach(); + this.forceContextLoss(); + this.off(); + this.canvas.removeEventListener("webglcontextlost", this._onWebglcontextlost); + this.canvas.removeEventListener("webglcontextrestored", this._onWebglcontextrestored); + }; + + __proto.hasRenderingContext = function () { + var ctx = this.context; + + if (!ctx || ctx.isContextLost() || !ctx.getProgramParameter(this.shaderProgram, ctx.LINK_STATUS)) { + return false; + } + + return true; + }; + + __proto.updateFieldOfView = function (fieldOfView) { + this.fieldOfView = fieldOfView; + + this._updateViewport(); + }; + + __proto.updateViewportDimensions = function (width, height) { + var viewPortChanged = false; + this.width = width; + this.height = height; + var w = width * DEVICE_PIXEL_RATIO; + var h = height * DEVICE_PIXEL_RATIO; + + if (w !== this.canvas.width) { + this.canvas.width = w; + viewPortChanged = true; + } + + if (h !== this.canvas.height) { + this.canvas.height = h; + viewPortChanged = true; + } + + if (!viewPortChanged) { + return; + } + + this._updateViewport(); + + this._shouldForceDraw = true; + }; + + __proto.keepUpdate = function (doUpdate) { + if (doUpdate && this.isImageLoaded() === false) { + // Force to draw a frame after image is loaded on render() + this._shouldForceDraw = true; + } + + this._keepUpdate = doUpdate; + }; + + __proto.startRender = function () { + this._animator.setCallback(this._render.bind(this)); + + this._animator.start(); + }; + + __proto.stopRender = function () { + this._animator.stop(); + }; + + __proto.renderWithQuaternion = function (quaternion, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastQuaternion && glMatrix.quat.exactEquals(this._lastQuaternion, quaternion) && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // updatefieldOfView only if fieldOfView is changed. + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + this.mvMatrix = glMatrix.mat4.fromQuat(glMatrix.mat4.create(), quaternion); + + this._draw(); + + this._lastQuaternion = glMatrix.quat.clone(quaternion); + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + + __proto.renderWithYawPitch = function (yaw, pitch, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastYaw !== null && this._lastYaw === yaw && this._lastPitch !== null && this._lastPitch === pitch && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출 + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + glMatrix.mat4.identity(this.mvMatrix); + glMatrix.mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.glMatrix.toRadian(pitch)); + glMatrix.mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.glMatrix.toRadian(yaw)); + + this._draw(); + + this._lastYaw = yaw; + this._lastPitch = pitch; + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + /** + * Returns projection renderer by each type + */ + + + __proto.getProjectionRenderer = function () { + return this._renderer; + }; + /** + * @return Promise + */ + + + __proto.enterVR = function (options) { + var vr = this._vr; + + if (!WEBXR_SUPPORTED && !navigator.getVRDisplays) { + return Promise$1.reject("VR is not available on this browser."); + } + + if (vr && vr.isPresenting()) { + return Promise$1.resolve("VR already enabled."); + } + + return this._requestPresent(options); + }; + + __proto._setImageType = function (imageType) { + var _this = this; + + if (!imageType || this._imageType === imageType) { + return; + } + + this._imageType = imageType; + this._isCubeMap = imageType === ImageType.CUBEMAP; + + if (this._renderer) { + this._renderer.off(); + } + + switch (imageType) { + case ImageType.CUBEMAP: + this._renderer = new CubeRenderer(); + break; + + case ImageType.CUBESTRIP: + this._renderer = new CubeStripRenderer(); + break; + + case ImageType.PANORAMA: + this._renderer = new CylinderRenderer(); + break; + + case ImageType.STEREOSCOPIC_EQUI: + this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat); + break; + + default: + this._renderer = new SphereRenderer(STEREO_FORMAT.NONE); + break; + } + + this._renderer.on(Renderer.EVENTS.ERROR, function (e) { + _this.trigger(new Component.ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.RENDERER_ERROR, + message: e.message + })); + }); + + this._initWebGL(); + }; + + __proto._initCanvas = function (container, canvasClass, width, height) { + var canvasInContainer = container.querySelector("." + canvasClass); + + var canvas = canvasInContainer || this._createCanvas(canvasClass); + + this._hasExternalCanvas = !!canvasInContainer; + canvas.width = width; + canvas.height = height; + this._onWebglcontextlost = this._onWebglcontextlost.bind(this); + this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this); + canvas.addEventListener("webglcontextlost", this._onWebglcontextlost); + canvas.addEventListener("webglcontextrestored", this._onWebglcontextrestored); + return canvas; + }; + + __proto._createCanvas = function (className) { + var canvas = document.createElement("canvas"); + canvas.className = className; + return canvas; + }; + + __proto._setDefaultCanvasStyle = function () { + var canvas = this.canvas; + canvas.style.bottom = "0"; + canvas.style.left = "0"; + canvas.style.right = "0"; + canvas.style.top = "0"; + canvas.style.margin = "auto"; + canvas.style.maxHeight = "100%"; + canvas.style.maxWidth = "100%"; + canvas.style.outline = "none"; + canvas.style.position = "absolute"; + }; + + __proto._onContentError = function () { + this._imageIsReady = false; + this._image = null; + this.trigger(new Component.ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.FAIL_IMAGE_LOAD, + message: "failed to load image" + })); + return false; + }; + + __proto._triggerContentLoad = function () { + this.trigger(new Component.ComponentEvent(EVENTS$1.IMAGE_LOADED, { + content: this._image, + isVideo: this._isVideo, + projectionType: this._imageType + })); + }; + + __proto._onContentLoad = function (e) { + if (e.errorCount > 0) return; + this._imageIsReady = true; + + this._triggerContentLoad(); + }; + + __proto._initShaderProgram = function () { + var gl = this.context; + + if (this.shaderProgram) { + gl.deleteProgram(this.shaderProgram); + this.shaderProgram = null; + } + + var renderer = this._renderer; + var vsSource = renderer.getVertexShaderSource(); + var fsSource = renderer.getFragmentShaderSource(); + var vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource); + var fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource); + var shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader); + + if (!shaderProgram) { + throw new Error("Failed to initialize shaders: " + WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())); + } + + gl.useProgram(shaderProgram); + shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); + shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); + shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); + shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); + shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); + shaderProgram.uEye = gl.getUniformLocation(shaderProgram, "uEye"); + gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); + gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); // clear buffer + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); // Use TEXTURE0 + + gl.uniform1i(shaderProgram.samplerUniform, 0); + this.shaderProgram = shaderProgram; + }; + + __proto._onWebglcontextlost = function (e) { + e.preventDefault(); + this.trigger(new Component.ComponentEvent(EVENTS$1.RENDERING_CONTEXT_LOST)); + }; + + __proto._onWebglcontextrestored = function () { + this._initWebGL(); + + this.trigger(new Component.ComponentEvent(EVENTS$1.RENDERING_CONTEXT_RESTORE)); + }; + + __proto._updateViewport = function () { + glMatrix.mat4.perspective(this.pMatrix, glMatrix.glMatrix.toRadian(this.fieldOfView), this.canvas.width / this.canvas.height, 0.1, 100); + this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight); + }; + + __proto._initWebGL = function () { + var gl; // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed. + + try { + this._initRenderingContext(); + + gl = this.context; + this.updateViewportDimensions(this.width, this.height); + + this._initShaderProgram(); + } catch (e) { + this.trigger(new Component.ComponentEvent(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.NO_WEBGL, + message: "no webgl support" + })); + this.destroy(); + console.error(e); // eslint-disable-line no-console + + return; + } // 캔버스를 투명으로 채운다. + + + gl.clearColor(0, 0, 0, 0); + var textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D; + + if (this.texture) { + gl.deleteTexture(this.texture); + } + + this.texture = WebGLUtils.createTexture(gl, textureTarget); + + if (this._imageType === ImageType.CUBESTRIP) { + // TODO: Apply following options on other projection type. + gl.enable(gl.CULL_FACE); // gl.enable(gl.DEPTH_TEST); + } + }; + + __proto._initRenderingContext = function () { + if (this.hasRenderingContext()) { + return; + } + + if (!window.WebGLRenderingContext) { + throw new Error("WebGLRenderingContext not available."); + } + + this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes); + + if (!this.context) { + throw new Error("Failed to acquire 3D rendering context"); + } + }; + + __proto._initBuffers = function () { + var image = this._image; + + var vertexPositionData = this._renderer.getVertexPositionData(); + + var indexData = this._renderer.getIndexData(); + + var textureCoordData = this._renderer.getTextureCoordData({ + image: image, + imageConfig: this._imageConfig + }); + + var gl = this.context; + this.vertexBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3, this.shaderProgram.vertexPositionAttribute); + this.indexBuffer = WebGLUtils.initBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1); + this.textureCoordBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2, this.shaderProgram.textureCoordAttribute); + + this._bindBuffers(); + }; + + __proto._bindTexture = function () { + // Detect if it is EAC Format while CUBESTRIP mode. + // We assume it is EAC if image is not 3/2 ratio. + if (this._imageType === ImageType.CUBESTRIP) { + var _a = this._renderer.getDimension(this._image), + width = _a.width, + height = _a.height; + + var isEAC = width && height && width / height !== 1.5 ? 1 : 0; + this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram, "uIsEAC"), isEAC); + } else if (this._imageType === ImageType.PANORAMA) { + var _b = this._renderer.getDimension(this._image), + width = _b.width, + height = _b.height; + + var imageAspectRatio = width && height && width / height; + + this._renderer.updateShaderData({ + imageAspectRatio: imageAspectRatio + }); + } // initialize shader buffers after image is loaded.(by updateShaderData) + // because buffer may be differ by image size.(eg. CylinderRenderer) + + + this._initBuffers(); + + this._renderer.bindTexture(this.context, this.texture, this._image, this._imageConfig); + + this._shouldForceDraw = true; + this.trigger(new Component.ComponentEvent(EVENTS$1.BIND_TEXTURE)); + }; + + __proto._updateTexture = function () { + this._renderer.updateTexture(this.context, this._image, this._imageConfig); + }; + + __proto._render = function () { + var yawPitchControl = this._yawPitchControl; + var fov = yawPitchControl.getFov(); + + if (yawPitchControl.shouldRenderWithQuaternion()) { + var quaternion = yawPitchControl.getQuaternion(); + this.renderWithQuaternion(quaternion, fov); + } else { + var yawPitch = yawPitchControl.getYawPitch(); + this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov); + } + }; + + __proto._bindBuffers = function () { + var gl = this.context; + var program = this.shaderProgram; + var vertexBuffer = this.vertexBuffer; + var textureCoordBuffer = this.textureCoordBuffer; + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.enableVertexAttribArray(program.vertexPositionAttribute); + gl.vertexAttribPointer(program.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); + gl.enableVertexAttribArray(program.textureCoordAttribute); + gl.vertexAttribPointer(program.textureCoordAttribute, textureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); + }; + + __proto._draw = function () { + if (this._isVideo && this._keepUpdate) { + this._updateTexture(); + } + + this._renderer.render({ + gl: this.context, + shaderProgram: this.shaderProgram, + indexBuffer: this.indexBuffer, + mvMatrix: this.mvMatrix, + pMatrix: this.pMatrix + }); + }; + + __proto._requestPresent = function (options) { + var _this = this; + + var gl = this.context; + var canvas = this.canvas; + var animator = this._animator; + this._vr = WEBXR_SUPPORTED ? new XRManager(options) : new VRManager(); + var vr = this._vr; + animator.stop(); + return new Promise$1(function (resolve, reject) { + vr.requestPresent(canvas, gl).then(function () { + vr.addEndCallback(_this.exitVR); + animator.setContext(vr.context); + animator.setCallback(_this._onFirstVRFrame); + + if (IS_IOS) { + _this._setWrapperFullscreen(); + } + + _this._shouldForceDraw = true; + animator.start(); + resolve("success"); + }).catch(function (e) { + vr.destroy(); + _this._vr = null; + animator.start(); + reject(e); + }); + }); + }; + + __proto._setWrapperFullscreen = function () { + var wrapper = this._wrapper; + if (!wrapper) return; + this._wrapperOrigStyle = wrapper.getAttribute("style"); + var wrapperStyle = wrapper.style; + wrapperStyle.width = "100vw"; + wrapperStyle.height = "100vh"; + wrapperStyle.position = "fixed"; + wrapperStyle.left = "0"; + wrapperStyle.top = "0"; + wrapperStyle.zIndex = "9999"; + }; + + __proto._restoreStyle = function () { + var wrapper = this._wrapper; + var canvas = this.canvas; + if (!wrapper) return; + + if (this._wrapperOrigStyle) { + wrapper.setAttribute("style", this._wrapperOrigStyle); + } else { + wrapper.removeAttribute("style"); + } + + this._wrapperOrigStyle = null; // Restore canvas style + + canvas.removeAttribute("style"); + + this._setDefaultCanvasStyle(); + }; + + PanoImageRenderer.EVENTS = EVENTS$1; + PanoImageRenderer.ERROR_TYPE = ERROR_TYPE$1; + return PanoImageRenderer; + }(Component); + + /** + * @memberof eg.view360 + * @extends eg.Component + * PanoViewer + */ + + var PanoViewer = + /*#__PURE__*/ + function (_super) { + __extends(PanoViewer, _super); + /** + * @classdesc 360 media viewer + * @ko 360 미디어 뷰어 + * + * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트 + * @param options + * + * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
+ * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다. + * @param {Object} [options.cubemapConfig.order = "RLUDBF"(ProjectionType === CUBEMAP) | "RLUDFB" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서 + * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다. + * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다. + * @param {String} [options.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
+ * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위) + * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위) + * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위) + * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위) + * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위) + * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다 + * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다. + * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키 + * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE}
+ * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위 + * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위 + * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위 + * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
+ * @param {String} [options.canvasClass="view360-canvas"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * + * @example + * ``` + * // PanoViewer Creation + * // create PanoViewer with option + * var PanoViewer = eg.view360.PanoViewer; + * // Area where the image will be displayed(HTMLElement) + * var container = document.getElementById("myPanoViewer"); + * + * var panoViewer = new PanoViewer(container, { + * // If projectionType is not specified, the default is "equirectangular". + * // Specifies an image of the "equirectangular" type. + * image: "/path/to/image/image.jpg" + * }); + * ``` + * + * @example + * ``` + * // Cubemap Config Setting Example + * // For support Youtube EAC projection, You should set cubemapConfig as follows. + * cubemapConfig: { + * order: "LFRDBU", + * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}] + * } + * ``` + */ + + + function PanoViewer(container, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; // Raises the error event if webgl is not supported. + + + if (!WebGLUtils.isWebGLAvailable()) { + setTimeout(function () { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.NO_WEBGL, + message: "no webgl support" + })); + }, 0); + return _this; + } + + if (!WebGLUtils.isStableWebGL()) { + setTimeout(function () { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_DEVICE, + message: "blacklisted browser" + })); + }, 0); + return _this; + } + + if (!!options.image && !!options.video) { + setTimeout(function () { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_RESOURCE, + message: "Specifying multi resouces(both image and video) is not valid." + })); + }, 0); + return _this; + } // Check XR support at not when imported, but when created. + // This is intended to make polyfills easier to use. + + + checkXRSupport(); + _this._container = container; + _this._image = options.image || options.video; + _this._isVideo = !!options.video; + _this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + _this._cubemapConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/ + order: _this._projectionType === PROJECTION_TYPE.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, options.cubemapConfig); + _this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; // If the width and height are not provided, will use the size of the container. + + _this._width = options.width || parseInt(window.getComputedStyle(container).width, 10); + _this._height = options.height || parseInt(window.getComputedStyle(container).height, 10); + /** + * Cache the direction for the performance in renderLoop + * + * This value should be updated by "change" event of YawPitchControl. + */ + + _this._yaw = options.yaw || 0; + _this._pitch = options.pitch || 0; + _this._fov = options.fov || 65; + _this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH; + _this._quaternion = null; + _this._aspectRatio = _this._height !== 0 ? _this._width / _this._height : 1; + _this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS; + var fovRange = options.fovRange || [30, 110]; + var touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ? options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL; + + var yawPitchConfig = __assign(__assign({}, options), { + element: container, + yaw: _this._yaw, + pitch: _this._pitch, + fov: _this._fov, + gyroMode: _this._gyroMode, + fovRange: fovRange, + aspectRatio: _this._aspectRatio, + touchDirection: touchDirection + }); + + _this._isReady = false; + + _this._initYawPitchControl(yawPitchConfig); + + _this._initRenderer(_this._yaw, _this._pitch, _this._fov, _this._projectionType, _this._cubemapConfig); + + return _this; + } + /** + * Check whether the current environment can execute PanoViewer + * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다. + * @return PanoViewer executable PanoViewer 실행가능 여부 + */ + + + var __proto = PanoViewer.prototype; + + PanoViewer.isSupported = function () { + return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL(); + }; + /** + * Check whether the current environment supports the WebGL + * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다. + * @return WebGL support WebGL 지원여부 + */ + + + PanoViewer.isWebGLAvailable = function () { + return WebGLUtils.isWebGLAvailable(); + }; + /** + * Check whether the current environment supports the gyro sensor. + * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다. + * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수 + */ + + + PanoViewer.isGyroSensorAvailable = function (callback) { + if (!DeviceMotionEvent && callback) { + callback(false); + return; + } + + var onDeviceMotionChange; + + var checkGyro = function () { + return new Promise$1(function (res) { + onDeviceMotionChange = function (deviceMotion) { + var isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null); + res(isGyroSensorAvailable); + }; + + window.addEventListener("devicemotion", onDeviceMotionChange); + }); + }; + + var timeout = function () { + return new Promise$1(function (res) { + setTimeout(function () { + return res(false); + }, 1000); + }); + }; + + Promise$1.race([checkGyro(), timeout()]).then(function (isGyroSensorAvailable) { + window.removeEventListener("devicemotion", onDeviceMotionChange); + + if (callback) { + callback(isGyroSensorAvailable); + } + + PanoViewer.isGyroSensorAvailable = function (fb) { + if (fb) { + fb(isGyroSensorAvailable); + } + + return isGyroSensorAvailable; + }; + }); + }; + + PanoViewer._isValidTouchDirection = function (direction) { + return direction === PanoViewer.TOUCH_DIRECTION.NONE || direction === PanoViewer.TOUCH_DIRECTION.YAW || direction === PanoViewer.TOUCH_DIRECTION.PITCH || direction === PanoViewer.TOUCH_DIRECTION.ALL; + }; + /** + * Get the video element that the viewer is currently playing. You can use this for playback. + * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다. + * @return HTMLVideoElementHTMLVideoElement + * @example + * ``` + * var videoTag = panoViewer.getVideo(); + * videoTag.play(); // play the video! + * ``` + */ + + + __proto.getVideo = function () { + if (!this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the video information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정) + * @param {object} param + * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}("equirectangular")] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setVideo("/path/to/video/video.mp4", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR + * }); + * ``` + */ + + + __proto.setVideo = function (video, param) { + if (param === void 0) { + param = {}; + } + + if (video) { + this.setImage(video, { + projectionType: param.projectionType, + isVideo: true, + cubemapConfig: param.cubemapConfig, + stereoFormat: param.stereoFormat + }); + } + + return this; + }; + /** + * Get the image information that the viewer is currently using. + * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다. + * @return Image Object이미지 객체 + * @example + * var imageObj = panoViewer.getImage(); + */ + + + __proto.getImage = function () { + if (this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the image information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.) + * @param {object} param Additional information이미지 추가 정보 + * @param {string} [param.projectionType="equirectangular"] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부 + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setImage("/path/to/image/image.png", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP + * }); + * ``` + */ + + + __proto.setImage = function (image, param) { + if (param === void 0) { + param = {}; + } + + var cubemapConfig = __assign({ + order: "RLUDBF", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, param.cubemapConfig); + + var stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; + var isVideo = !!param.isVideo; + + if (this._image && this._isVideo !== isVideo) { + /* eslint-disable no-console */ + console.warn("PanoViewer is not currently supporting content type changes. (Image <--> Video)"); + /* eslint-enable no-console */ + + return this; + } + + if (image) { + this._deactivate(); + + this._image = image; + this._isVideo = isVideo; + this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + this._cubemapConfig = cubemapConfig; + this._stereoFormat = stereoFormat; + + this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig); + } + + return this; + }; + /** + * Set whether the renderer always updates the texture and renders. + * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다. + * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.keepUpdate = function (doUpdate) { + this._photoSphereRenderer.keepUpdate(doUpdate); + + return this; + }; + /** + * Get the current projection type (equirectangular/cube) + * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다. + * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE} + */ + + + __proto.getProjectionType = function () { + return this._projectionType; + }; + /** + * Activate the device's motion sensor, and return the Promise whether the sensor is enabled + * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element. + * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다. + * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다. + */ + + + __proto.enableSensor = function () { + return new Promise$1(function (resolve, reject) { + if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === "function") { + DeviceMotionEvent.requestPermission().then(function (permissionState) { + if (permissionState === "granted") { + resolve(); + } else { + reject(new Error("permission denied")); + } + }).catch(function (e) { + // This can happen when this method wasn't triggered by user interaction + reject(e); + }); + } else { + resolve(); + } + }); + }; + /** + * Disable the device's motion sensor. + * @ko 디바이스의 모션 센서를 비활성화합니다. + * @deprecated + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.disableSensor = function () { + return this; + }; + /** + * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred). + * This method must be used in the context of user interaction, like onclick callback on the button element. + * It can be rejected when an enabling device sensor fails or image/video is still loading("ready" event not triggered). + * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다) + * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우("ready"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다. + * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요. + * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error) + */ + + + __proto.enterVR = function (options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + if (!this._isReady) { + return Promise$1.reject(new Error("PanoViewer is not ready to show image.")); + } + + return new Promise$1(function (resolve, reject) { + _this.enableSensor().then(function () { + return _this._photoSphereRenderer.enterVR(options); + }).then(function (res) { + return resolve(res); + }).catch(function (e) { + return reject(e); + }); + }); + }; + /** + * Exit VR stereo rendering mode. + * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.exitVR = function () { + this._photoSphereRenderer.exitVR(); + + return this; + }; + /** + * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}. + * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다. + * @param useZoom + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseZoom = function (useZoom) { + if (typeof useZoom === "boolean") { + this._yawPitchControl.option("useZoom", useZoom); + } + + return this; + }; + /** + * When true, enables the keyboard move key control: awsd, arrow keys + * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키) + * @param useKeyboard + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseKeyboard = function (useKeyboard) { + this._yawPitchControl.option("useKeyboard", useKeyboard); + + return this; + }; + /** + * Enables control through device motion. ("none", "yawPitch", "VR") + * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR") + * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE} + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setGyroMode("yawPitch"); + * //equivalent + * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH); + * ``` + */ + + + __proto.setGyroMode = function (gyroMode) { + this._yawPitchControl.option("gyroMode", gyroMode); + + return this; + }; + /** + * Set the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 설정합니다. + * @param range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setFovRange([50, 90]); + */ + + + __proto.setFovRange = function (range) { + this._yawPitchControl.option("fovRange", range); + + return this; + }; + /** + * Get the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 반환합니다. + * @return FOV range + * @example + * var range = panoViewer.getFovRange(); // [50, 90] + */ + + + __proto.getFovRange = function () { + return this._yawPitchControl.option("fovRange"); + }; + /** + * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size. + * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다. + * @param {object} [size] + * @param {number} [size.width=width of the container] + * @param {number} [size.height=height of the container] + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.updateViewportDimensions = function (size) { + if (size === void 0) { + size = {}; + } + + if (!this._isReady) { + return this; + } + + var containerSize; + + if (size.width === undefined || size.height === undefined) { + containerSize = window.getComputedStyle(this._container); + } + + var width = size.width || parseInt(containerSize.width, 10); + var height = size.height || parseInt(containerSize.height, 10); // Skip if viewport is not changed. + + if (width === this._width && height === this._height) { + return this; + } + + this._width = width; + this._height = height; + this._aspectRatio = width / height; + + this._photoSphereRenderer.updateViewportDimensions(width, height); + + this._yawPitchControl.option("aspectRatio", this._aspectRatio); + + this._yawPitchControl.updatePanScale({ + height: height + }); + + this.lookAt({}, 0); + return this; + }; + /** + * Get the current field of view(FOV) + * @ko 현재 field of view(FOV) 값을 반환합니다. + */ + + + __proto.getFov = function () { + return this._fov; + }; + /** + * Get current yaw value + * @ko 현재 yaw 값을 반환합니다. + */ + + + __proto.getYaw = function () { + return this._yaw; + }; + /** + * Get current pitch value + * @ko 현재 pitch 값을 반환합니다. + */ + + + __proto.getPitch = function () { + return this._pitch; + }; + /** + * Get the range of controllable Yaw values + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + */ + + + __proto.getYawRange = function () { + return this._yawPitchControl.option("yawRange"); + }; + /** + * Get the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다. + */ + + + __proto.getPitchRange = function () { + return this._yawPitchControl.option("pitchRange"); + }; + /** + * Set the range of controllable yaw + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setYawRange([-90, 90]); + */ + + + __proto.setYawRange = function (yawRange) { + this._yawPitchControl.option("yawRange", yawRange); + + return this; + }; + /** + * Set the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 설정합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setPitchRange([-40, 40]); + */ + + + __proto.setPitchRange = function (pitchRange) { + this._yawPitchControl.option("pitchRange", pitchRange); + + return this; + }; + /** + * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed. + * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다. + * @param showPolePoint + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setShowPolePoint = function (showPolePoint) { + this._yawPitchControl.option("showPolePoint", showPolePoint); + + return this; + }; + /** + * Set a new view by setting camera configuration. Any parameters not specified remain the same. + * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다. + * @param {object} orientation + * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위) + * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위) + * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위) + * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초) + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * // Change the yaw angle (absolute angle) to 30 degrees for one second. + * panoViewer.lookAt({yaw: 30}, 1000); + * ``` + */ + + + __proto.lookAt = function (orientation, duration) { + if (duration === void 0) { + duration = 0; + } + + if (!this._isReady) { + return this; + } + + var yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw; + var pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch; + + var pitchRange = this._yawPitchControl.option("pitchRange"); + + var verticalAngleOfImage = pitchRange[1] - pitchRange[0]; + var fov = orientation.fov !== undefined ? orientation.fov : this._fov; + + if (verticalAngleOfImage < fov) { + fov = verticalAngleOfImage; + } + + this._yawPitchControl.lookAt({ + yaw: yaw, + pitch: pitch, + fov: fov + }, duration); + + if (duration === 0) { + this._photoSphereRenderer.renderWithYawPitch(yaw, pitch, fov); + } + + return this; + }; + /** + * Set touch direction by which user can control. + * @ko 사용자가 조작가능한 터치 방향을 지정합니다. + * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @return PanoViewer instance + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Limit the touch direction to the yaw direction only. + * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW); + * ``` + */ + + + __proto.setTouchDirection = function (direction) { + if (PanoViewer._isValidTouchDirection(direction)) { + this._yawPitchControl.option("touchDirection", direction); + } + + return this; + }; + /** + * Returns touch direction by which user can control + * @ko 사용자가 조작가능한 터치 방향을 반환한다. + * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Returns the current touch direction. + * var dir = panoViewer.getTouchDirection(); + * ``` + */ + + + __proto.getTouchDirection = function () { + return this._yawPitchControl.option("touchDirection"); + }; + /** + * Destroy viewer. Remove all registered event listeners and remove viewer canvas. + * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.destroy = function () { + this._deactivate(); + + if (this._yawPitchControl) { + this._yawPitchControl.destroy(); + + this._yawPitchControl = null; + } + + return this; + }; // TODO: Remove parameters as they're just using private values + + + __proto._initRenderer = function (yaw, pitch, fov, projectionType, cubemapConfig) { + var _this = this; + + this._photoSphereRenderer = new PanoImageRenderer(this._image, this._width, this._height, this._isVideo, this._container, this._canvasClass, { + initialYaw: yaw, + initialPitch: pitch, + fieldOfView: fov, + imageType: projectionType, + cubemapConfig: cubemapConfig, + stereoFormat: this._stereoFormat + }); + + this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl); + + this._bindRendererHandler(); + + this._photoSphereRenderer.bindTexture().then(function () { + return _this._activate(); + }).catch(function () { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.FAIL_BIND_TEXTURE, + message: "failed to bind texture" + })); + }); + }; + /** + * @private + * update values of YawPitchControl if needed. + * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image. + * + * This function should be called after isReady status is true. + */ + + + __proto._updateYawPitchIfNeeded = function () { + if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) { + // update fov by aspect ratio + var image = this._photoSphereRenderer.getContent(); + + var imageAspectRatio = image.naturalWidth / image.naturalHeight; + var yawSize = void 0; + var maxFov = void 0; // If height is larger than width, then we assume it's rotated by 90 degree. + + if (imageAspectRatio < 1) { + // So inverse the aspect ratio. + imageAspectRatio = 1 / imageAspectRatio; + } + + if (imageAspectRatio < 6) { + yawSize = util.toDegree(imageAspectRatio); // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5 + + maxFov = util.toDegree(Math.atan(0.5)) * 2; + } else { + yawSize = 360; + maxFov = 360 / imageAspectRatio; // Make it 5 fixed as axes does. + } // console.log("_updateYawPitchIfNeeded", maxFov, "aspectRatio", image.naturalWidth, image.naturalHeight, "yawSize", yawSize); + + + var minFov = this._yawPitchControl.option("fovRange")[0]; // this option should be called after fov is set. + + + this._yawPitchControl.option({ + "fov": maxFov, + "yawRange": [-yawSize / 2, yawSize / 2], + "pitchRange": [-maxFov / 2, maxFov / 2], + "fovRange": [minFov, maxFov] + }); + + this.lookAt({ + fov: maxFov + }); + } + }; + + __proto._bindRendererHandler = function () { + var _this = this; + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.ERROR, function (e) { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, e)); + }); + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, function () { + _this._deactivate(); + + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.RENDERING_CONTEXT_LOST, + message: "webgl rendering context lost" + })); + }); + }; + + __proto._initYawPitchControl = function (yawPitchConfig) { + var _this = this; + + this._yawPitchControl = new YawPitchControl(yawPitchConfig); + + this._yawPitchControl.on(PANOVIEWER_EVENTS.ANIMATION_END, function (e) { + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.ANIMATION_END, e)); + }); + + this._yawPitchControl.on("change", function (e) { + _this._yaw = e.yaw; + _this._pitch = e.pitch; + _this._fov = e.fov; + _this._quaternion = e.quaternion; + + _this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.VIEW_CHANGE, { + yaw: e.yaw, + pitch: e.pitch, + fov: e.fov, + quaternion: e.quaternion, + isTrusted: e.isTrusted + })); + }); + }; + + __proto._activate = function () { + this._photoSphereRenderer.attachTo(this._container); + + this._yawPitchControl.enable(); + + this.updateViewportDimensions(); + this._isReady = true; // update yawPitchControl after isReady status is true. + + this._updateYawPitchIfNeeded(); + + this.trigger(new Component.ComponentEvent(PANOVIEWER_EVENTS.READY)); + + this._photoSphereRenderer.startRender(); + }; + /** + * Destroy webgl context and block user interaction and stop rendering + */ + + + __proto._deactivate = function () { + // Turn off the video if it has one + var video = this.getVideo(); + + if (video) { + video.pause(); + } + + if (this._isReady) { + this._photoSphereRenderer.stopRender(); + + this._yawPitchControl.disable(); + + this._isReady = false; + } + + if (this._photoSphereRenderer) { + this._photoSphereRenderer.destroy(); + + this._photoSphereRenderer = null; + } + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @type {String} + * @example + * eg.view360.PanoViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.PanoViewer + */ + + + PanoViewer.VERSION = VERSION; + PanoViewer.ERROR_TYPE = ERROR_TYPE; + PanoViewer.EVENTS = PANOVIEWER_EVENTS; + PanoViewer.PROJECTION_TYPE = PROJECTION_TYPE; + PanoViewer.GYRO_MODE = GYRO_MODE; // This should be deprecated! + // eslint-disable-next-line @typescript-eslint/naming-convention + + PanoViewer.ProjectionType = PROJECTION_TYPE; + PanoViewer.STEREO_FORMAT = STEREO_FORMAT; + /** + * Constant value for touch directions + * @ko 터치 방향에 대한 상수 값. + * @namespace + * @name TOUCH_DIRECTION + */ + + PanoViewer.TOUCH_DIRECTION = { + /** + * Constant value for none direction. + * @ko none 방향에 대한 상수 값. + * @name NONE + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 1 + */ + NONE: YawPitchControl.TOUCH_DIRECTION_NONE, + + /** + * Constant value for horizontal(yaw) direction. + * @ko horizontal(yaw) 방향에 대한 상수 값. + * @name YAW + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 6 + */ + YAW: YawPitchControl.TOUCH_DIRECTION_YAW, + + /** + * Constant value for vertical direction. + * @ko vertical(pitch) 방향에 대한 상수 값. + * @name PITCH + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 24 + */ + PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH, + + /** + * Constant value for all direction. + * @ko all 방향에 대한 상수 값. + * @name ALL + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 30 + */ + ALL: YawPitchControl.TOUCH_DIRECTION_ALL + }; + return PanoViewer; + }(Component); + + var PanoViewer$1 = { + __proto__: null, + PanoViewer: PanoViewer, + VERSION: VERSION, + GYRO_MODE: GYRO_MODE, + PANOVIEWER_EVENTS: PANOVIEWER_EVENTS, + ERROR_TYPE: ERROR_TYPE, + PROJECTION_TYPE: PROJECTION_TYPE, + STEREO_FORMAT: STEREO_FORMAT, + PANOVIEWER_OPTIONS: PANOVIEWER_OPTIONS, + DEFAULT_CANVAS_CLASS: DEFAULT_CANVAS_CLASS + }; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + var SPINVIEWER_OPTIONS = { + imageUrl: true, + rowCount: true, + colCount: true, + width: true, + height: true, + autoHeight: true, + colRow: true, + scale: true, + frameIndex: true, + wrapperClass: true, + imageClass: true + }; + var SPINVIEWER_EVENTS = { + LOAD: "load", + IMAGE_ERROR: "imageError", + CHANGE: "change", + ANIMATION_END: "animationEnd" + }; + var DEFAULT_WRAPPER_CLASS = "view360-wrapper"; + var DEFAULT_IMAGE_CLASS = "view360-image"; + + /** + * @memberof eg.view360 + * @extends eg.Component + * SpriteImage + */ + + var SpriteImage = + /*#__PURE__*/ + function (_super) { + __extends(SpriteImage, _super); + /** + * @class eg.view360.SpriteImage + * @classdesc A module that displays a single or continuous image of any one of the "sprite images". SpinViewer internally uses SpriteImage to show each frame of the sprite image. + * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다. + * @extends eg.Component + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the "Sprite image". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
+ * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * + * // Initialize SpriteImage + * + * var el = document.getElementById("image-div"); + * var sprites = new eg.view360.SpriteImage(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 + * }); + */ + + + function SpriteImage(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + var opt = options || {}; + _this._el = element; + _this._rowCount = opt.rowCount || 1; + _this._colCount = opt.colCount || 1; + _this._totalCount = _this._rowCount * _this._colCount; // total frames + + _this._width = opt.width || "auto"; + _this._height = opt.height || "auto"; + _this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten. + + _this._colRow = [0, 0]; + + if (opt.colRow) { + _this._colRow = opt.colRow; + } else if (opt.frameIndex) { + _this.setFrameIndex(opt.frameIndex); + } + + _this._el.style.width = SpriteImage._getSizeString(_this._width); + _this._el.style.height = SpriteImage._getSizeString(_this._height); + var wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS; + var imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS; + + if (!opt.imageUrl) { + setTimeout(function () { + _this.trigger(new Component.ComponentEvent("imageError", { + imageUrl: opt.imageUrl + })); + }, 0); + return _this; + } + + var imageInContainer = element.querySelector("." + imageClass); + var wrapperInContainer = element.querySelector("." + wrapperClass); + + if (wrapperInContainer && imageInContainer) { + // Set it to invisible to prevent wrapper being resized + imageInContainer.style.display = "none"; + } + + _this._image = imageInContainer || new Image(); + /** + * Event + */ + + var image = _this._image; + + image.onload = function () { + if (wrapperInContainer && imageInContainer) { + imageInContainer.style.display = ""; + } + + _this._bg = SpriteImage._createBgDiv(wrapperInContainer, image, _this._rowCount, _this._colCount, _this._autoHeight); + + _this._el.appendChild(_this._bg); + + _this.setColRow(_this._colRow[0], _this._colRow[1]); + + _this.trigger(new Component.ComponentEvent("load", { + target: _this._el, + bgElement: _this._bg + })); + + if (_this._autoPlayReservedInfo) { + _this.play(_this._autoPlayReservedInfo); + + _this._autoPlayReservedInfo = null; + } + }; + + image.onerror = function () { + _this.trigger(new Component.ComponentEvent("imageError", { + imageUrl: opt.imageUrl + })); + }; + + image.src = opt.imageUrl; + return _this; + } + + var __proto = SpriteImage.prototype; + + SpriteImage._createBgDiv = function (wrapperInContainer, img, rowCount, colCount, autoHeight) { + var el = wrapperInContainer || document.createElement("div"); + el.style.position = "relative"; + el.style.overflow = "hidden"; + img.style.position = "absolute"; + img.style.width = colCount * 100 + "%"; + img.style.height = rowCount * 100 + "%"; + /** Prevent image from being dragged on IE10, IE11, Safari especially */ + + img.ondragstart = function () { + return false; + }; // img.style.pointerEvents = "none"; + // Use hardware accelerator if available + + + if (SUPPORT_WILLCHANGE) { + img.style.willChange = "transform"; + } + + el.appendChild(img); + var unitWidth = img.naturalWidth / colCount; + var unitHeight = img.naturalHeight / rowCount; + + if (autoHeight) { + var r = unitHeight / unitWidth; + el.style.paddingBottom = r * 100 + "%"; + } else { + el.style.height = "100%"; + } + + return el; + }; + + SpriteImage._getSizeString = function (size) { + if (typeof size === "number") { + return size + "px"; + } + + return size; + }; + /** + * Specifies the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정 + * @method eg.view360.SpriteImage#setFrameIndex + * @param {Number} frameIndex frame index of a frame프레임의 인덱스 + * + * @example + * + * sprites.setFrameIndex(0, 1);// col = 0, row = 1 + */ + + + __proto.setFrameIndex = function (index) { + var colRow = this.toColRow(index); + this.setColRow(colRow[0], colRow[1]); + }; + /** + * Returns the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환 + * @method eg.view360.SpriteImage#getFrameIndex + * @return {Number} frame index frame 인덱스 + * + * @example + * + * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1 + * + */ + + + __proto.getFrameIndex = function () { + return this._colRow[1] * this._colCount + this._colRow[0]; + }; + /** + * Specifies the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정 + * @method eg.view360.SpriteImage#setColRow + * @param {Number} col Column number of a frame프레임의 행값 + * @param {Number} row Row number of a frame프레임의 열값 + * + * @example + * + * sprites.setlColRow(1, 2); // col = 1, row = 2 + */ + + + __proto.setColRow = function (col, row) { + if (row > this._rowCount - 1 || col > this._colCount - 1) { + return; + } + + if (this._image && TRANSFORM) { + // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser? + this._image.style[TRANSFORM] = "translate(" + -(col / this._colCount * 100) + "%, " + -(row / this._rowCount * 100) + "%)"; + } + + this._colRow = [col, row]; + }; + /** + * Returns the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환 + * @method eg.view360.SpriteImage#gelColRow + * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열 + * + * @example + * + * var colRow = sprites.getlColRow(); + * // colRow = [1, 2] - index of col is 1, index of row is 2 + * + */ + + + __proto.getColRow = function () { + return this._colRow; + }; + /** + * Stop playing + * @ko play 되고 있던 프레임 재생을 중지합니다. + * @method eg.view360.SpriteImage#stop + * + * @example + * + * viewer.stop(); + * + */ + + + __proto.stop = function () { + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + }; + /** + * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'. + * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다. + * @method eg.view360.SpriteImage#play + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위 + * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복 + * + * @example + * + * viewer.play({angle: 16, playCount: 1}); + * + */ + + + __proto.play = function (_a) { + var _this = this; + + var _b = _a === void 0 ? { + interval: 1000 / this._totalCount, + playCount: 0 + } : _a, + interval = _b.interval, + playCount = _b.playCount; + + if (!this._bg) { + this._autoPlayReservedInfo = { + interval: interval, + playCount: playCount + }; + return; + } + + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + + var frameIndex = this.getFrameIndex(); + var count = 0; + var frameCount = 0; // for checking 1 cycle + + this._autoPlayTimer = window.setInterval(function () { + frameIndex %= _this._totalCount; + + var colRow = _this.toColRow(frameIndex); + + _this.setColRow(colRow[0], colRow[1]); + + frameIndex++; // Done 1 Cycle? + + if (++frameCount === _this._totalCount) { + frameCount = 0; + count++; + } + + if (playCount > 0 && count === playCount) { + clearInterval(_this._autoPlayTimer); + } + }, interval); + }; + + __proto.toColRow = function (frameIndex) { + var colCount = this._colCount; + var rowCount = this._rowCount; + + if (frameIndex < 0) { + return [0, 0]; + } else if (frameIndex >= this._totalCount) { + return [colCount - 1, rowCount - 1]; + } + + var col = frameIndex % colCount; + var row = Math.floor(frameIndex / colCount); // console.log(frameIndex, col, row); + + return [col, row]; + }; + + SpriteImage.VERSION = VERSION; + return SpriteImage; + }(Component); + + var DEFAULT_PAN_SCALE = 0.21; + /** + * @memberof eg.view360 + * @extends eg.Component + * SpinViewer + */ + + var SpinViewer = + /*#__PURE__*/ + function (_super) { + __extends(SpinViewer, _super); + /** + * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object. + * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다. + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값 + * @param {String} [options.wrapperClass="view360-wrapper"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @param {String} [options.imageClass="view360-image"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * ``` + * // Initialize SpinViewer + * var el = document.getElementById("product-360"); + * var viewer = new eg.view360.SpinViewer(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 //required + * }); + * ``` + */ + + + function SpinViewer(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this._el = element; + + var opt = __assign({}, options); + + var colCount = opt.colCount || 1; + var rowCount = opt.rowCount || 1; + _this._scale = opt.scale || 1; + _this._panScale = _this._scale * DEFAULT_PAN_SCALE; + _this._frameCount = colCount * rowCount; // Init SpriteImage + + _this._sprites = new SpriteImage(element, opt).on({ + "load": function (evt) { + _this.trigger(new Component.ComponentEvent("load", evt)); + }, + "imageError": function (evt) { + _this.trigger(new Component.ComponentEvent("imageError", { + imageUrl: evt.imageUrl + })); + } + }); // Init Axes + + _this._panInput = new Axes.PanInput(_this._el, { + scale: [_this._panScale, _this._panScale] + }); + _this._axes = new Axes({ + angle: { + range: [0, 359], + circular: true + } + }).on({ + "change": function (evt) { + var curr = Math.floor(evt.pos.angle / (360 / _this._frameCount)); + var frameIndex = _this._frameCount - curr - 1; + + _this._sprites.setFrameIndex(frameIndex); + + _this.trigger(new Component.ComponentEvent("change", { + frameIndex: frameIndex, + colRow: _this._sprites.getColRow(), + angle: evt.pos.angle + })); + }, + "animationEnd": function (evt) { + _this.trigger(new Component.ComponentEvent("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + + _this._axes.connect("angle", _this._panInput); + + return _this; + } + /** + * Set spin scale + * @ko scale 을 조정할 수 있는 함수 + * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.setScale(2);// It moves twice as much. + */ + + + var __proto = SpinViewer.prototype; + + __proto.setScale = function (scale) { + if (isNaN(scale) || scale < 0) { + return this; + } + + this._scale = scale; + this._panScale = scale * DEFAULT_PAN_SCALE; + this._panInput.options.scale = [this._panScale, this._panScale]; + return this; + }; + /** + * Get spin scale + * @ko scale 값을 반환한다. + * + * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @example + * viewer.getScale();// It returns number + */ + + + __proto.getScale = function () { + return this._scale; + }; + /** + * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle. + * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle상대적 회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinBy(720, {duration: 500}); + */ + + + __proto.spinBy = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setBy({ + angle: angle + }, param.duration); + + return this; + }; + /** + * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle). + * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinTo(30, {duration:100}); + */ + + + __proto.spinTo = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setTo({ + angle: angle + }, param.duration); + + return this; + }; + /** + * Returns current angles + * @ko 현재 각도를 반환한다. + * + * @return {Number} Current angle 현재 각도 + */ + + + __proto.getAngle = function () { + return this._axes.get().angle || 0; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @static + * @example + * eg.view360.SpinViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.SpinViewer + */ + + + SpinViewer.VERSION = VERSION; + return SpinViewer; + }(Component); + + var SpinViewer$1 = { + __proto__: null, + SpinViewer: SpinViewer, + SpriteImage: SpriteImage, + VERSION: VERSION, + SPINVIEWER_OPTIONS: SPINVIEWER_OPTIONS, + SPINVIEWER_EVENTS: SPINVIEWER_EVENTS, + DEFAULT_WRAPPER_CLASS: DEFAULT_WRAPPER_CLASS, + DEFAULT_IMAGE_CLASS: DEFAULT_IMAGE_CLASS + }; + + var withMethods = function (component, prototype, vanillaInstance) { + [Component.prototype, component.prototype].forEach(function (proto) { + Object.getOwnPropertyNames(proto).filter(function (name) { + return !prototype[name] && !name.startsWith("_") && name !== "constructor"; + }).forEach(function (name) { + var descriptor = Object.getOwnPropertyDescriptor(proto, name); + + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function () { + var _a; + + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + return (_a = descriptor.value).call.apply(_a, __spread([this[vanillaInstance]], args)); + } + }); + } else { + var getterDescriptor = {}; + + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + + return (_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[vanillaInstance]); + }; + } + + if (descriptor.set) { + getterDescriptor.set = function () { + var _a; + + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spread([this[vanillaInstance]], args)); + }; + } + + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); + }; + + var withPanoViewerMethods = function (prototype, name) { + withMethods(PanoViewer, prototype, name); + }; + + var withSpinViewerMethods = function (prototype, name) { + withMethods(SpinViewer, prototype, name); + }; + + var updatePanoViewer = (function (panoViewer, newProps, prevProps) { + if (isPropChanged(newProps.image, prevProps.image)) { + panoViewer.setImage(newProps.image, { + projectionType: newProps.projectionType, + cubemapConfig: newProps.cubemapConfig, + stereoFormat: newProps.stereoFormat, + isVideo: false + }); + } else if (isPropChanged(newProps.video, prevProps.video)) { + panoViewer.setVideo(newProps.video, { + projectionType: newProps.projectionType, + cubemapConfig: newProps.cubemapConfig, + stereoFormat: newProps.stereoFormat + }); + } + + var singleUpdateOptions = ["fovRange", "gyroMode", "pitchRange", "showPolePoint", "touchDirection", "useKeyboard", "useZoom", "yawRange"]; + singleUpdateOptions.forEach(function (optionName) { + updateOption(panoViewer, optionName, newProps, prevProps); + }); + }); + + var isPropChanged = function (val, prevVal) { + return val != null && val !== prevVal; + }; + + var updateOption = function (panoViewer, optionName, newProps, prevProps) { + if (isPropChanged(newProps[optionName], prevProps[optionName])) { + panoViewer["set" + optionName[0].toUpperCase() + optionName.slice(1)](newProps[optionName]); + } + }; + + var getValidProps = function (propsObj) { + return Object.keys(propsObj).reduce(function (props, propName) { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + + return props; + }, {}); + }; + var generateCanvasKey = function (oldKey) { + var newKey; + + do { + var array = new Uint32Array(1); + crypto.getRandomValues(array); + newKey = array[0]; + } while (newKey === oldKey); + + return newKey; + }; + + var CFC = { + __proto__: null, + withMethods: withMethods, + withPanoViewerMethods: withPanoViewerMethods, + withSpinViewerMethods: withSpinViewerMethods, + updatePanoViewer: updatePanoViewer, + getValidProps: getValidProps, + generateCanvasKey: generateCanvasKey + }; + + /* + * Copyright (c) 2017 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + var View360 = {}; + merge(View360, PanoViewer$1); + merge(View360, SpinViewer$1); + merge(View360, CFC); + + return View360; + +}))); +//# sourceMappingURL=view360.js.map diff --git a/dist/view360.js.map b/dist/view360.js.map new file mode 100644 index 000000000..868055b8a --- /dev/null +++ b/dist/view360.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.js","sources":["../src/version.ts","../src/utils/browser.ts","../src/utils/browserFeature.ts","../src/utils/math-util.ts","../src/YawPitchControl/utils.ts","../src/YawPitchControl/consts.ts","../src/YawPitchControl/input/lib/webvr-polyfill/math-util.ts","../src/YawPitchControl/input/lib/webvr-polyfill/util.ts","../src/YawPitchControl/input/lib/webvr-polyfill/pose-predictor.ts","../src/YawPitchControl/input/DeviceMotion.ts","../src/YawPitchControl/input/lib/webvr-polyfill/sensor-sample.ts","../src/YawPitchControl/input/lib/webvr-polyfill/complementary-filter.ts","../src/YawPitchControl/input/ComplementaryFilter.ts","../src/YawPitchControl/input/FusionPoseSensor.ts","../src/YawPitchControl/input/TiltMotionInput.ts","../src/YawPitchControl/ScreenRotationAngle.ts","../src/YawPitchControl/input/RotationPanInput.ts","../src/YawPitchControl/DeviceQuaternion.ts","../src/YawPitchControl/YawPitchControl.ts","../src/PanoViewer/consts.ts","../src/utils/utils.ts","../src/PanoImageRenderer/WebGLUtils.ts","../src/PanoImageRenderer/renderer/Renderer.ts","../src/PanoImageRenderer/renderer/CubeRenderer.ts","../src/PanoImageRenderer/renderer/CubeStripRenderer.ts","../src/PanoImageRenderer/renderer/SphereRenderer.ts","../src/PanoImageRenderer/renderer/CylinderRenderer.ts","../src/PanoImageRenderer/vr/VRManager.ts","../src/PanoImageRenderer/vr/XRManager.ts","../src/PanoImageRenderer/WebGLAnimator.ts","../src/PanoImageRenderer/PanoImageRenderer.ts","../src/PanoViewer/PanoViewer.ts","../src/SpinViewer/consts.ts","../src/SpinViewer/SpriteImage.ts","../src/SpinViewer/SpinViewer.ts","../src/cfc/withMethods.ts","../src/cfc/withPanoViewerMethods.ts","../src/cfc/withSpinViewerMethods.ts","../src/cfc/updatePanoViewer.ts","../src/cfc/utils.ts","../src/index.umd.ts"],"sourcesContent":["const VERSION = \"#__VERSION__#\";\n\nexport {\n VERSION\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","/**\n * Original Code\n * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js\n * Math Util\n * modified by egjs\n */\n/**\n * @fileoverview gl-matrix - High performance matrix and vector operations\n * @author Brandon Jones\n * @author Colin MacKenzie IV\n * @version 2.3.2\n */\n\n/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE. */\n\n// Some minimal math functionality borrowed from gl-Matrix and stripped down\n// for the purposes of this library.\n\nimport { vec2, vec3, quat } from \"gl-matrix\";\n\nimport { ValueOf } from \"../types/internal\";\n\nconst quatToVec3 = (quaternion: quat) => {\n const baseV = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(baseV, baseV, quaternion);\n return baseV;\n};\n\nconst toDegree = (a: number) => a * 180 / Math.PI;\n\nconst util: any = {};\n\nutil.isPowerOfTwo = (n: number) => n && (n & (n - 1)) === 0;\n\nutil.extractPitchFromQuat = (quaternion: quat) => {\n const baseV = quatToVec3(quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n};\n\nutil.hypot = Math.hypot || ((x: number, y: number) => Math.sqrt(x * x + y * y));\n\n// implement reference\n// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식\n// calculating angle between two vectors : http://darkpgmr.tistory.com/121\nconst ROTATE_CONSTANT: {\n PITCH_DELTA: 1;\n YAW_DELTA_BY_ROLL: 2;\n YAW_DELTA_BY_YAW: 3;\n} = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n};\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nconst getRotationDelta = (prevQ: quat, curQ: quat, rotateKind: ValueOf) => {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n // const coefficientD = -1 * vec3.dot(vecN, meshPoint1);\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance =\n coefficientA * crossVec[0] +\n coefficientB * crossVec[1] +\n coefficientC * crossVec[2];\n\n let thetaDirection;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return toDegree(deltaRadian);\n};\n\nconst angleBetweenVec2 = (v1: vec2, v2: vec2) => {\n const det = v1[0] * v2[1] - v2[0] * v1[1];\n const theta = -Math.atan2(det, vec2.dot(v1, v2));\n return theta;\n};\n\nutil.yawOffsetBetween = (viewDir: number, targetDir: number) => {\n const viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]);\n const targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]);\n\n vec2.normalize(viewDirXZ, viewDirXZ);\n vec2.normalize(targetDirXZ, targetDirXZ);\n\n const theta = -angleBetweenVec2(viewDirXZ, targetDirXZ);\n\n return theta;\n};\n\nutil.sign = (x: number) => Math.sign\n ? Math.sign(x)\n : (Number(x > 0) - Number(x < 0)) || +x;\n\nutil.toDegree = toDegree;\nutil.getRotationDelta = getRotationDelta;\nutil.angleBetweenVec2 = angleBetweenVec2;\n\nexport {\n util,\n ROTATE_CONSTANT\n};\n","import { quat } from \"gl-matrix\";\n\nimport {\n util as mathUtil,\n ROTATE_CONSTANT\n} from \"../utils/math-util\";\n\nexport const toAxis = (source, offset) => offset.reduce((acc, v, i) => {\n if (source[i]) {\n acc[source[i]] = v;\n }\n return acc;\n}, {});\n\nexport const getDeltaYaw = (prvQ: quat, curQ: quat) => {\n const yawDeltaByYaw = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(mathUtil.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nexport const getDeltaPitch = (prvQ: quat, curQ: quat) => {\n const pitchDelta = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n","import { userAgent } from \"../utils/browserFeature\";\n/**\n * Returns a number value indiciating the version of Chrome being used,\n * or otherwise `null` if not on Chrome.\n *\n * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19\n */\n/**\n * In Chrome m65, `devicemotion` events are broken but subsequently fixed\n * in 65.0.3325.148. Since many browsers use Chromium, ensure that\n * we scope this detection by branch and build numbers to provide\n * a proper fallback.\n * https://github.com/immersive-web/webvr-polyfill/issues/307\n */\nlet version = -1; // It should not be null because it will be compared with number\nlet branch: string | null = null;\nlet build: string | null = null;\n\nconst match = /Chrome\\/([0-9]+)\\.(?:[0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(userAgent);\n\nif (match) {\n version = parseInt(match[1], 10);\n branch = match[2];\n build = match[3];\n}\n\nconst CHROME_VERSION = version;\nconst IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === \"3325\" && parseInt(build!, 10) < 148;\nconst IS_ANDROID = /Android/i.test(userAgent);\n\nconst CONTROL_MODE_VR = 1;\nconst CONTROL_MODE_YAWPITCH = 2;\n\nconst TOUCH_DIRECTION_NONE = 1;\nconst TOUCH_DIRECTION_YAW = 2;\nconst TOUCH_DIRECTION_PITCH = 4;\nconst TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH;\n\n/* Const for MovableCoord */\nconst MC_DECELERATION = 0.0014;\nconst MC_MAXIMUM_DURATION = 1000;\nconst MC_BIND_SCALE = [0.20, 0.20];\n\nconst MIN_FIELD_OF_VIEW = 20;\nconst MAX_FIELD_OF_VIEW = 110;\nconst PAN_SCALE = 320;\n\n// const DELTA_THRESHOLD = 0.015;\n// const DELTA_THRESHOLD = 0.09; // Note4\n// const DELTA_THRESHOLD = 0.0825;\n// const DELTA_THRESHOLD = 0.075;\n// const DELTA_THRESHOLD = 0.06;\n// const DELTA_THRESHOLD = 0.045;\nconst DELTA_THRESHOLD = 0.0375; // Note2\n\nconst YAW_RANGE_HALF = 180;\nconst PITCH_RANGE_HALF = 90;\nconst CIRCULAR_PITCH_RANGE_HALF = 180;\nconst PINCH_EVENTS = \"pinchstart pinchmove pinchend\";\n\nconst KEYMAP = {\n LEFT_ARROW: 37,\n A: 65,\n UP_ARROW: 38,\n W: 87,\n RIGHT_ARROW: 39,\n D: 68,\n DOWN_ARROW: 40,\n S: 83\n};\n\nconst GYRO_MODE: {\n NONE: \"none\";\n YAWPITCH: \"yawPitch\";\n VR: \"VR\";\n} = {\n NONE: \"none\",\n YAWPITCH: \"yawPitch\",\n VR: \"VR\"\n};\n\nexport {\n GYRO_MODE,\n\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n\n TOUCH_DIRECTION_NONE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MIN_FIELD_OF_VIEW,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n DELTA_THRESHOLD,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n PINCH_EVENTS,\n KEYMAP,\n\n CHROME_VERSION,\n IS_CHROME_WITHOUT_DEVICE_MOTION,\n IS_ANDROID\n};\n","/* eslint-disable */\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { window as win } from \"../../../../utils/browser\";\n\nconst MathUtil = win.MathUtil || {};\n\nMathUtil.degToRad = Math.PI / 180;\nMathUtil.radToDeg = 180 / Math.PI;\n\n// Some minimal math functionality borrowed from THREE.Math and stripped down\n// for the purposes of this library.\n\n\nMathUtil.Vector2 = function( x, y ) {\n this.x = x || 0;\n this.y = y || 0;\n};\n\nMathUtil.Vector2.prototype = {\n constructor: MathUtil.Vector2,\n\n set: function( x, y ) {\n this.x = x;\n this.y = y;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n },\n\n subVectors: function( a, b ) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n\n return this;\n }\n};\n\nMathUtil.Vector3 = function( x, y, z ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n};\n\nMathUtil.Vector3.prototype = {\n constructor: MathUtil.Vector3,\n\n set: function( x, y, z ) {\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n\n return this;\n },\n\n length: function() {\n return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n },\n\n normalize: function() {\n const scalar = this.length();\n\n if ( scalar !== 0 ) {\n const invScalar = 1 / scalar;\n\n this.multiplyScalar(invScalar);\n } else {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n }\n\n return this;\n },\n\n multiplyScalar: function( scalar ) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n },\n\n applyQuaternion: function( q ) {\n const x = this.x;\n const y = this.y;\n const z = this.z;\n\n const qx = q.x;\n const qy = q.y;\n const qz = q.z;\n const qw = q.w;\n\n // calculate quat * vector\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = - qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n return this;\n },\n\n dot: function( v ) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n },\n\n crossVectors: function( a, b ) {\n const ax = a.x;\n const ay = a.y;\n const az = a.z;\n const bx = b.x;\n const by = b.y;\n const bz = b.z;\n\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n\n return this;\n }\n};\n\nMathUtil.Quaternion = function( x, y, z, w ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n this.w = ( w !== undefined ) ? w : 1;\n};\n\nMathUtil.Quaternion.prototype = {\n constructor: MathUtil.Quaternion,\n\n set: function( x, y, z, w ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n\n return this;\n },\n\n copy: function( quaternion ) {\n this.x = quaternion.x;\n this.y = quaternion.y;\n this.z = quaternion.z;\n this.w = quaternion.w;\n\n return this;\n },\n\n setFromEulerXYZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 + s1 * s2 * c3;\n this.w = c1 * c2 * c3 - s1 * s2 * s3;\n\n return this;\n },\n\n setFromEulerYXZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 - s1 * s2 * c3;\n this.w = c1 * c2 * c3 + s1 * s2 * s3;\n\n return this;\n },\n\n setFromAxisAngle: function( axis, angle ) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n // assumes axis is normalized\n\n const halfAngle = angle / 2;\n const s = Math.sin( halfAngle );\n\n this.x = axis.x * s;\n this.y = axis.y * s;\n this.z = axis.z * s;\n this.w = Math.cos( halfAngle );\n\n return this;\n },\n\n multiply: function( q ) {\n return this.multiplyQuaternions( this, q );\n },\n\n multiplyQuaternions: function( a, b ) {\n // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n const qax = a.x;\n const qay = a.y;\n const qaz = a.z;\n const qaw = a.w;\n const qbx = b.x;\n const qby = b.y;\n const qbz = b.z;\n const qbw = b.w;\n\n this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n return this;\n },\n\n inverse: function() {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n\n this.normalize();\n\n return this;\n },\n\n normalize: function() {\n let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n if ( l === 0 ) {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n this.w = 1;\n } else {\n l = 1 / l;\n\n this.x = this.x * l;\n this.y = this.y * l;\n this.z = this.z * l;\n this.w = this.w * l;\n }\n\n return this;\n },\n\n slerp: function( qb, t ) {\n if ( t === 0 ) return this;\n if ( t === 1 ) return this.copy( qb );\n\n const x = this.x;\n const y = this.y;\n const z = this.z;\n const w = this.w;\n\n // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n let cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;\n\n if ( cosHalfTheta < 0 ) {\n this.w = - qb.w;\n this.x = - qb.x;\n this.y = - qb.y;\n this.z = - qb.z;\n\n cosHalfTheta = - cosHalfTheta;\n } else {\n this.copy( qb );\n }\n\n if ( cosHalfTheta >= 1.0 ) {\n this.w = w;\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n }\n\n const halfTheta = Math.acos( cosHalfTheta );\n const sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n if ( Math.abs( sinHalfTheta ) < 0.001 ) {\n this.w = 0.5 * ( w + this.w );\n this.x = 0.5 * ( x + this.x );\n this.y = 0.5 * ( y + this.y );\n this.z = 0.5 * ( z + this.z );\n\n return this;\n }\n\n const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;\n const ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n this.w = ( w * ratioA + this.w * ratioB );\n this.x = ( x * ratioA + this.x * ratioB );\n this.y = ( y * ratioA + this.y * ratioB );\n this.z = ( z * ratioA + this.z * ratioB );\n\n return this;\n },\n\n setFromUnitVectors: function() {\n // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n // assumes direction vectors vFrom and vTo are normalized\n\n let v1;\n let r;\n const EPS = 0.000001;\n\n return function( vFrom, vTo ) {\n if ( v1 === undefined ) v1 = new MathUtil.Vector3();\n\n r = vFrom.dot( vTo ) + 1;\n\n if ( r < EPS ) {\n r = 0;\n\n if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n v1.set( - vFrom.y, vFrom.x, 0 );\n } else {\n v1.set( 0, - vFrom.z, vFrom.y );\n }\n } else {\n v1.crossVectors( vFrom, vTo );\n }\n\n this.x = v1.x;\n this.y = v1.y;\n this.z = v1.z;\n this.w = r;\n\n this.normalize();\n\n return this;\n };\n }()\n};\n\nexport default MathUtil;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tslint:disable: only-arrow-functions\n\nimport { window as win, document as doc, navigator as nav } from \"../../../../utils/browser\";\n\nconst userAgent = nav?.userAgent ?? \"\";\nconst Util = (win ).Util || {};\n\nUtil.MIN_TIMESTEP = 0.001;\nUtil.MAX_TIMESTEP = 1;\n\nUtil.base64 = function(mimeType, base64) {\n return \"data:\" + mimeType + \";base64,\" + base64;\n};\n\nUtil.clamp = function(value, min, max) {\n return Math.min(Math.max(min, value), max);\n};\n\nUtil.lerp = function(a, b, t) {\n return a + ((b - a) * t);\n};\n\nUtil.isIOS = (function() {\n const isIOS = /iPad|iPhone|iPod/.test(nav?.platform);\n return function() {\n return isIOS;\n };\n})();\n\nUtil.isWebViewAndroid = (function() {\n const isWebViewAndroid = userAgent.indexOf(\"Version\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1 &&\n userAgent.indexOf(\"Chrome\") !== -1;\n return function() {\n return isWebViewAndroid;\n };\n})();\n\nUtil.isSafari = (function() {\n const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n return function() {\n return isSafari;\n };\n})();\n\nUtil.isFirefoxAndroid = (function() {\n const isFirefoxAndroid = userAgent.indexOf(\"Firefox\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1;\n return function() {\n return isFirefoxAndroid;\n };\n})();\n\nUtil.isR7 = (function() {\n const isR7 = userAgent.indexOf(\"R7 Build\") !== -1;\n return function() {\n return isR7;\n };\n})();\n\nUtil.isLandscapeMode = function() {\n const rtn = (win.orientation === 90 || win.orientation === -90);\n return Util.isR7() ? !rtn : rtn;\n};\n\n// Helper method to validate the time steps of sensor timestamps.\nUtil.isTimestampDeltaValid = function(timestampDeltaS) {\n if (isNaN(timestampDeltaS)) {\n return false;\n }\n if (timestampDeltaS <= Util.MIN_TIMESTEP) {\n return false;\n }\n if (timestampDeltaS > Util.MAX_TIMESTEP) {\n return false;\n }\n return true;\n};\n\nUtil.getScreenWidth = function() {\n return Math.max(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.getScreenHeight = function() {\n return Math.min(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.requestFullscreen = function(element) {\n if (Util.isWebViewAndroid()) {\n return false;\n }\n if (element.requestFullscreen) {\n element.requestFullscreen();\n } else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n } else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n } else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.exitFullscreen = function() {\n if (doc.exitFullscreen) {\n doc.exitFullscreen();\n } else if (doc.webkitExitFullscreen) {\n doc.webkitExitFullscreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.getFullscreenElement = function() {\n return doc.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n};\n\nUtil.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {\n // No error checking for brevity.\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n const program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n\n for (const attribName in attribLocationMap)\n gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);\n\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n};\n\nUtil.getProgramUniforms = function(gl, program) {\n const uniforms = {};\n const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n let uniformName = \"\";\n for (let i = 0; i < uniformCount; i++) {\n const uniformInfo = gl.getActiveUniform(program, i);\n uniformName = uniformInfo.name.replace(\"[0]\", \"\");\n uniforms[uniformName] = gl.getUniformLocation(program, uniformName);\n }\n return uniforms;\n};\n\nUtil.orthoMatrix = function(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right);\n const bt = 1 / (bottom - top);\n const nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n};\n\nUtil.copyArray = function(source, dest) {\n for (let i = 0, n = source.length; i < n; i++) {\n dest[i] = source[i];\n }\n};\n\nUtil.isMobile = function() {\n let check = false;\n (function(a) {\n if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))check = true;\n })(userAgent || nav?.vendor || win.opera);\n return check;\n};\n\nUtil.extend = function(dest, src) {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n dest[key] = src[key];\n }\n }\n\n return dest;\n};\n\nUtil.safariCssSizeWorkaround = function(canvas) {\n // TODO(smus): Remove this workaround when Safari for iOS is fixed.\n // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).\n //\n // \"To the last I grapple with thee;\n // from hell's heart I stab at thee;\n // for hate's sake I spit my last breath at thee.\"\n // -- Moby Dick, by Herman Melville\n if (Util.isIOS()) {\n const width = canvas.style.width;\n const height = canvas.style.height;\n canvas.style.width = (parseInt(width) + 1) + \"px\";\n canvas.style.height = (parseInt(height)) + \"px\";\n setTimeout(function() {\n canvas.style.width = width;\n canvas.style.height = height;\n }, 100);\n }\n\n // Debug only.\n win.Util = Util;\n win.canvas = canvas;\n};\n\nUtil.isDebug = function() {\n return Util.getQueryParameter(\"debug\");\n};\n\nUtil.getQueryParameter = function(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n const results = regex.exec(location.search);\n return results === null ? \"\" : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n};\n\nUtil.frameDataFromPose = (function() {\n const piOver180 = Math.PI / 180.0;\n const rad45 = Math.PI * 0.25;\n\n // Borrowed from glMatrix.\n function mat4_perspectiveFromFieldOfView(out, fov, near, far) {\n const upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45);\n const downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45);\n const leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45);\n const rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45);\n const xScale = 2.0 / (leftTan + rightTan);\n const yScale = 2.0 / (upTan + downTan);\n\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = ((upTan - downTan) * yScale * 0.5);\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = (far * near) / (near - far);\n out[15] = 0.0;\n return out;\n }\n\n function mat4_fromRotationTranslation(out, q, v) {\n // Quaternion math\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n\n return out;\n }\n\n function mat4_translate(out, a, v) {\n const x = v[0];\n const y = v[1];\n const z = v[2];\n let a00;\n let a01;\n let a02;\n let a03;\n let a10;\n let a11;\n let a12;\n let a13;\n let a20;\n let a21;\n let a22;\n let a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];\n a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];\n a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];\n\n out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;\n out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;\n out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;\n\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n }\n\n function mat4_invert(out, a) {\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n }\n\n const defaultOrientation = new Float32Array([0, 0, 0, 1]);\n const defaultPosition = new Float32Array([0, 0, 0]);\n\n function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {\n mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);\n\n const orientation = pose.orientation || defaultOrientation;\n const position = pose.position || defaultPosition;\n\n mat4_fromRotationTranslation(view, orientation, position);\n if (parameters)\n mat4_translate(view, view, parameters.offset);\n mat4_invert(view, view);\n }\n\n return function(frameData, pose, vrDisplay) {\n if (!frameData || !pose)\n return false;\n\n frameData.pose = pose;\n frameData.timestamp = pose.timestamp;\n\n updateEyeMatrices(\n frameData.leftProjectionMatrix, frameData.leftViewMatrix,\n pose, vrDisplay.getEyeParameters(\"left\"), vrDisplay);\n updateEyeMatrices(\n frameData.rightProjectionMatrix, frameData.rightViewMatrix,\n pose, vrDisplay.getEyeParameters(\"right\"), vrDisplay);\n\n return true;\n };\n})();\n\nUtil.isInsideCrossDomainIFrame = function() {\n const isFramed = (win.self !== win.top);\n const refDomain = Util.getDomainFromUrl(doc.referrer);\n const thisDomain = Util.getDomainFromUrl(win.location.href);\n\n return isFramed && (refDomain !== thisDomain);\n};\n\n// From http://stackoverflow.com/a/23945027.\nUtil.getDomainFromUrl = function(url) {\n let domain;\n // Find & remove protocol (http, ftp, etc.) and get domain.\n if (url.indexOf(\"://\") > -1) {\n domain = url.split(\"/\")[2];\n } else {\n domain = url.split(\"/\")[0];\n }\n\n // find & remove port number\n domain = domain.split(\":\")[0];\n\n return domain;\n};\n\nexport default Util;\n","/* eslint-disable */\n\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * Given an orientation and the gyroscope data, predicts the future orientation\n * of the head. This makes rendering appear faster.\n *\n * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf\n * @param {Number} predictionTimeS time from head movement to the appearance of\n * the corresponding image.\n */\nclass PosePredictor {\n public predictionTimeS;\n public previousQ;\n public previousTimestampS;\n public deltaQ;\n public outQ;\n\n public constructor(predictionTimeS) {\n this.predictionTimeS = predictionTimeS;\n\n // The quaternion corresponding to the previous state.\n this.previousQ = new MathUtil.Quaternion();\n // Previous time a prediction occurred.\n this.previousTimestampS = null;\n\n // The delta quaternion that adjusts the current pose.\n this.deltaQ = new MathUtil.Quaternion();\n // The output quaternion.\n this.outQ = new MathUtil.Quaternion();\n }\n\n public getPrediction(currentQ, gyro, timestampS) {\n if (!this.previousTimestampS) {\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n return currentQ;\n }\n\n // Calculate axis and angle based on gyroscope rotation rate data.\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n\n const angularSpeed = gyro.length();\n\n // If we're rotating slowly, don't do prediction.\n if (angularSpeed < MathUtil.degToRad * 20) {\n if (Util.isDebug()) {\n console.log(\"Moving slowly, at %s deg/s: no prediction\",\n (MathUtil.radToDeg * angularSpeed).toFixed(1));\n }\n this.outQ.copy(currentQ);\n this.previousQ.copy(currentQ);\n return this.outQ;\n }\n\n // Get the predicted angle based on the time delta and latency.\n const deltaT = timestampS - this.previousTimestampS;\n const predictAngle = angularSpeed * this.predictionTimeS;\n\n this.deltaQ.setFromAxisAngle(axis, predictAngle);\n this.outQ.copy(this.previousQ);\n this.outQ.multiply(this.deltaQ);\n\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n\n return this.outQ;\n }\n}\n\nexport default PosePredictor;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3 } from \"gl-matrix\";\n\nimport { Mutable } from \"../../types/internal\";\nimport { window } from \"../../utils/browser\";\nimport { IS_CHROME_WITHOUT_DEVICE_MOTION, IS_ANDROID } from \"../consts\";\n\nconst STILLNESS_THRESHOLD = 200; // millisecond\n\nexport default class DeviceMotion extends Component<{\n devicemotion: {\n inputEvent: DeviceMotionEvent | {\n deviceorientation: {\n alpha: number;\n beta: number;\n gamma: number;\n };\n };\n };\n}> {\n public readonly isWithoutDeviceMotion: boolean;\n public readonly isAndroid: boolean;\n\n public stillGyroVec: vec3;\n public rawGyroVec: vec3;\n public adjustedGyroVec: vec3;\n public lastDevicemotionTimestamp: number;\n\n private _timer: number;\n private _isEnabled: boolean;\n\n public constructor() {\n super();\n this._onDeviceMotion = this._onDeviceMotion.bind(this);\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onChromeWithoutDeviceMotion = this._onChromeWithoutDeviceMotion.bind(this);\n\n this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION;\n this.isAndroid = IS_ANDROID;\n\n this.stillGyroVec = vec3.create();\n this.rawGyroVec = vec3.create();\n this.adjustedGyroVec = vec3.create();\n\n this._timer = -1;\n\n this.lastDevicemotionTimestamp = 0;\n this._isEnabled = false;\n this.enable();\n }\n\n public enable() {\n if (this.isAndroid) {\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n }\n if (this.isWithoutDeviceMotion) {\n window.addEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n } else {\n window.addEventListener(\"devicemotion\", this._onDeviceMotion);\n }\n this._isEnabled = true;\n }\n\n public disable() {\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n window.removeEventListener(\"devicemotion\", this._onDeviceMotion);\n this._isEnabled = false;\n }\n\n private _onChromeWithoutDeviceMotion(e: DeviceOrientationEvent) {\n let {alpha, beta, gamma} = e;\n\n // There is deviceorientation event trigged with empty values\n // on Headless Chrome.\n if (alpha === null) {\n return;\n }\n\n // convert to radian\n alpha = (alpha || 0) * Math.PI / 180;\n beta = (beta || 0) * Math.PI / 180;\n gamma = (gamma || 0) * Math.PI / 180;\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: {\n deviceorientation: {\n alpha,\n beta,\n gamma: -gamma\n }\n }\n }));\n }\n\n private _onDeviceOrientation() {\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timer = window.setTimeout(() => {\n if ((new Date().getTime() - this.lastDevicemotionTimestamp) < STILLNESS_THRESHOLD) {\n vec3.copy(this.stillGyroVec, this.rawGyroVec);\n }\n }, STILLNESS_THRESHOLD);\n }\n\n private _onDeviceMotion(e: DeviceMotionEvent) {\n // desktop chrome triggers devicemotion event with empthy sensor values.\n // Those events should ignored.\n const isGyroSensorAvailable = !(e.rotationRate!.alpha == null);\n const isGravitySensorAvailable = !(e.accelerationIncludingGravity!.x == null);\n\n if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) {\n return;\n }\n\n const devicemotionEvent = {...e} as Mutable;\n\n devicemotionEvent.interval = e.interval;\n devicemotionEvent.timeStamp = e.timeStamp;\n devicemotionEvent.type = e.type;\n devicemotionEvent.rotationRate = {\n alpha: e.rotationRate!.alpha,\n beta: e.rotationRate!.beta,\n gamma: e.rotationRate!.gamma\n };\n devicemotionEvent.accelerationIncludingGravity = {\n x: e.accelerationIncludingGravity!.x,\n y: e.accelerationIncludingGravity!.y,\n z: e.accelerationIncludingGravity!.z\n };\n devicemotionEvent.acceleration = {\n x: e.acceleration!.x,\n y: e.acceleration!.y,\n z: e.acceleration!.z\n };\n\n if (this.isAndroid) {\n vec3.set(\n this.rawGyroVec,\n e.rotationRate!.alpha || 0,\n e.rotationRate!.beta || 0,\n e.rotationRate!.gamma || 0);\n vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec);\n this.lastDevicemotionTimestamp = new Date().getTime();\n\n (devicemotionEvent as any).adjustedRotationRate = {\n alpha: this.adjustedGyroVec[0],\n beta: this.adjustedGyroVec[1],\n gamma: this.adjustedGyroVec[2]};\n }\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: devicemotionEvent\n }));\n }\n}\n","class SensorSample {\n public sample;\n public timestampS;\n\n public constructor(sample?, timestampS?) {\n this.set(sample, timestampS);\n }\n\n public set(sample, timestampS) {\n this.sample = sample;\n this.timestampS = timestampS;\n }\n\n public copy(sensorSample) {\n this.set(sensorSample.sample, sensorSample.timestampS);\n }\n}\n\nexport default SensorSample;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SensorSample from \"./sensor-sample\";\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * An implementation of a simple complementary filter, which fuses gyroscope and\n * accelerometer data from the 'devicemotion' event.\n *\n * Accelerometer data is very noisy, but stable over the long term.\n * Gyroscope data is smooth, but tends to drift over the long term.\n *\n * This fusion is relatively simple:\n * 1. Get orientation estimates from accelerometer by applying a low-pass filter\n * on that data.\n * 2. Get orientation estimates from gyroscope by integrating over time.\n * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the\n * short term.\n */\nclass ComplementaryFilter {\n public kFilter;\n public currentAccelMeasurement;\n public currentGyroMeasurement;\n public previousGyroMeasurement;\n public filterQ;\n public previousFilterQ;\n public accelQ;\n public isOrientationInitialized;\n public estimatedGravity;\n public measuredGravity;\n public gyroIntegralQ;\n\n constructor(kFilter) {\n this.kFilter = kFilter;\n\n // Raw sensor measurements.\n this.currentAccelMeasurement = new SensorSample();\n this.currentGyroMeasurement = new SensorSample();\n this.previousGyroMeasurement = new SensorSample();\n\n // Set default look direction to be in the correct direction.\n if (Util.isIOS()) {\n this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);\n } else {\n this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);\n }\n this.previousFilterQ = new MathUtil.Quaternion();\n this.previousFilterQ.copy(this.filterQ);\n\n // Orientation based on the accelerometer.\n this.accelQ = new MathUtil.Quaternion();\n // Whether or not the orientation has been initialized.\n this.isOrientationInitialized = false;\n // Running estimate of gravity based on the current orientation.\n this.estimatedGravity = new MathUtil.Vector3();\n // Measured gravity based on accelerometer.\n this.measuredGravity = new MathUtil.Vector3();\n\n // Debug only quaternion of gyro-based orientation.\n this.gyroIntegralQ = new MathUtil.Quaternion();\n }\n\n public addAccelMeasurement(vector, timestampS) {\n this.currentAccelMeasurement.set(vector, timestampS);\n }\n\n public addGyroMeasurement = function(vector, timestampS) {\n this.currentGyroMeasurement.set(vector, timestampS);\n\n const deltaT = timestampS - this.previousGyroMeasurement.timestampS;\n if (Util.isTimestampDeltaValid(deltaT)) {\n this.run_();\n }\n\n this.previousGyroMeasurement.copy(this.currentGyroMeasurement);\n };\n\n public getOrientation() {\n return this.filterQ;\n }\n\n public run_() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n if (Util.isDebug()) {\n console.log(\"Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)\",\n MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),\n (this.estimatedGravity.x).toFixed(1),\n (this.estimatedGravity.y).toFixed(1),\n (this.estimatedGravity.z).toFixed(1),\n (this.measuredGravity.x).toFixed(1),\n (this.measuredGravity.y).toFixed(1),\n (this.measuredGravity.z).toFixed(1));\n }\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n }\n\n private accelToQuaternion_(accel) {\n const normAccel = new MathUtil.Vector3();\n normAccel.copy(accel);\n normAccel.normalize();\n const quat = new MathUtil.Quaternion();\n quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);\n quat.inverse();\n return quat;\n }\n\n private gyroToQuaternionDelta_(gyro, dt) {\n // Extract axis and angle from the gyroscope data.\n const quat = new MathUtil.Quaternion();\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n quat.setFromAxisAngle(axis, gyro.length() * dt);\n return quat;\n }\n}\n\nexport default ComplementaryFilter;\n","import MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport ComplementaryFilter from \"./lib/webvr-polyfill/complementary-filter\";\n\nComplementaryFilter.prototype.run_ = function() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n\n if (!this.isFilterQuaternionInitialized) {\n this.isFilterQuaternionInitialized = true;\n }\n};\n\nComplementaryFilter.prototype.getOrientation = function() {\n if (this.isFilterQuaternionInitialized) {\n return this.filterQ;\n } else {\n return null;\n }\n};\n\nexport default ComplementaryFilter;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\n\nimport { window, IS_IOS, IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { CHROME_VERSION } from \"../consts\";\n\nimport PosePredictor from \"./lib/webvr-polyfill/pose-predictor\";\nimport MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport Util from \"./lib/webvr-polyfill/util\";\nimport DeviceMotion from \"./DeviceMotion\";\nimport ComplementaryFilter from \"./ComplementaryFilter\";\n\n\nconst K_FILTER = 0.98;\nconst PREDICTION_TIME_S = 0.040;\n\nexport default class FusionPoseSensor extends Component<{\n change: {\n quaternion: quat;\n };\n}> {\n public deviceMotion: DeviceMotion | null;\n public accelerometer: any;\n public gyroscope: any;\n public filter: ComplementaryFilter;\n public posePredictor: PosePredictor;\n public filterToWorldQ: any;\n public isFirefoxAndroid: boolean;\n public isIOS: boolean;\n public isChromeUsingDegrees: boolean;\n public inverseWorldToScreenQ: any;\n public worldToScreenQ: any;\n public originalPoseAdjustQ: any;\n public resetQ: any;\n public deviceOrientationFixQ: any;\n public predictedQ: any;\n public previousTimestampS: number;\n\n private _isEnabled: boolean;\n private _deviceOrientationQ: any;\n private _prevOrientation: quat;\n private _alpha: number;\n\n public constructor() {\n super();\n\n this.deviceMotion = new DeviceMotion();\n\n this.accelerometer = new MathUtil.Vector3();\n this.gyroscope = new MathUtil.Vector3();\n\n this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);\n this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);\n\n this.filter = new ComplementaryFilter(K_FILTER);\n this.posePredictor = new PosePredictor(PREDICTION_TIME_S);\n\n this.filterToWorldQ = new MathUtil.Quaternion();\n\n this.isFirefoxAndroid = Util.isFirefoxAndroid();\n // This includes iPhone & iPad(both desktop and mobile mode) ref #326\n this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP;\n\n // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18\n this.isChromeUsingDegrees = CHROME_VERSION >= 66;\n\n this._isEnabled = false;\n\n // Set the filter to world transform, depending on OS.\n if (this.isIOS) {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);\n } else {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n this.inverseWorldToScreenQ = new MathUtil.Quaternion();\n this.worldToScreenQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),\n -window.orientation * Math.PI / 180);\n\n this._setScreenTransform();\n // Adjust this filter for being in landscape mode.\n if (Util.isLandscapeMode()) {\n this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);\n }\n\n // Keep track of a reset transform for resetSensor.\n this.resetQ = new MathUtil.Quaternion();\n\n this.deviceMotion.on(\"devicemotion\", this._onDeviceMotionChange);\n this.enable();\n }\n\n public enable() {\n if (this.isEnabled()) {\n return;\n }\n this.deviceMotion!.enable();\n this._isEnabled = true;\n window.addEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public disable() {\n if (!this.isEnabled()) {\n return;\n }\n this.deviceMotion!.disable();\n this._isEnabled = false;\n window.removeEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public isEnabled() {\n return this._isEnabled;\n }\n\n public destroy() {\n this.disable();\n this.deviceMotion = null;\n }\n\n public getOrientation() {\n let orientation;\n\n // Hack around using deviceorientation instead of devicemotion\n if (this.deviceMotion!.isWithoutDeviceMotion && this._deviceOrientationQ) {\n this.deviceOrientationFixQ = this.deviceOrientationFixQ || (() => {\n const y = new MathUtil.Quaternion()\n .setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -this._alpha);\n\n return y;\n })();\n\n orientation = this._deviceOrientationQ;\n const out = new MathUtil.Quaternion();\n\n out.copy(orientation);\n out.multiply(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.worldToScreenQ);\n out.multiplyQuaternions(this.deviceOrientationFixQ, out);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n } else {\n // Convert from filter space to the the same system used by the\n // deviceorientation event.\n orientation = this.filter.getOrientation();\n\n if (!orientation) {\n return null;\n }\n\n const out = this._convertFusionToPredicted(orientation);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n }\n }\n\n private _triggerChange() {\n const orientation = this.getOrientation();\n\n // if orientation is not prepared. don't trigger change event\n if (!orientation) {\n return;\n }\n\n if (!this._prevOrientation) {\n this._prevOrientation = orientation;\n return;\n }\n\n if (quat.equals(this._prevOrientation, orientation)) {\n return;\n }\n\n this.trigger(new ComponentEvent(\"change\", { quaternion: orientation }));\n }\n\n private _convertFusionToPredicted(orientation: quat) {\n // Predict orientation.\n this.predictedQ =\n this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);\n\n // Convert to THREE coordinate system: -Z forward, Y up, X right.\n const out = new MathUtil.Quaternion();\n\n out.copy(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.predictedQ);\n out.multiply(this.worldToScreenQ);\n\n return out;\n }\n\n private _onDeviceMotionChange({ inputEvent }) {\n const deviceorientation = inputEvent.deviceorientation;\n const deviceMotion = inputEvent;\n const accGravity = deviceMotion.accelerationIncludingGravity;\n const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;\n let timestampS = deviceMotion.timeStamp / 1000;\n\n if (deviceorientation) {\n if (!this._alpha) {\n this._alpha = deviceorientation.alpha;\n }\n this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();\n this._deviceOrientationQ.setFromEulerYXZ(\n deviceorientation.beta,\n deviceorientation.alpha,\n deviceorientation.gamma\n );\n\n this._triggerChange();\n } else {\n // Firefox Android timeStamp returns one thousandth of a millisecond.\n if (this.isFirefoxAndroid) {\n timestampS /= 1000;\n }\n\n this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);\n this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);\n\n // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate`\n // is reported in degrees, so we first convert to radians.\n if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) {\n this.gyroscope.multiplyScalar(Math.PI / 180);\n }\n\n this.filter.addAccelMeasurement(this.accelerometer, timestampS);\n this.filter.addGyroMeasurement(this.gyroscope, timestampS);\n\n this._triggerChange();\n\n this.previousTimestampS = timestampS;\n }\n }\n\n private _onScreenOrientationChange() {\n this._setScreenTransform();\n }\n\n private _setScreenTransform() {\n this.worldToScreenQ.set(0, 0, 0, 1);\n\n const orientation = window.orientation;\n\n switch (orientation) {\n case 0:\n break;\n case 90:\n case -90:\n case 180:\n this.worldToScreenQ\n .setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI);\n break;\n default:\n break;\n }\n this.inverseWorldToScreenQ.copy(this.worldToScreenQ);\n this.inverseWorldToScreenQ.inverse();\n }\n}\n","import Component from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\n\nimport { toAxis } from \"../utils\";\nimport { util, ROTATE_CONSTANT } from \"../../utils/math-util\";\n\nimport FusionPoseSensor from \"./FusionPoseSensor\";\n\nconst getDeltaYaw = (prvQ: quat, curQ: quat): number => {\n const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(util.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nconst getDeltaPitch = (prvQ: quat, curQ: quat): number => {\n const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport default class TiltMotionInput extends Component<{}> {\n public element: HTMLElement;\n public options: { scale: number; threshold: number };\n public fusionPoseSensor: FusionPoseSensor | null;\n public axes: string[];\n public observer: InputTypeObserver | null;\n\n private _prevQuaternion: quat | null;\n private _quaternion: quat | null;\n\n public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {\n super();\n this.element = el;\n\n this._prevQuaternion = null;\n this._quaternion = null;\n\n this.fusionPoseSensor = null;\n\n this.options = {\n ...{\n scale: 1,\n threshold: 0\n }, ...options\n };\n\n this._onPoseChange = this._onPoseChange.bind(this);\n }\n\n public mapAxes(axes: string[]) {\n this.axes = axes;\n }\n\n public connect(observer: InputTypeObserver) {\n if (this.observer) {\n return this;\n }\n this.observer = observer;\n this.fusionPoseSensor = new FusionPoseSensor();\n this.fusionPoseSensor.enable();\n this._attachEvent();\n return this;\n }\n\n public disconnect() {\n if (!this.observer) {\n return this;\n }\n\n this._dettachEvent();\n this.fusionPoseSensor!.disable();\n this.fusionPoseSensor!.destroy();\n this.fusionPoseSensor = null;\n this.observer = null;\n return this;\n }\n\n public destroy() {\n this.disconnect();\n (this.element as any) = null;\n (this.options as any) = null;\n (this.axes as any) = null;\n this._prevQuaternion = null;\n this._quaternion = null;\n }\n\n private _onPoseChange(event) {\n if (!this._prevQuaternion) {\n this._prevQuaternion = quat.clone(event.quaternion);\n this._quaternion = quat.clone(event.quaternion);\n return;\n }\n\n quat.copy(this._prevQuaternion, this._quaternion!);\n quat.copy(this._quaternion!, event.quaternion);\n\n this.observer!.change(this, event, toAxis(this.axes, [\n getDeltaYaw(this._prevQuaternion, this._quaternion as quat),\n getDeltaPitch(this._prevQuaternion, this._quaternion as quat)\n ]));\n }\n\n private _attachEvent() {\n this.fusionPoseSensor!.on(\"change\", this._onPoseChange);\n }\n\n private _dettachEvent() {\n this.fusionPoseSensor!.off(\"change\", this._onPoseChange);\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport { window } from \"../utils/browser\";\n\n// Singleton\nlet screenRotationAngleInst: ScreenRotationAngle | null = null;\nlet refCount = 0;\n\nexport default class ScreenRotationAngle {\n private _spinR: number;\n private _screenOrientationAngle: number;\n\n public constructor() {\n refCount++;\n\n if (screenRotationAngleInst) {\n return screenRotationAngleInst;\n }\n /* eslint-disable */\n screenRotationAngleInst = this;\n /* eslint-enable */\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n\n this._spinR = 0;\n\n this._screenOrientationAngle = 0;\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.addEventListener(\"orientationchange\", this._onOrientationChange);\n }\n\n public getRadian() {\n // Join with screen orientation\n // this._testVal = this._spinR + \", \" + this._screenOrientationAngle + \", \" + window.orientation;\n return this._spinR + glMatrix.toRadian(this._screenOrientationAngle);\n }\n\n public unref() {\n if (--refCount > 0) {\n return;\n }\n\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"orientationchange\", this._onOrientationChange);\n\n this._spinR = 0;\n this._screenOrientationAngle = 0;\n /* eslint-disable */\n screenRotationAngleInst = null;\n /* eslint-enable */\n refCount = 0;\n }\n\n private _onDeviceOrientation(e: DeviceOrientationEvent) {\n if (e.beta === null || e.gamma === null) {\n // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it.\n return;\n }\n\n // Radian\n const betaR = glMatrix.toRadian(e.beta);\n const gammaR = glMatrix.toRadian(e.gamma);\n\n /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */\n this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR));\n }\n\n private _onOrientationChange() {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientationAngle = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n /* iOS */\n this._screenOrientationAngle = window.orientation >= 0 ?\n window.orientation : 360 + (window.orientation as number);\n }\n }\n}\n","import Axes, { PanInput } from \"@egjs/axes\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\nimport { PanInputOption } from \"@egjs/axes/declaration/inputType/PanInput\";\n\nimport ScreenRotationAngle from \"../ScreenRotationAngle\";\n\n/**\n * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle.\n *\n * The reason for using this function is that in VR mode,\n * the roll angle is adjusted in the direction opposite to the screen rotation angle.\n *\n * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move.\n * @extends PanInput\n */\nexport default class RotationPanInput extends PanInput {\n private _useRotation: boolean;\n private _screenRotationAngle: ScreenRotationAngle | null;\n private _userDirection: number;\n\n /**\n * Constructor\n * @private\n * @param {HTMLElement} el target element\n * @param {Object} [options] The option object\n * @param {Boolean} [options.useRotation] Whether to use rotation(or VR)\n */\n public constructor(el: HTMLElement, options: Partial<{ useRotation: boolean } & PanInputOption> = {}) {\n super(el, options);\n\n this._useRotation = false;\n this._screenRotationAngle = null;\n\n this.setUseRotation(!!(options && options.useRotation));\n\n this._userDirection = Axes.DIRECTION_ALL;\n }\n\n public setUseRotation(useRotation: boolean) {\n this._useRotation = useRotation;\n\n if (this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n this._screenRotationAngle = null;\n }\n\n if (this._useRotation) {\n this._screenRotationAngle = new ScreenRotationAngle();\n }\n }\n\n public connect(observer: InputTypeObserver) {\n // User intetened direction\n this._userDirection = this._direction;\n\n // In VR Mode, Use ALL direction if direction is not none\n // Because horizontal and vertical is changed dynamically by screen rotation.\n // this._direction is used to initialize hammerjs\n if (this._useRotation && (this._direction & Axes.DIRECTION_ALL)) {\n this._direction = Axes.DIRECTION_HORIZONTAL;\n }\n\n return super.connect(observer);\n }\n\n public destroy() {\n if (this._useRotation && this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n }\n\n super.destroy();\n }\n\n protected _getOffset(properties: number[], useDirection: boolean[]) {\n if (this._useRotation === false) {\n return super._getOffset(properties, useDirection);\n }\n\n const offset = super._getOffset(properties, [true, true]);\n const newOffset = [0, 0];\n\n const theta = this._screenRotationAngle!.getRadian();\n\n const cosTheta = Math.cos(theta);\n const sinTheta = Math.sin(theta);\n\n // RotateZ\n newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta;\n newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta;\n\n // Use only user allowed direction.\n if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) {\n newOffset[0] = 0;\n } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) {\n newOffset[1] = 0;\n }\n\n return newOffset;\n }\n}\n\n/**\n * Override getDirectionByAngle to return DIRECTION_ALL\n * Ref: https://github.com/naver/egjs-axes/issues/99\n *\n * But we obey axes's rule. If axes's rule is problem, let's apply following code.\n */\n// PanInput.getDirectionByAngle = function (angle, thresholdAngle) {\n// \treturn DIRECTION_ALL;\n// };\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3, glMatrix, quat } from \"gl-matrix\";\n\nimport FusionPoseSensor from \"./input/FusionPoseSensor\";\n\nconst Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0);\n\nexport default class DeviceQuaternion extends Component<{\n change: {\n isTrusted: boolean;\n };\n}> {\n private _fusionPoseSensor: FusionPoseSensor | null;\n private _quaternion: quat;\n\n public constructor() {\n super();\n\n this._fusionPoseSensor = new FusionPoseSensor();\n this._quaternion = quat.create();\n\n this._fusionPoseSensor.enable();\n this._fusionPoseSensor.on(\"change\", e => {\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(\"change\", { isTrusted: true }));\n });\n }\n\n public getCombinedQuaternion(yaw: number) {\n const yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw));\n const conj = quat.conjugate(quat.create(), this._quaternion);\n // Multiply pitch quaternion -> device quaternion -> yaw quaternion\n const outQ = quat.multiply(quat.create(), conj, yawQ);\n\n return outQ;\n }\n\n public destroy() {\n // detach all event handler\n this.off();\n\n if (this._fusionPoseSensor) {\n this._fusionPoseSensor.off();\n this._fusionPoseSensor.destroy();\n this._fusionPoseSensor = null;\n }\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PinchInput, MoveKeyInput, WheelInput } from \"@egjs/axes\";\nimport { vec2, quat, glMatrix } from \"gl-matrix\";\n\nimport { SUPPORT_TOUCH, SUPPORT_DEVICEMOTION } from \"../utils/browserFeature\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { ValueOf } from \"../types/internal\";\n\nimport TiltMotionInput from \"./input/TiltMotionInput\";\nimport RotationPanInput from \"./input/RotationPanInput\";\nimport DeviceQuaternion from \"./DeviceQuaternion\";\nimport {\n GYRO_MODE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n TOUCH_DIRECTION_NONE\n} from \"./consts\";\n\n\nconst DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF];\nconst DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF];\nconst CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF];\n\nexport interface YawPitchControlOptions {\n element: HTMLElement | null;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n touchDirection: number;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n aspectRatio: number;\n}\ninterface YawPitchControlEvents {\n change: ComponentEvent<{\n yaw: number;\n pitch: number;\n fov: number;\n quaternion: quat | null;\n targetElement: HTMLElement;\n isTrusted: boolean;\n }>;\n hold: ComponentEvent<{\n isTrusted: boolean;\n }>;\n animationEnd: ComponentEvent<{\n isTrusted: boolean;\n }>;\n}\n\n/**\n * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates.\n * @alias eg.YawPitchControl\n * @extends eg.Component\n *\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass YawPitchControl extends Component {\n public static VERSION = VERSION;\n // Expose DeviceOrientationControls sub module for test purpose\n public static CONTROL_MODE_VR = CONTROL_MODE_VR;\n public static CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH;\n public static TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL;\n public static TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW;\n public static TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH;\n public static TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE;\n\n public options: YawPitchControlOptions;\n\n private _element: HTMLElement | null;\n private _initialFov: number;\n private _enabled: boolean;\n private _isAnimating: boolean;\n private _deviceQuaternion: DeviceQuaternion | null;\n\n private _axes: Axes;\n private _axesPanInput: RotationPanInput;\n private _axesWheelInput: WheelInput;\n private _axesTiltMotionInput: TiltMotionInput | null;\n private _axesPinchInput: PinchInput | null;\n private _axesMoveKeyInput: MoveKeyInput;\n\n /**\n * @param {object} options The option object of the eg.YawPitch module\n * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module\n * @param {number} [options.yaw=0] initial yaw (degree)\n * @param {number} [options.pitch=0] initial pitch (degree)\n * @param {number} [options.fov=65] initial field of view (degree)\n * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown\n * @param {boolean} [options.useZoom=true] Indicates whether zoom is available\n * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled\n * @param {string} [config.gyroMode=yawPitch] Enables control through device motion.\n * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move)\n * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw\n * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch\n * @param {number[]} [options.fovRange=[30, 110] Range of FOV\n * @param {number} [options.aspectRatio=1] Aspect Ratio\n */\n public constructor(options: Partial) {\n super();\n this.options = {} as any;\n\n const opt = {\n ...{\n element: null,\n yaw: 0,\n pitch: 0,\n fov: 65,\n showPolePoint: false,\n useZoom: true,\n useKeyboard: true,\n gyroMode: GYRO_MODE.YAWPITCH,\n touchDirection: TOUCH_DIRECTION_ALL,\n yawRange: DEFAULT_YAW_RANGE,\n pitchRange: DEFAULT_PITCH_RANGE,\n fovRange: [30, 110],\n aspectRatio: 1 /* TODO: Need Mandatory? */\n }, ...options\n };\n\n this._element = opt.element;\n this._initialFov = opt.fov;\n this._enabled = false;\n this._isAnimating = false;\n this._deviceQuaternion = null;\n\n this._initAxes(opt);\n this.option(opt);\n }\n\n /**\n * Update Pan Scale\n *\n * Scale(Sensitivity) values of panning is related with fov and height.\n * If at least one of them is changed, this function need to be called.\n * @param {*} param\n */\n public updatePanScale(param: Partial<{\n height: number;\n }> = {}) {\n const fov = this._axes.get().fov;\n const areaHeight = param.height || parseInt(window.getComputedStyle(this._element!).height, 10);\n const scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight;\n\n this._axesPanInput.options.scale = [scale, scale];\n this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW;\n\n return this;\n }\n\n public option(): YawPitchControlOptions;\n public option(key: K): YawPitchControlOptions[K];\n public option(key: K, newValue: YawPitchControlOptions[K]): YawPitchControl;\n public option(newOptions: Partial): YawPitchControl;\n /*\n * Override component's option method\n * to call method for updating values which is affected by option change.\n *\n * @param {*} args\n */\n public option(key?: K | Partial, newValue?: YawPitchControlOptions[K]) {\n // Getter\n if (!key) {\n return this._getOptions();\n } else if (key && typeof key === \"string\" && typeof newValue === \"undefined\") {\n return this._getOptions(key);\n }\n\n // Setter\n let newOptions: Partial = {};\n let changedKeyList: string[] = []; // TODO: if value is not changed, then do not push on changedKeyList.\n\n if (typeof key === \"string\") {\n changedKeyList.push(key);\n newOptions[key] = newValue;\n } else {\n const options = key; // Retrieving object here\n changedKeyList = Object.keys(options);\n newOptions = {...options};\n }\n\n this._setOptions(this._getValidatedOptions(newOptions));\n this._applyOptions(changedKeyList);\n return this;\n }\n\n /**\n * Enable YawPitch functionality\n * @method eg.YawPitch#enable\n */\n public enable() {\n if (this._enabled) {\n return this;\n }\n\n this._enabled = true;\n\n // touchDirection is decided by parameter is valid string (Ref. Axes.connect)\n this._applyOptions(Object.keys(this.options));\n\n // TODO: Is this code is needed? Check later.\n this.updatePanScale();\n\n return this;\n }\n\n /**\n * Disable YawPitch functionality\n * @method eg.YawPitch#disable\n */\n public disable(persistOrientation: boolean = false) {\n if (!this._enabled) {\n return this;\n }\n\n // TODO: Check peristOrientation is needed!\n if (!persistOrientation) {\n this._resetOrientation();\n }\n this._axes.disconnect();\n this._enabled = false;\n return this;\n }\n\n /**\n * Set one or more of yaw, pitch, fov\n * @param {Object} coordinate yaw, pitch, fov\n * @param {Number} duration Animation duration. if it is above 0 then it's animated.\n */\n public lookAt({yaw, pitch, fov}, duration) {\n const pos = this._axes.get();\n\n const y = yaw === undefined ? 0 : yaw - pos.yaw;\n const p = pitch === undefined ? 0 : pitch - pos.pitch;\n const f = fov === undefined ? 0 : fov - pos.fov;\n\n // Allow duration of animation to have more than MC_MAXIMUM_DURATION.\n this._axes.options.maximumDuration = Infinity;\n\n this._axes.setBy({\n yaw: y,\n pitch: p,\n fov: f\n }, duration);\n }\n\n public getYawPitch() {\n const yawPitch = this._axes.get();\n\n return {\n yaw: yawPitch.yaw,\n pitch: yawPitch.pitch\n };\n }\n\n public getFov() {\n return this._axes.get().fov;\n }\n\n public getQuaternion() {\n const pos = this._axes.get();\n\n return this._deviceQuaternion!.getCombinedQuaternion(pos.yaw);\n }\n\n public shouldRenderWithQuaternion() {\n return this.options.gyroMode === GYRO_MODE.VR;\n }\n\n /**\n * Destroys objects\n */\n public destroy() {\n /* eslint-disable @typescript-eslint/no-unused-expressions */\n this._axes && this._axes.destroy();\n this._axesPanInput && this._axesPanInput.destroy();\n this._axesWheelInput && this._axesWheelInput.destroy();\n this._axesTiltMotionInput && this._axesTiltMotionInput.destroy();\n this._axesPinchInput && this._axesPinchInput.destroy();\n this._axesMoveKeyInput && this._axesMoveKeyInput.destroy();\n this._deviceQuaternion && this._deviceQuaternion.destroy();\n /* eslint-enable @typescript-eslint/no-unused-expressions */\n }\n\n private _initAxes(opt: YawPitchControlOptions) {\n const yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio);\n const pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint);\n const useRotation = opt.gyroMode === GYRO_MODE.VR;\n\n this._axesPanInput = new RotationPanInput(this._element!, {useRotation});\n this._axesWheelInput = new WheelInput(this._element, {scale: -4});\n this._axesTiltMotionInput = null;\n this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, {scale: -1}) : null;\n this._axesMoveKeyInput = new MoveKeyInput(this._element, {scale: [-6, 6]});\n\n this._axes = new Axes({\n yaw: {\n range: yRange,\n circular: this._isCircular(yRange),\n bounce: [0, 0]\n },\n pitch: {\n range: pRange,\n circular: this._isCircular(pRange),\n bounce: [0, 0]\n },\n fov: {\n range: opt.fovRange,\n circular: [false, false],\n bounce: [0, 0]\n }\n }, {\n deceleration: MC_DECELERATION,\n maximumDuration: MC_MAXIMUM_DURATION\n }, {\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }).on({\n // TODO: change event type after Axes event type inference update\n hold: (evt: any) => {\n // Restore maximumDuration not to be spin too mush.\n this._axes.options.maximumDuration = MC_MAXIMUM_DURATION;\n\n this.trigger(new ComponentEvent(\"hold\", { isTrusted: evt.isTrusted }));\n },\n change: (evt: any) => {\n if (evt.delta.fov !== 0) {\n this._updateControlScale(evt);\n this.updatePanScale();\n }\n this._triggerChange(evt);\n },\n release: evt => {\n this._triggerChange(evt);\n },\n animationEnd: (evt: any) => {\n this.trigger(new ComponentEvent(\"animationEnd\", { isTrusted: evt.isTrusted }));\n }\n });\n }\n\n private _getValidatedOptions(newOptions: Partial) {\n if (newOptions.yawRange) {\n newOptions.yawRange =\n this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio);\n }\n if (newOptions.pitchRange) {\n newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov);\n }\n return newOptions;\n }\n\n private _getOptions(): YawPitchControlOptions;\n private _getOptions(key: K): YawPitchControlOptions[K];\n private _getOptions(key?: K) {\n let value;\n\n if (typeof key === \"string\") {\n value = this.options[key];\n } else if (arguments.length === 0) {\n value = this.options;\n }\n return value;\n }\n\n private _setOptions(options: Partial): void {\n for (const key in options) {\n this.options[key] = options[key];\n }\n }\n\n private _applyOptions(keys: string[]) {\n const options = this.options;\n const axes = this._axes;\n const isVR = options.gyroMode === GYRO_MODE.VR;\n const isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH;\n // If it's VR mode, restrict user interaction to yaw direction only\n const touchDirection = isVR ?\n (TOUCH_DIRECTION_YAW & options.touchDirection) :\n options.touchDirection;\n\n // If one of below is changed, call updateControlScale()\n if (keys.some(key =>\n key === \"showPolePoint\" || key === \"fov\" || key === \"aspectRatio\" ||\n key === \"yawRange\" || key === \"pitchRange\"\n )) {\n // If fov is changed, update pan scale\n if (keys.indexOf(\"fov\") >= 0) {\n axes.setTo({\"fov\": options.fov});\n this.updatePanScale();\n }\n\n this._updateControlScale();\n }\n\n if (keys.some(key => key === \"fovRange\")) {\n const fovRange = options.fovRange;\n const prevFov = axes.get().fov;\n let nextFov = axes.get().fov;\n\n vec2.copy(axes.axis.fov.range as vec2, fovRange as vec2);\n\n if (nextFov < fovRange[0]) {\n nextFov = fovRange[0];\n } else if (prevFov > fovRange[1]) {\n nextFov = fovRange[1];\n }\n\n if (prevFov !== nextFov) {\n axes.setTo({\n fov: nextFov\n }, 0);\n this._updateControlScale();\n this.updatePanScale();\n }\n }\n\n if (keys.some(key => key === \"gyroMode\") && SUPPORT_DEVICEMOTION) {\n // Disconnect first\n if (this._axesTiltMotionInput) {\n this._axes.disconnect(this._axesTiltMotionInput);\n this._axesTiltMotionInput.destroy();\n this._axesTiltMotionInput = null;\n }\n\n if (this._deviceQuaternion) {\n this._deviceQuaternion.destroy();\n this._deviceQuaternion = null;\n }\n\n if (isVR) {\n this._initDeviceQuaternion();\n } else if (isYawPitch) {\n this._axesTiltMotionInput = new TiltMotionInput(this._element!);\n this._axes.connect([\"yaw\", \"pitch\"], this._axesTiltMotionInput);\n }\n\n this._axesPanInput.setUseRotation(isVR);\n }\n\n if (keys.some(key => key === \"useKeyboard\")) {\n const useKeyboard = options.useKeyboard;\n\n if (useKeyboard) {\n axes.connect([\"yaw\", \"pitch\"], this._axesMoveKeyInput);\n } else {\n axes.disconnect(this._axesMoveKeyInput);\n }\n }\n\n if (keys.some(key => key === \"useZoom\")) {\n const useZoom = options.useZoom;\n\n // Disconnect first\n axes.disconnect(this._axesWheelInput);\n if (useZoom) {\n axes.connect([\"fov\"], this._axesWheelInput);\n }\n }\n\n this._togglePinchInputByOption(options.touchDirection, options.useZoom);\n\n if (keys.some(key => key === \"touchDirection\") && this._enabled) {\n this._enableTouch(touchDirection);\n }\n }\n\n private _togglePinchInputByOption(touchDirection: YawPitchControlOptions[\"touchDirection\"], useZoom: boolean) {\n if (this._axesPinchInput) {\n // disconnect first\n this._axes.disconnect(this._axesPinchInput);\n\n // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll.\n if (\n useZoom &&\n touchDirection === TOUCH_DIRECTION_ALL &&\n // TODO: Get rid of using private property of axes instance.\n (this._axes as any)._inputs.indexOf(this._axesPinchInput) === -1\n ) {\n this._axes.connect([\"fov\"], this._axesPinchInput);\n }\n }\n }\n\n private _enableTouch(direction: YawPitchControlOptions[\"touchDirection\"]) {\n // Disconnect first\n if (this._axesPanInput) {\n this._axes.disconnect(this._axesPanInput);\n }\n\n const yawEnabled = direction & TOUCH_DIRECTION_YAW ? \"yaw\" : null;\n const pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? \"pitch\" : null;\n\n this._axes.connect([yawEnabled, pitchEnabled] as string[], this._axesPanInput);\n }\n\n private _initDeviceQuaternion() {\n this._deviceQuaternion = new DeviceQuaternion();\n this._deviceQuaternion.on(\"change\", e => {\n this._triggerChange(e);\n });\n }\n\n private _getValidYawRange(newYawRange: number[], newFov?: number, newAspectRatio?: number) {\n const ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1);\n const fov = newFov || this._axes.get().fov;\n const horizontalFov = fov * ratio;\n const isValid = newYawRange[1] - newYawRange[0] >= horizontalFov;\n\n if (isValid) {\n return newYawRange;\n } else {\n return this.options.yawRange || DEFAULT_YAW_RANGE;\n }\n }\n\n private _getValidPitchRange(newPitchRange: number[], newFov?: number) {\n const fov = newFov || this._axes.get().fov;\n const isValid = newPitchRange[1] - newPitchRange[0] >= fov;\n\n if (isValid) {\n return newPitchRange;\n } else {\n return this.options.pitchRange || DEFAULT_PITCH_RANGE;\n }\n }\n\n private _isCircular(range: number[]) {\n return range[1] - range[0] < 360 ? [false, false] : [true, true];\n }\n\n /**\n * Update yaw/pitch min/max by 5 factor\n *\n * 1. showPolePoint\n * 2. fov\n * 3. yawRange\n * 4. pitchRange\n * 5. aspectRatio\n *\n * If one of above is changed, call this function\n */\n private _updateControlScale(changeEvt?: any) { // TODO: Change type after Axes type inference update\n const opt = this.options;\n const fov = this._axes.get().fov;\n\n const pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint);\n const yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio);\n\n // TODO: If not changed!?\n const pos = this._axes.get();\n let y = pos.yaw;\n let p = pos.pitch;\n\n vec2.copy(this._axes.axis.yaw.range as any, yRange as any);\n vec2.copy(this._axes.axis.pitch.range as any, pRange as any);\n this._axes.axis.yaw.circular = this._isCircular(yRange);\n this._axes.axis.pitch.circular = this._isCircular(pRange);\n\n /**\n * update yaw/pitch by it's range.\n */\n if (y < yRange[0]) {\n y = yRange[0];\n } else if (y > yRange[1]) {\n y = yRange[1];\n }\n\n if (p < pRange[0]) {\n p = pRange[0];\n } else if (p > pRange[1]) {\n p = pRange[1];\n }\n\n if (changeEvt) {\n changeEvt.set({\n yaw: y,\n pitch: p\n });\n }\n\n this._axes.setTo({\n yaw: y,\n pitch: p\n }, 0);\n\n return this;\n }\n\n private _updatePitchRange(pitchRange: number[], fov: number, showPolePoint: boolean) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n // Circular pitch on VR\n return CIRCULAR_PITCH_RANGE;\n }\n\n const verticalAngle = pitchRange[1] - pitchRange[0];\n const halfFov = fov / 2;\n const isPanorama = verticalAngle < 180;\n\n if (showPolePoint && !isPanorama) {\n // Use full pinch range\n return pitchRange.concat();\n }\n\n // Round value as movableCood do.\n return [pitchRange[0] + halfFov, pitchRange[1] - halfFov];\n }\n\n private _updateYawRange(yawRange: number[], fov: number, aspectRatio: number) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n return DEFAULT_YAW_RANGE;\n }\n\n const horizontalAngle = yawRange[1] - yawRange[0];\n\n /**\n * Full 360 Mode\n */\n if (horizontalAngle >= 360) {\n // Don't limit yaw range on Full 360 mode.\n return yawRange.concat();\n }\n\n /**\n * Panorama mode\n */\n // Ref : https://github.com/naver/egjs-view360/issues/290\n const halfHorizontalFov =\n mathUtil.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))) as number;\n\n // Round value as movableCood do.\n return [\n yawRange[0] + halfHorizontalFov,\n yawRange[1] - halfHorizontalFov\n ];\n }\n\n // TODO: update param type after Axes event type inference update\n private _triggerChange(evt: any) {\n const pos = this._axes.get();\n const opt = this.options;\n const event: YawPitchControlEvents[\"change\"] extends ComponentEvent ? T : never = {\n targetElement: opt.element as HTMLElement,\n isTrusted: evt.isTrusted,\n yaw: pos.yaw,\n pitch: pos.pitch,\n fov: pos.fov,\n quaternion: null\n };\n\n if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) {\n event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw);\n }\n\n this.trigger(new ComponentEvent(\"change\", event));\n }\n\n // TODO: makes constant to be logic\n private _adjustAspectRatio(input: number) {\n const inputRange = [\n 0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670,\n 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19,\n 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26,\n 2.30, 2.60, 3.00, 5.00, 6.00\n ];\n const outputRange = [\n 0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710,\n 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15,\n 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72,\n 1.82, 1.92, 2.00, 2.24, 2.30\n ];\n\n let rangeIdx = -1;\n\n for (let i = 0; i < inputRange.length - 1; i++) {\n if (inputRange[i] <= input && inputRange[i + 1] >= input) {\n rangeIdx = i;\n break;\n }\n }\n\n if (rangeIdx === -1) {\n if (inputRange[0] > input) {\n return outputRange[0];\n } else {\n // FIXME: this looks definitely wrong\n return outputRange[(outputRange[0] as any).length - 1];\n }\n }\n\n const inputA = inputRange[rangeIdx];\n const inputB = inputRange[rangeIdx + 1];\n const outputA = outputRange[rangeIdx];\n const outputB = outputRange[rangeIdx + 1];\n\n return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA));\n }\n\n private _lerp(a: number, b: number, fraction: number) {\n return a + fraction * (b - a);\n }\n\n private _resetOrientation() {\n const opt = this.options;\n\n this._axes.setTo({\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }, 0);\n\n return this;\n }\n}\n\nexport default YawPitchControl;\n","/**\n * Constant value for gyro mode.
(Reference {@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide})\n * @ko gyro 모드 대한 상수 값.
({@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide} 참고)\n * @namespace\n * @name GYRO_MODE\n * @memberof eg.view360.PanoViewer\n */\n/**\n * Disable gyro\n * @ko gyro 비활성화\n * @name NONE\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"none\"\n */\n/**\n * YawPitch Mode\n * @ko YawPitch Mode\n * @name YAWPITCH\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"yawPitch\"\n */\n/**\n * VR Mode\n * @ko VR Mode\n * @name VR\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"VR\"\n */\nimport { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\nimport { GYRO_MODE } from \"../YawPitchControl/consts\";\n\n/**\n * Constant value for errors\n * @ko 에러에 대한 상수 값\n * @namespace\n * @name ERROR_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst ERROR_TYPE = {\n /**\n * Unsupported device\n * @ko 미지원 기기\n * @name INVALID_DEVICE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 10\n */\n INVALID_DEVICE: 10,\n /**\n * Webgl not support\n * @ko WEBGL 미지원\n * @name NO_WEBGL\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 11\n */\n NO_WEBGL: 11,\n /**\n * Failed to load image\n * @ko 이미지 로드 실패\n * @name FAIL_IMAGE_LOAD\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 12\n */\n FAIL_IMAGE_LOAD: 12,\n /**\n * Failed to bind texture\n * @ko 텍스쳐 바인딩 실패\n * @name FAIL_BIND_TEXTURE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 13\n */\n FAIL_BIND_TEXTURE: 13,\n /**\n * Only one resource(image or video) should be specified\n * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함)\n * @name INVALID_RESOURCE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 14\n */\n INVALID_RESOURCE: 14,\n /**\n * WebGL context lost occurred\n * @ko WebGL context lost 발생\n * @name RENDERING_CONTEXT_LOST\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 15\n */\n RENDERING_CONTEXT_LOST: 15\n};\n\n/**\n * Constant value for events\n * @ko 이벤트에 대한 상수 값\n * @namespace\n * @name EVENTS\n * @memberof eg.view360.PanoViewer\n */\nconst PANOVIEWER_EVENTS: {\n READY: \"ready\";\n VIEW_CHANGE: \"viewChange\";\n ANIMATION_END: \"animationEnd\";\n ERROR: \"error\";\n} = {\n /**\n * Events that is fired when PanoViewer is ready to show image and handle user interaction.\n * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트\n * @name READY\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default ready\n */\n READY: \"ready\",\n /**\n * Events that is fired when direction or fov is changed.\n * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트\n * @name VIEW_CHANGE\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default viewChange\n */\n VIEW_CHANGE: \"viewChange\",\n /**\n * Events that is fired when animation which is triggered by inertia is ended.\n * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트\n * @name ANIMATION_END\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default animationEnd\n */\n ANIMATION_END: \"animationEnd\",\n /**\n * Events that is fired when error occurs\n * @ko 에러 발생 시 발생하는 이벤트\n * @name ERROR\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default error\n */\n ERROR: \"error\"\n};\n\n/**\n * Constant value for projection type\n * @ko 프로젝션 타입 대한 상수 값\n * @namespace\n * @name PROJECTION_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst PROJECTION_TYPE: {\n EQUIRECTANGULAR: \"equirectangular\";\n CUBEMAP: \"cubemap\";\n CUBESTRIP: \"cubestrip\";\n PANORAMA: \"panorama\";\n STEREOSCOPIC_EQUI: \"stereoequi\";\n} = {\n /**\n * Constant value for equirectangular type.\n * @ko equirectangular 에 대한 상수 값.\n * @name EQUIRECTANGULAR\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default equirectangular\n */\n EQUIRECTANGULAR: \"equirectangular\",\n /**\n * Constant value for cubemap type.\n * @ko cubemap 에 대한 상수 값.\n * @name CUBEMAP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubemap\n */\n CUBEMAP: \"cubemap\",\n /**\n * Constant value for cubestrip type.\n * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC.\n * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다.\n * @name CUBESTRIP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubestrip\n */\n CUBESTRIP: \"cubestrip\",\n /**\n * Constant value for PANORAMA type.\n *\n * PANORAMA is a format for a panorma image which is taken from smartphone.\n * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다.\n *\n * @name PANORAMA\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default panorama\n */\n PANORAMA: \"panorama\",\n /**\n * Constant value for EQUI_STEREOSCOPY type.\n *\n * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present.\n * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다.\n *\n * @name STEREOSCOPIC_EQUI\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default stereoequi\n */\n STEREOSCOPIC_EQUI: \"stereoequi\"\n};\n\n/**\n * A constant value for the format of the stereoscopic equirectangular projection type.\n * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값\n * @namespace\n * @name STEREO_FORMAT\n * @memberof eg.view360.PanoViewer\n */\nconst STEREO_FORMAT: {\n TOP_BOTTOM: \"3dv\";\n LEFT_RIGHT: \"3dh\";\n NONE: \"\";\n} = {\n /**\n * A constant value for format of top bottom stereoscopic 360 equirectangular projection.\n * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name TOP_BOTTOM\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dv\"\n */\n TOP_BOTTOM: \"3dv\",\n /**\n * A constant value for format of left right stereoscopic 360 equirectangular projection.\n * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name LEFT_RIGHT\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dh\"\n */\n LEFT_RIGHT: \"3dh\",\n /**\n * A constant value specifying media is not in stereoscopic format.\n * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"\"\n */\n NONE: \"\"\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst PANOVIEWER_OPTIONS: { [key in keyof PanoViewerOptions]: true } = {\n image: true,\n video: true,\n projectionType: true,\n cubemapConfig: true,\n stereoFormat: true,\n width: true,\n height: true,\n yaw: true,\n pitch: true,\n fov: true,\n showPolePoint: true,\n useZoom: true,\n useKeyboard: true,\n gyroMode: true,\n yawRange: true,\n pitchRange: true,\n fovRange: true,\n touchDirection: true,\n canvasClass: true\n};\n\nconst DEFAULT_CANVAS_CLASS = \"view360-canvas\";\n\nexport {\n GYRO_MODE,\n PANOVIEWER_EVENTS,\n ERROR_TYPE,\n PROJECTION_TYPE,\n STEREO_FORMAT,\n PANOVIEWER_OPTIONS,\n DEFAULT_CANVAS_CLASS\n};\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","import agent from \"@egjs/agent\";\n\nimport { TypedArray } from \"../types/internal\";\n\nconst WEBGL_ERROR_CODE = {\n \"0\": \"NO_ERROR\",\n \"1280\": \"INVALID_ENUM\",\n \"1281\": \"INVALID_VALUE\",\n \"1282\": \"INVALID_OPERATION\",\n \"1285\": \"OUT_OF_MEMORY\",\n \"1286\": \"INVALID_FRAMEBUFFER_OPERATION\",\n \"37442\": \"CONTEXT_LOST_WEBGL\"\n};\n\nlet webglAvailability: boolean | null = null;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet MAX_TEXTURE_SIZE_FOR_TEST: number | null = null;\n\nexport default class WebGLUtils {\n public static createShader(gl: WebGLRenderingContext, type: number, source: string) {\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (success) {\n return shader;\n }\n\n // eslint-disable-next-line\n console.error(gl.getShaderInfoLog(shader));\n\n return null;\n }\n\n public static createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = gl.createProgram()!;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (success) {\n return program;\n }\n\n gl.deleteProgram(program);\n return null;\n }\n\n public static initBuffer(gl: WebGLRenderingContext, target: number /* bind point */, data: TypedArray, itemSize: number, attr?: number) {\n const buffer = gl.createBuffer()!;\n\n gl.bindBuffer(target, buffer);\n gl.bufferData(target, data, gl.STATIC_DRAW);\n\n if (buffer) {\n (buffer as any).itemSize = itemSize;\n (buffer as any).numItems = data.length / itemSize;\n }\n\n if (attr !== undefined) {\n gl.enableVertexAttribArray(attr);\n gl.vertexAttribPointer(attr, (buffer as any).itemSize, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n }\n\n public static getWebglContext(canvas: HTMLCanvasElement, userContextAttributes?: WebGLContextAttributes) {\n const webglIdentifiers = [\"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n const contextAttributes = {\n ...{\n preserveDrawingBuffer: false,\n antialias: false\n }, ...userContextAttributes\n };\n\n const onWebglcontextcreationerror = e => e.statusMessage;\n\n canvas.addEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n return context;\n }\n\n public static createTexture(gl: WebGLRenderingContext, textureTarget: number) {\n const texture = gl.createTexture();\n\n gl.bindTexture(textureTarget, texture);\n gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(textureTarget, null);\n\n return texture;\n }\n\n /**\n * Returns the webgl availability of the current browser.\n * @method WebGLUtils#isWebGLAvailable\n * @retuen {Boolean} isWebGLAvailable\n */\n public static isWebGLAvailable(): boolean {\n if (webglAvailability === null) {\n const canvas = document.createElement(\"canvas\");\n const webglContext = WebGLUtils.getWebglContext(canvas);\n\n webglAvailability = !!webglContext;\n\n // webglContext Resource forced collection\n if (webglContext) {\n const loseContextExtension = webglContext.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n return !!webglAvailability;\n }\n\n /**\n * Returns whether webgl is stable in the current browser.\n * @method WebGLUtils#isStableWebGL\n * @retuen {Boolean} isStableWebGL\n */\n public static isStableWebGL() {\n const agentInfo = agent();\n let isStableWebgl = true;\n\n if (agentInfo.os.name === \"android\") {\n const version = parseFloat(agentInfo.os.version);\n\n if (version <= 4.3 && version >= 1) {\n isStableWebgl = false;\n } else if (version === 4.4) {\n if (agentInfo.browser.name !== \"chrome\") {\n isStableWebgl = false;\n }\n }\n }\n return isStableWebgl;\n }\n\n public static getErrorNameFromWebGLErrorCode(code: number | string) {\n if (!(code in WEBGL_ERROR_CODE)) {\n return \"UNKNOWN_ERROR\";\n }\n\n return WEBGL_ERROR_CODE[code];\n }\n\n\n /**\n * This function is wrapper for texImage2D to handle exceptions on texImage2D.\n * Purpose is to prevent service from being stopped by script error.\n */\n public static texImage2D(gl: WebGLRenderingContext, target: number, pixels: TexImageSource) {\n try {\n gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n } catch (error) {\n /* eslint-disable no-console */\n console.error(\"WebGLUtils.texImage2D error:\", error);\n /* eslint-enable no-console */\n }\n }\n\n public static getMaxTextureSize(gl: WebGLRenderingContext) {\n // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test\n return MAX_TEXTURE_SIZE_FOR_TEST || gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n}\n\n/**\n * This function should not be used in service code. It's provided only for test purpose.\n * It should be set to null or 0 when test is done.\n * @param {Number} size\n */\nconst setMaxTextureSizeForTestOnlyPurpose = (size: number) => {\n MAX_TEXTURE_SIZE_FOR_TEST = size;\n};\n\nexport {\n setMaxTextureSizeForTestOnlyPurpose\n};\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport agent from \"@egjs/agent\";\nimport { mat4 } from \"gl-matrix\";\n\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nconst agentInfo = agent();\nconst isIE11 = agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11;\n\nconst EVENTS: {\n ERROR: \"error\";\n} = {\n ERROR: \"error\"\n};\n\n/**\n *\n * Extends Component for firing errors occurs internally.\n */\nabstract class Renderer extends Component<{\n [EVENTS.ERROR]: {\n message: string;\n };\n}> {\n public static EVENTS = EVENTS;\n\n private _forceDimension: { width: number; height: number } | null;\n private _pixelCanvas: HTMLCanvasElement | null;\n private _pixelContext: CanvasRenderingContext2D | null;\n\n public constructor() {\n super();\n\n this._forceDimension = null;\n this._pixelCanvas = null;\n this._pixelContext = null;\n }\n\n public abstract getVertexPositionData(): number[];\n public abstract getIndexData(): number[];\n public abstract getTextureCoordData(textureData: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }): number[];\n\n public abstract getVertexShaderSource(): string;\n public abstract getFragmentShaderSource(): string;\n public abstract bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n public abstract updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n\n public render({ gl, shaderProgram, indexBuffer, mvMatrix, pMatrix }: {\n gl: WebGLRenderingContext;\n shaderProgram: WebGLProgram;\n indexBuffer: WebGLBuffer;\n mvMatrix: mat4;\n pMatrix: mat4;\n }) {\n gl.uniformMatrix4fv((shaderProgram as any).pMatrixUniform, false, pMatrix);\n gl.uniformMatrix4fv((shaderProgram as any).mvMatrixUniform, false, mvMatrix);\n\n if (indexBuffer) {\n gl.drawElements(gl.TRIANGLES, (indexBuffer as any).numItems, gl.UNSIGNED_SHORT, 0);\n }\n }\n\n // Define interface for Renderers\n /**\n * Following MUST BE DEFINED on Child of Renderer\n *\n * DATA\n *\n * - getVertexPositionData\n * - getIndexData\n * - getTextureCoordData\n *\n * SOURCE\n *\n * - getVertexShaderSource\n * - getFragmentShaderSource\n *\n * TEXTURE\n *\n * - bindTexture\n */\n public getDimension(pixelSource: HTMLImageElement | HTMLVideoElement) {\n const width = (pixelSource as HTMLImageElement).naturalWidth\n || (pixelSource as HTMLVideoElement).videoWidth;\n const height = (pixelSource as HTMLImageElement).naturalHeight\n || (pixelSource as HTMLVideoElement).videoHeight;\n\n return { width, height };\n }\n\n /**\n * Update data used by shader\n */\n public updateShaderData(param) { // eslint-disable-line @typescript-eslint/no-unused-vars\n /*\n * Update following data in implementation layer.\n * If the data is not changed, it does not need to implement this function.\n *\n * - _VERTEX_POSITION_DATA\n * - _TEXTURE_COORD_DATA\n * - _INDEX_DATA\n */\n }\n\n /**\n *\n * @param {HTMLImageElement | HTMLVideoElement} image\n * @param {Object = {width, height}} forceDimension Forced dimension to resize\n */\n protected _initPixelSource(image: HTMLImageElement | HTMLVideoElement, forceDimension: Renderer[\"_forceDimension\"] = null) {\n const isIE11Video = isIE11 && (image instanceof HTMLVideoElement);\n\n if (isIE11Video || forceDimension) {\n const {width, height} = forceDimension || this.getDimension(image);\n\n this._pixelCanvas = document.createElement(\"canvas\");\n this._pixelCanvas.width = width;\n this._pixelCanvas.height = height;\n this._pixelContext = this._pixelCanvas.getContext(\"2d\");\n }\n this._forceDimension = forceDimension;\n }\n\n protected _getPixelSource(image: HTMLImageElement | HTMLVideoElement) {\n if (!this._pixelCanvas) {\n return image;\n }\n\n /**\n * IE11 && Video\n * or\n * Dimension is forced (Image is larger than texture size.)\n */\n const contentDimension = this.getDimension(image);\n const textureDimension = this._forceDimension || contentDimension;\n\n if (this._pixelCanvas.width !== textureDimension.width) {\n this._pixelCanvas.width = textureDimension.width;\n }\n\n if (this._pixelCanvas.height !== textureDimension.height) {\n this._pixelCanvas.height = textureDimension.height;\n }\n\n if (this._forceDimension) {\n this._pixelContext!.drawImage(image,\n 0, 0, contentDimension.width, contentDimension.height,\n 0, 0, textureDimension.width, textureDimension.height);\n } else {\n this._pixelContext!.drawImage(image, 0, 0);\n }\n\n return this._pixelCanvas;\n }\n\n protected _extractTileConfig(imageConfig: CubemapConfig) {\n let tileConfig: TileConfig[] =\n Array.isArray(imageConfig.tileConfig) ?\n imageConfig.tileConfig : Array(...Array(6)).map(() => imageConfig.tileConfig) as TileConfig[];\n\n tileConfig = tileConfig.map(\n config => ({\n ...{\n flipHorizontal: false,\n rotation: 0\n }, ...config\n })\n );\n\n return tileConfig;\n }\n\n protected _triggerError(error) {\n /* eslint-disable no-console */\n console.error(\"Renderer Error:\", error);\n /* eslint-enable no-console */\n\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n message: typeof error === \"string\" ? error : error.message\n }));\n }\n}\n\nexport default Renderer;\n","import agent from \"@egjs/agent\";\n\nimport WebGLUtils from \"../WebGLUtils\";\nimport { util as mathUtil } from \"../../utils/math-util\";\nimport { CubemapConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nclass CubeRenderer extends Renderer {\n public static extractOrder(imageConfig: CubemapConfig) {\n return imageConfig.order || \"RLUDBF\";\n }\n\n private static _VERTEX_POSITION_DATA: number[] | null = null;\n private static _INDEX_DATA: number[] | null = null;\n\n public getVertexPositionData() {\n CubeRenderer._VERTEX_POSITION_DATA =\n CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // top\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // bottom\n 1, -1, -1,\n -1, -1, -1,\n -1, -1, 1,\n 1, -1, 1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n return CubeRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n if (CubeRenderer._INDEX_DATA) {\n return CubeRenderer._INDEX_DATA;\n }\n\n const indexData: number[] = [];\n const vertexPositionData = this.getVertexPositionData();\n\n for (let i = 0; i < (vertexPositionData.length / 3); i += 4) {\n indexData.push(\n i,\n i + 2,\n i + 1,\n i,\n i + 3,\n i + 2\n );\n }\n\n CubeRenderer._INDEX_DATA = indexData;\n return indexData;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n const vertexOrder = \"BFUDRL\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const base = this.getVertexPositionData();\n const tileConfig = this._extractTileConfig(imageConfig);\n const elemSize = 3;\n const vertexPerTile = 4;\n const { trim } = imageConfig;\n\n const texCoords = vertexOrder.split(\"\")\n .map(face => tileConfig[order.indexOf(face)])\n .map((config, i) => {\n const rotation = Math.floor(config.rotation / 90);\n const ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2];\n\n for (let r = 0; r < Math.abs(rotation); r++) {\n if ((config.flipHorizontal && rotation > 0) ||\n (!config.flipHorizontal && rotation < 0)) {\n ordermap.push(ordermap.shift()!);\n } else {\n ordermap.unshift(ordermap.pop()!);\n }\n }\n\n const elemPerTile = elemSize * vertexPerTile;\n const tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile);\n const tileTemp: number[][] = [];\n\n for (let j = 0; j < vertexPerTile; j++) {\n tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize);\n }\n return tileTemp;\n })\n .map(coord => this._shrinkCoord({ image, faceCoords: coord, trim }))\n .reduce((acc: number[], val: number[][]) => [\n ...acc,\n ...val.reduce((coords, coord) => [...coords, ...coord], [])\n ], []);\n\n return texCoords;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n const baseOrder = \"RLUDBF\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const orderMap = {};\n\n order.split(\"\").forEach((v, i) => {\n orderMap[v] = i;\n });\n\n try {\n if (image instanceof Array) {\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]);\n }\n } else {\n const maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image);\n\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n const tile = this.extractTileFromImage(\n image, tileIdx, maxCubeMapTextureSize\n );\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile);\n }\n }\n } catch (e) {\n this._triggerError(e);\n }\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n this.updateTexture(gl, image, imageConfig);\n }\n\n public getSourceTileSize(image: HTMLImageElement | HTMLVideoElement) {\n const {width, height} = this.getDimension(image);\n const aspectRatio = width / height;\n let inputTextureSize;\n\n if (aspectRatio === 1 / 6) {\n inputTextureSize = width;\n } else if (aspectRatio === 6) {\n inputTextureSize = height;\n } else if (aspectRatio === 2 / 3) {\n inputTextureSize = width / 2;\n } else {\n inputTextureSize = width / 3;\n }\n return inputTextureSize;\n }\n\n public extractTileFromImage(image: HTMLImageElement | HTMLVideoElement, tileIdx: number, outputTextureSize: number) {\n const {width} = this.getDimension(image);\n const inputTextureSize = this.getSourceTileSize(image);\n\n const canvas = document.createElement(\"canvas\");\n\n canvas.width = outputTextureSize;\n canvas.height = outputTextureSize;\n const context = canvas.getContext(\"2d\");\n const tilePerRow = width / inputTextureSize;\n\n const x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow);\n const y = Math.floor(tileIdx / tilePerRow) * (inputTextureSize);\n\n context!.drawImage(\n image, x, y,\n inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize\n );\n return canvas;\n }\n\n public getMaxCubeMapTextureSize(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n const agentInfo = agent();\n const maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n let imageWidth = this.getSourceTileSize(image);\n\n if (agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11) {\n if (!mathUtil.isPowerOfTwo(imageWidth)) {\n for (let i = 1; i < maxCubeMapTextureSize; i *= 2) {\n if (i < imageWidth) {\n continue;\n } else {\n imageWidth = i;\n break;\n }\n }\n }\n }\n if (agentInfo.os.name === \"ios\") {\n const majorVersion = agentInfo.os.majorVersion;\n\n // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다.\n if (majorVersion === 9) {\n imageWidth = 1024;\n }\n // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다.\n if (majorVersion === 8) {\n imageWidth = 512;\n }\n }\n // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수\n return Math.min(maxCubeMapTextureSize, imageWidth);\n }\n\n private _shrinkCoord(coordData: {\n image: HTMLImageElement | HTMLVideoElement;\n faceCoords: number[][];\n trim: number;\n }) {\n const { image, faceCoords, trim } = coordData;\n\n const inputTextureSize = Array.isArray(image)\n ? this.getDimension(image[0]).width\n : this.getSourceTileSize(image);\n\n // Shrink by \"trim\" px\n const SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize);\n\n const axisMultipliers = [0, 1, 2].map(axisIndex => {\n const axisDir = mathUtil.sign(faceCoords[0][axisIndex]);\n const notSameDir = faceCoords.some(coord => mathUtil.sign(coord[axisIndex]) !== axisDir);\n\n return notSameDir;\n }).map(notSameDir => notSameDir ? SHRINK_MULTIPLIER : 1);\n\n return faceCoords.map(coords => coords.map((coord, axisIndex) => coord * axisMultipliers[axisIndex]));\n }\n}\n\nexport default CubeRenderer;\n","\nimport WebGLUtils from \"../WebGLUtils\";\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nexport default class CubeStripRenderer extends Renderer {\n private _vertices: number[];\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}`;\n }\n\n public getVertexPositionData() {\n if (!this._vertices) {\n this._vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n }\n\n return this._vertices;\n }\n\n public getIndexData() {\n // TODO: 한번만 계산하도록 수정하기\n const indices = (() => {\n const indexData: number[] = [];\n\n for (let i = 0; i < (this._vertices.length / 3); i += 4) {\n indexData.push(\n i,\n i + 1,\n i + 2,\n i,\n i + 2,\n i + 3\n );\n }\n return indexData;\n })();\n\n return indices;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n // TODO: make it cols, rows as config.\n const cols = 3;\n const rows = 2;\n\n const textureSize = this.getDimension(image);\n const { trim } = imageConfig;\n\n const order = imageConfig.order || \"RLUDFB\";\n let coords: number[][] = [];\n\n // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다.\n for (let r = rows - 1; r >= 0; r--) {\n for (let c = 0; c < cols; c++) {\n const coord = [\n c / cols, r / rows,\n (c + 1) / cols, r / rows,\n (c + 1) / cols, (r + 1) / rows,\n c / cols, (r + 1) / rows\n ];\n\n coords.push(coord);\n }\n }\n\n const tileConfigs = this._extractTileConfig(imageConfig);\n\n // Transform Coord By Flip & Rotation\n coords = coords\n // shrink coord to avoid pixel bleeding\n .map(coord => this._shrinkCoord(coord, textureSize, trim))\n .map((coord, i) => this._transformCoord(coord, tileConfigs[i]));\n\n // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치\n return \"BFUDRL\".split(\"\")\n .map(face => order.indexOf(face))\n .map(index => coords[index])\n .reduce((acc, val) => acc.concat(val), []);\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n private _transformCoord(coord: number[], tileConfig: TileConfig) {\n let newCoord = coord.slice();\n\n if (tileConfig.flipHorizontal) {\n newCoord = this._flipHorizontalCoord(newCoord);\n }\n\n if (tileConfig.rotation) {\n newCoord = this._rotateCoord(newCoord, tileConfig.rotation);\n }\n\n return newCoord;\n }\n\n private _shrinkCoord(coord: number[], textureSize: { width: number; height: number }, trim: number) {\n const { width, height } = textureSize;\n\n // Shrink by \"trim\" px\n const SHRINK_Y = trim * (1 / height);\n const SHRINK_X = trim * (1 / width);\n\n return [\n coord[0] + SHRINK_X, coord[1] + SHRINK_Y,\n coord[2] - SHRINK_X, coord[3] + SHRINK_Y,\n coord[4] - SHRINK_X, coord[5] - SHRINK_Y,\n coord[6] + SHRINK_X, coord[7] - SHRINK_Y\n ];\n }\n\n private _rotateCoord(coord: number[], rotationAngle: number) {\n const SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord.\n const shiftCount = Math.floor(rotationAngle / 90) % 4;\n\n if (shiftCount === 0) {\n return coord;\n }\n\n let moved;\n let rotatedCoord: number[] = [];\n\n if (shiftCount > 0) {\n moved = coord.splice(0, shiftCount * SIZE);\n rotatedCoord = coord.concat(moved);\n } else {\n moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE);\n rotatedCoord = moved.concat(coord);\n }\n\n return rotatedCoord;\n }\n\n private _flipHorizontalCoord(coord: number[]) {\n return [\n coord[2], coord[3],\n coord[0], coord[1],\n coord[6], coord[7],\n coord[4], coord[5]\n ];\n }\n}\n","import WebGLUtils from \"../WebGLUtils\";\nimport { STEREO_FORMAT } from \"../../PanoViewer/consts\";\nimport { ValueOf } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nconst latitudeBands = 60;\nconst longitudeBands = 60;\nconst radius = 2;\nconst ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\nlet latIdx: number;\nlet lngIdx: number;\n\nfor (latIdx = 0; latIdx <= latitudeBands; latIdx++) {\n const theta = (latIdx / latitudeBands - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / longitudeBands;\n const v = latIdx / latitudeBands;\n\n textureCoordData.push(u, v);\n vertexPositionData.push(radius * x, radius * y, radius * z);\n\n if (lngIdx !== longitudeBands && latIdx !== latitudeBands) {\n const a = latIdx * (longitudeBands + 1) + lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n}\n\nclass SphereRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n private _stereoFormat: ValueOf;\n\n public constructor(format: SphereRenderer[\"_stereoFormat\"]) {\n super();\n\n this._stereoFormat = format;\n }\n\n public render(ctx: Parameters[0]) {\n const {gl, shaderProgram} = ctx;\n\n let leftEyeScaleOffset: number[];\n let rightEyeScaleOffset: number[];\n\n switch (this._stereoFormat) {\n case STEREO_FORMAT.TOP_BOTTOM:\n leftEyeScaleOffset = [1, 0.5, 0, 0];\n rightEyeScaleOffset = [1, 0.5, 0, 0.5];\n break;\n case STEREO_FORMAT.LEFT_RIGHT:\n leftEyeScaleOffset = [0.5, 1, 0, 0];\n rightEyeScaleOffset = [0.5, 1, 0.5, 0];\n break;\n default:\n leftEyeScaleOffset = [1, 1, 0, 0];\n rightEyeScaleOffset = [1, 1, 0, 0];\n }\n\n const uTexScaleOffset = gl.getUniformLocation(shaderProgram, \"uTexScaleOffset\");\n\n gl.uniform4fv(uTexScaleOffset, [...leftEyeScaleOffset, ...rightEyeScaleOffset]);\n\n super.render(ctx);\n }\n\n public getVertexPositionData() {\n return SphereRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return SphereRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return SphereRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const { width, height } = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n}\n\nexport default SphereRenderer;\n","import { glMatrix } from \"gl-matrix\";\n\nimport WebGLUtils from \"../WebGLUtils\";\n\nimport Renderer from \"./Renderer\";\n\n// const latitudeBands = 60;\nconst MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6;\nconst longitudeBands = 60;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\n\nclass CylinderRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n public getVertexPositionData() {\n return CylinderRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return CylinderRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return CylinderRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n let resizeDimension: { width: number; height: number } | undefined;\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device texture limit(${maxSize}))`);\n\n // Request resizing texture.\n /**\n * TODO: Is it need to apply on another projection type?\n */\n resizeDimension = width > height ?\n {width: maxSize, height: maxSize * height / width} :\n {width: maxSize * width / height, height: maxSize};\n }\n\n // Pixel Source for IE11 & Video or resizing needed\n this._initPixelSource(image, resizeDimension);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n public updateShaderData({ imageAspectRatio = MIN_ASPECT_RATIO_FOR_FULL_PANORAMA }) {\n let lngIdx: number;\n let cylinderMaxRadian: number;\n let halfCylinderY: number;\n let rotated: boolean;\n let aspectRatio: number;\n\n // Exception case: orientation is rotated.\n if (imageAspectRatio < 1) {\n /**\n * If rotated is true, we assume that image is rotated counter clockwise.\n * TODO: If there's other rotation, it is need to implement by each rotation.\n */\n rotated = true;\n aspectRatio = 1 / imageAspectRatio;\n } else {\n rotated = false;\n aspectRatio = imageAspectRatio;\n }\n\n if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) {\n const fov = 360 / aspectRatio;\n\n cylinderMaxRadian = 2 * Math.PI; // 360 deg\n halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2));\n } else {\n cylinderMaxRadian = aspectRatio;\n halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1.\n }\n\n // initialize shader data before update\n textureCoordData.length = 0;\n vertexPositionData.length = 0;\n indexData.length = 0;\n\n const CYLIDER_Y = [-halfCylinderY, halfCylinderY];\n const startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360)\n\n // console.log(\"cylinderMaxRadian:\", glMatrix.toDegree(cylinderMaxRadian), \"CYLIDER_Y\", CYLIDER_Y, \"start angle\", glMatrix.toDegree(startAngleForCenterAlign));\n for (let yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength/* bottom & top */; yIdx++) {\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const angle = startAngleForCenterAlign + (lngIdx / longitudeBands * cylinderMaxRadian);\n const x = Math.cos(angle);\n const y = CYLIDER_Y[yIdx];\n const z = Math.sin(angle);\n let u: number;\n let v: number;\n\n if (rotated) {\n // Rotated 90 degree (counter clock wise)\n u = 1 - yIdx; // yLength - yIdx;\n v = lngIdx / longitudeBands;\n } else {\n // \t// Normal case (Not rotated)\n u = lngIdx / longitudeBands;\n v = yIdx;\n }\n\n textureCoordData.push(u, v);\n vertexPositionData.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < longitudeBands) {\n const a = lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n }\n}\n\nexport default CylinderRenderer;\n","import Promise from \"promise-polyfill\";\nimport { mat4 } from \"gl-matrix\";\n\nconst VR_DISPLAY_PRESENT_CHANGE = \"vrdisplaypresentchange\";\nconst DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1];\nconst DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1];\nconst EYES = {\n LEFT: \"left\",\n RIGHT: \"right\"\n} as const;\n\nclass VRManager {\n private _vrDisplay: VRDisplay | null;\n private _frameData: VRFrameData;\n private _yawOffset: number;\n private _leftBounds: number[];\n private _rightBounds: number[];\n\n public constructor() {\n this._frameData = new window.VRFrameData();\n this._clear();\n }\n\n public get context() { return this._vrDisplay; }\n\n public destroy = () => {\n const vrDisplay = this._vrDisplay;\n\n this.removeEndCallback(this.destroy);\n\n if (vrDisplay && vrDisplay.isPresenting) {\n void vrDisplay.exitPresent();\n }\n\n this._clear();\n };\n\n public canRender() {\n return Boolean(this._vrDisplay);\n }\n\n public beforeRender(gl: WebGLRenderingContext) {\n // Render to the default backbuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public afterRender() {\n this._vrDisplay!.submitFrame();\n }\n\n public getEyeParams(gl: WebGLRenderingContext) {\n const display = this._vrDisplay!;\n const halfWidth = gl.drawingBufferWidth * 0.5;\n const height = gl.drawingBufferHeight;\n const frameData = this._frameData;\n\n display.getFrameData(frameData);\n\n const leftMVMatrix = frameData.leftViewMatrix;\n const rightMVMatrix = frameData.rightViewMatrix;\n\n mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset);\n mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset);\n\n return [\n {\n viewport: [0, 0, halfWidth, height],\n mvMatrix: leftMVMatrix,\n pMatrix: frameData.leftProjectionMatrix\n },\n {\n viewport: [halfWidth, 0, halfWidth, height],\n mvMatrix: rightMVMatrix,\n pMatrix: frameData.rightProjectionMatrix\n }\n ];\n }\n\n public isPresenting() {\n return Boolean(this._vrDisplay && this._vrDisplay.isPresenting);\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public requestPresent(canvas: HTMLCanvasElement) {\n return navigator.getVRDisplays().then(displays => {\n const vrDisplay = displays.length && displays[0];\n\n if (!vrDisplay) {\n return Promise.reject(new Error(\"No displays available.\"));\n }\n if (!vrDisplay.capabilities.canPresent) {\n return Promise.reject(new Error(\"Display lacking capability to present.\"));\n }\n\n return vrDisplay.requestPresent([{source: canvas}]).then(() => {\n const leftEye = vrDisplay.getEyeParameters(EYES.LEFT);\n const rightEye = vrDisplay.getEyeParameters(EYES.RIGHT);\n\n canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;\n canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);\n\n this._setDisplay(vrDisplay);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setDisplay(vrDisplay: VRDisplay) {\n this._vrDisplay = vrDisplay;\n\n const layers = vrDisplay.getLayers();\n\n if (layers.length) {\n const layer = layers[0];\n\n this._leftBounds = layer.leftBounds as number[];\n this._rightBounds = layer.rightBounds as number[];\n }\n\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._vrDisplay = null;\n this._leftBounds = DEFAULT_LEFT_BOUNDS;\n this._rightBounds = DEFAULT_RIGHT_BOUNDS;\n this._yawOffset = 0;\n }\n}\n\nexport default VRManager;\n","import { mat4, glMatrix } from \"gl-matrix\";\nimport { XRFrame, XRLayer, XRReferenceSpace, XRSession, XRSessionInit } from \"webxr\";\n\nimport { IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { merge } from \"../../utils/utils\";\n\nconst XR_REFERENCE_SPACE = \"local\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\nclass XRManager {\n private _xrSession: XRSession | null;\n private _xrLayer: XRLayer | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n private _yawOffset: number;\n private _presenting: boolean;\n\n public constructor(options: XRSessionOptions = {}) {\n this._clear();\n this._options = options;\n }\n\n public get context() { return this._xrSession; }\n\n public destroy = () => {\n const xrSession = this._xrSession;\n\n this.removeEndCallback(this.destroy);\n\n if (xrSession) {\n // Capture to avoid errors\n xrSession.end().then(() => void 0, () => void 0);\n }\n this._clear();\n };\n\n public canRender(frame: XRFrame) {\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n return Boolean(pose);\n }\n\n public beforeRender(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer!.framebuffer);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n public afterRender() {}\n\n public getEyeParams(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) {\n // Can't render\n return null;\n }\n\n const glLayer = session.renderState.baseLayer;\n\n return pose.views.map(view => {\n const viewport = glLayer!.getViewport(view);\n const mvMatrix = view.transform.inverse.matrix;\n\n if (IS_SAFARI_ON_DESKTOP) {\n mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180));\n }\n\n mat4.rotateY(mvMatrix, mvMatrix, this._yawOffset);\n\n return {\n viewport: [viewport.x, viewport.y, viewport.width, viewport.height],\n mvMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n public isPresenting() {\n return this._presenting;\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.addEventListener(\"end\", callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.removeEventListener(\"end\", callback);\n }\n\n public async requestPresent(canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {\n const options = merge({\n requiredFeatures: [XR_REFERENCE_SPACE]\n }, this._options);\n\n const attributes = gl.getContextAttributes();\n if (attributes && (attributes as any).xrCompatible !== true) {\n await (gl as any).makeXRCompatible();\n }\n\n return (navigator as any).xr.requestSession(\"immersive-vr\", options).then(session => {\n const xrLayer = new (window as any).XRWebGLLayer(session, gl);\n\n session.updateRenderState({baseLayer: xrLayer});\n return session.requestReferenceSpace(XR_REFERENCE_SPACE)\n .then(refSpace => {\n this._setSession(session, xrLayer, refSpace);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setSession(session: XRSession, xrLayer: XRLayer, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrLayer = xrLayer;\n this._xrRefSpace = refSpace;\n this._presenting = true;\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._xrSession = null;\n this._xrLayer = null;\n this._xrRefSpace = null;\n this._presenting = false;\n this._yawOffset = 0;\n this._options = {};\n }\n}\n\nexport default XRManager;\n","import { IS_SAFARI_ON_DESKTOP } from \"../utils/browser\";\n\nclass WebGLAnimator {\n private _callback: ((...args: any[]) => any) | null;\n private _context: any;\n private _rafId: number;\n private _rafTimer: number;\n\n public constructor() {\n this._callback = null;\n this._context = window;\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public setCallback(callback: (...args: any[]) => any) {\n this._callback = callback;\n }\n\n public setContext(context: any) {\n this._context = context;\n }\n\n public start() {\n const context = this._context;\n const callback = this._callback;\n\n // No context / callback set\n if (!context || !callback) return;\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n if (IS_SAFARI_ON_DESKTOP) {\n this._rafId = context.requestAnimationFrame(this._onLoopNextTick);\n } else {\n this._rafId = context.requestAnimationFrame(this._onLoop);\n }\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n /**\n * There can be more than 1 argument when we use XRSession's raf\n */\n private _onLoop = (...args: any[]) => {\n this._callback!(...args);\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n };\n\n /**\n * MacOS X Safari Bug Fix\n * This code guarantees that rendering should be occurred.\n *\n * In MacOS X(10.14.2), Safari (12.0.2)\n * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term\n * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms)\n * So browser cannot render the frame and may be freezing.\n */\n private _onLoopNextTick = (...args: any[]) => {\n const before = performance.now();\n\n this._callback!(...args);\n\n const diff = performance.now() - before;\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n this._rafTimer = -1;\n }\n\n /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */\n if (diff < 16) {\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n } else {\n /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */\n this._rafTimer = window.setTimeout(this._onLoop, 0);\n }\n };\n}\n\nexport default WebGLAnimator;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { XRFrame } from \"webxr\";\nimport Promise from \"promise-polyfill\";\nimport { glMatrix, vec3, mat3, mat4, quat } from \"gl-matrix\";\nimport ImReady, { OnReady } from \"@egjs/imready\";\n\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { devicePixelRatio, WEBXR_SUPPORTED } from \"../utils/browserFeature\";\nimport { PROJECTION_TYPE, STEREO_FORMAT } from \"../PanoViewer/consts\";\nimport { IS_IOS } from \"../utils/browser\";\nimport { CubemapConfig, ImageCandidate, ValueOf, VideoCandidate } from \"../types/internal\";\nimport YawPitchControl from \"../YawPitchControl/YawPitchControl\";\nimport { toImageElement, toVideoElement } from \"../utils/utils\";\n\nimport WebGLUtils from \"./WebGLUtils\";\nimport Renderer from \"./renderer/Renderer\";\nimport CubeRenderer from \"./renderer/CubeRenderer\";\nimport CubeStripRenderer from \"./renderer/CubeStripRenderer\";\nimport SphereRenderer from \"./renderer/SphereRenderer\";\nimport CylinderRenderer from \"./renderer/CylinderRenderer\";\nimport VRManager from \"./vr/VRManager\";\nimport XRManager from \"./vr/XRManager\";\nimport WebGLAnimator from \"./WebGLAnimator\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ImageType = PROJECTION_TYPE;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet DEVICE_PIXEL_RATIO = devicePixelRatio || 1;\n\n// DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다.\nif (DEVICE_PIXEL_RATIO > 2) {\n DEVICE_PIXEL_RATIO = 2;\n}\n\n// define custom events name\n/**\n * TODO: how to manage events/errortype with PanoViewer\n *\n * I think renderer events should be seperated from viewer events although it has same name.\n */\nconst EVENTS: {\n BIND_TEXTURE: \"bindTexture\";\n IMAGE_LOADED: \"imageLoaded\";\n ERROR: \"error\";\n RENDERING_CONTEXT_LOST: \"renderingContextLost\";\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\";\n} = {\n BIND_TEXTURE: \"bindTexture\",\n IMAGE_LOADED: \"imageLoaded\",\n ERROR: \"error\",\n RENDERING_CONTEXT_LOST: \"renderingContextLost\",\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\"\n};\n\nconst ERROR_TYPE = {\n INVALID_DEVICE: 10,\n NO_WEBGL: 11,\n FAIL_IMAGE_LOAD: 12,\n RENDERER_ERROR: 13\n};\n\nclass PanoImageRenderer extends Component<{\n [EVENTS.ERROR]: {\n type: number;\n message: string;\n };\n [EVENTS.IMAGE_LOADED]: {\n content: HTMLElement;\n isVideo: boolean;\n projectionType: ValueOf;\n };\n [EVENTS.BIND_TEXTURE]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_LOST]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_RESTORE]: ComponentEvent;\n}> {\n public static EVENTS = EVENTS;\n public static ERROR_TYPE = ERROR_TYPE;\n\n public sphericalConfig: {\n initialYaw: number;\n initialPitch: number;\n fieldOfView: number;\n imageType: ValueOf;\n stereoFormat: ValueOf;\n cubemapConfig: Partial;\n };\n\n public fieldOfView: number;\n public width: number;\n public height: number;\n\n public canvas: HTMLCanvasElement;\n public context: WebGLRenderingContext;\n public shaderProgram: WebGLProgram | null;\n public texture: WebGLTexture;\n\n public pMatrix: mat4;\n public mvMatrix: mat4;\n\n public textureCoordBuffer: WebGLBuffer | null = null;\n public vertexBuffer: WebGLBuffer | null = null;\n public indexBuffer: WebGLBuffer | null = null;\n\n private _wrapper: HTMLElement | null;\n private _wrapperOrigStyle: string | null;\n private _lastQuaternion: quat | null;\n private _lastYaw: number | null;\n private _lastPitch: number | null;\n private _lastFieldOfView: number | null;\n private _renderingContextAttributes?: WebGLContextAttributes;\n\n private _renderer: Renderer;\n private _contentLoader: ImReady | null;\n private _image: HTMLImageElement | HTMLImageElement[] | HTMLVideoElement | null;\n private _imageConfig: CubemapConfig | null;\n private _imageType: ValueOf;\n private _imageIsReady: boolean;\n private _isVideo: boolean;\n private _isCubeMap: boolean;\n private _shouldForceDraw: boolean;\n private _keepUpdate: boolean;\n private _hasExternalCanvas: boolean;\n\n private _yawPitchControl: YawPitchControl;\n private _animator: WebGLAnimator;\n private _vr: VRManager | XRManager | null;\n\n public constructor(\n image: ImageCandidate | VideoCandidate,\n width: number,\n height: number,\n isVideo: boolean,\n container: HTMLElement,\n canvasClass: string,\n sphericalConfig: PanoImageRenderer[\"sphericalConfig\"],\n renderingContextAttributes?: WebGLContextAttributes\n ) {\n // Super constructor\n super();\n\n this.sphericalConfig = sphericalConfig;\n this.fieldOfView = sphericalConfig.fieldOfView;\n\n this.width = width;\n this.height = height;\n\n this._lastQuaternion = null;\n this._lastYaw = null;\n this._lastPitch = null;\n this._lastFieldOfView = null;\n\n this.pMatrix = mat4.create();\n this.mvMatrix = mat4.create();\n\n // initialzie pMatrix\n mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), width / height, 0.1, 100);\n\n this.textureCoordBuffer = null;\n this.vertexBuffer = null;\n this.indexBuffer = null;\n\n this.canvas = this._initCanvas(container, canvasClass, width, height);\n\n this._setDefaultCanvasStyle();\n this._wrapper = null; // canvas wrapper\n this._wrapperOrigStyle = null;\n\n this._renderingContextAttributes = renderingContextAttributes;\n this._image = null;\n this._imageConfig = null;\n this._imageIsReady = false;\n this._shouldForceDraw = false;\n this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still.\n\n this._onContentLoad = this._onContentLoad.bind(this);\n this._onContentError = \tthis._onContentError.bind(this);\n\n this._animator = new WebGLAnimator();\n\n // VR/XR manager\n this._vr = null;\n\n if (image) {\n this.setImage({\n image,\n imageType: sphericalConfig.imageType,\n isVideo,\n cubemapConfig: sphericalConfig.cubemapConfig\n });\n }\n }\n\n // FIXME: Please refactor me to have more loose connection to yawpitchcontrol\n public setYawPitchControl(yawPitchControl: YawPitchControl) {\n this._yawPitchControl = yawPitchControl;\n }\n\n public getContent() {\n return this._image;\n }\n\n public setImage({\n image,\n imageType,\n isVideo = false,\n cubemapConfig\n }: {\n image: ImageCandidate | VideoCandidate;\n imageType: PanoImageRenderer[\"_imageType\"];\n isVideo: boolean;\n cubemapConfig: Partial;\n }) {\n this._imageIsReady = false;\n this._isVideo = isVideo;\n this._imageConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only */\n order: (imageType === ImageType.CUBEMAP) ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n },\n ...cubemapConfig\n };\n this._setImageType(imageType);\n\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._contentLoader = new ImReady()\n .on(\"ready\", this._onContentLoad)\n .on(\"error\", this._onContentError);\n\n if (isVideo) {\n this._image = toVideoElement(image as VideoCandidate);\n this._contentLoader.check([this._image]);\n this._keepUpdate = true;\n } else {\n this._image = toImageElement(image as ImageCandidate);\n this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n this._keepUpdate = false;\n }\n }\n\n public isImageLoaded() {\n return !!this._image && this._imageIsReady &&\n (!this._isVideo || (this._image as HTMLVideoElement).readyState >= 2 /* HAVE_CURRENT_DATA */);\n }\n\n public bindTexture() {\n return new Promise((res, rej) => {\n const contentLoader = this._contentLoader;\n\n if (!this._image) {\n return rej(\"Image is not defined\");\n }\n\n if (!contentLoader) {\n return rej(\"ImageLoader is not initialized\");\n }\n\n if (contentLoader.isReady()) {\n this._bindTexture();\n res();\n } else {\n contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n contentLoader.once(\"ready\", e => {\n if (e.errorCount > 0) {\n rej(\"Failed to load images.\");\n } else {\n this._bindTexture();\n res();\n }\n });\n }\n });\n }\n\n // 부모 엘리먼트에 canvas 를 붙임\n public attachTo(parentElement) {\n if (!this._hasExternalCanvas) {\n this.detach();\n parentElement.appendChild(this.canvas);\n }\n this._wrapper = parentElement;\n }\n\n public forceContextLoss() {\n if (this.hasRenderingContext()) {\n const loseContextExtension = this.context.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n\n // 부모 엘리먼트에서 canvas 를 제거\n public detach() {\n if (!this._hasExternalCanvas && this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n\n public destroy() {\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._animator.stop();\n this.detach();\n this.forceContextLoss();\n\n this.off();\n\n this.canvas.removeEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n this.canvas.removeEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n }\n\n public hasRenderingContext() {\n const ctx = this.context;\n if (\n !ctx\n || ctx.isContextLost()\n || !ctx.getProgramParameter(this.shaderProgram!, ctx.LINK_STATUS)) {\n return false;\n }\n return true;\n }\n\n public updateFieldOfView(fieldOfView) {\n this.fieldOfView = fieldOfView;\n this._updateViewport();\n }\n\n public updateViewportDimensions(width, height) {\n let viewPortChanged = false;\n\n this.width = width;\n this.height = height;\n\n const w = width * DEVICE_PIXEL_RATIO;\n const h = height * DEVICE_PIXEL_RATIO;\n\n if (w !== this.canvas.width) {\n this.canvas.width = w;\n viewPortChanged = true;\n }\n\n if (h !== this.canvas.height) {\n this.canvas.height = h;\n viewPortChanged = true;\n }\n\n if (!viewPortChanged) {\n return;\n }\n\n this._updateViewport();\n this._shouldForceDraw = true;\n }\n\n public keepUpdate(doUpdate) {\n if (doUpdate && this.isImageLoaded() === false) {\n // Force to draw a frame after image is loaded on render()\n this._shouldForceDraw = true;\n }\n\n this._keepUpdate = doUpdate;\n }\n\n public startRender() {\n this._animator.setCallback(this._render.bind(this));\n this._animator.start();\n }\n\n public stopRender() {\n this._animator.stop();\n }\n\n public renderWithQuaternion(quaternion, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // updatefieldOfView only if fieldOfView is changed.\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion);\n\n this._draw();\n\n this._lastQuaternion = quat.clone(quaternion);\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n public renderWithYawPitch(yaw, pitch, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastYaw !== null && this._lastYaw === yaw &&\n this._lastPitch !== null && this._lastPitch === pitch &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n mat4.identity(this.mvMatrix);\n mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch));\n mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw));\n\n this._draw();\n\n this._lastYaw = yaw;\n this._lastPitch = pitch;\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n /**\n * Returns projection renderer by each type\n */\n public getProjectionRenderer() {\n return this._renderer;\n }\n\n /**\n * @return Promise\n */\n public enterVR(options) {\n const vr = this._vr;\n\n if (!WEBXR_SUPPORTED && !(navigator as any).getVRDisplays) {\n return Promise.reject(\"VR is not available on this browser.\");\n }\n if (vr && vr.isPresenting()) {\n return Promise.resolve(\"VR already enabled.\");\n }\n\n return this._requestPresent(options);\n }\n\n public exitVR = () => {\n const vr = this._vr;\n const gl = this.context;\n const animator = this._animator;\n\n if (!vr) return;\n\n vr.removeEndCallback(this.exitVR);\n vr.destroy();\n this._vr = null;\n\n // Restore canvas & context on iOS\n if (IS_IOS) {\n this._restoreStyle();\n }\n this.updateViewportDimensions(this.width, this.height);\n this._updateViewport();\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._bindBuffers();\n this._shouldForceDraw = true;\n\n animator.stop();\n animator.setContext(window);\n animator.setCallback(this._render.bind(this));\n animator.start();\n };\n\n private _setImageType(imageType) {\n if (!imageType || this._imageType === imageType) {\n return;\n }\n\n this._imageType = imageType;\n this._isCubeMap = imageType === ImageType.CUBEMAP;\n\n if (this._renderer) {\n this._renderer.off();\n }\n\n switch (imageType) {\n case ImageType.CUBEMAP:\n this._renderer = new CubeRenderer();\n break;\n case ImageType.CUBESTRIP:\n this._renderer = new CubeStripRenderer();\n break;\n case ImageType.PANORAMA:\n this._renderer = new CylinderRenderer();\n break;\n case ImageType.STEREOSCOPIC_EQUI:\n this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat);\n break;\n default:\n this._renderer = new SphereRenderer(STEREO_FORMAT.NONE);\n break;\n }\n\n this._renderer.on(Renderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERER_ERROR,\n message: e.message\n }));\n });\n\n this._initWebGL();\n }\n\n private _initCanvas(container: HTMLElement, canvasClass: string, width: number, height: number) {\n const canvasInContainer = container.querySelector(`.${canvasClass}`);\n const canvas = canvasInContainer || this._createCanvas(canvasClass);\n\n this._hasExternalCanvas = !!canvasInContainer;\n\n canvas.width = width;\n canvas.height = height;\n\n this._onWebglcontextlost = this._onWebglcontextlost.bind(this);\n this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this);\n\n canvas.addEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n canvas.addEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n\n return canvas;\n }\n\n private _createCanvas(className: string) {\n const canvas = document.createElement(\"canvas\");\n\n canvas.className = className;\n\n return canvas;\n }\n\n private _setDefaultCanvasStyle() {\n const canvas = this.canvas;\n\n canvas.style.bottom = \"0\";\n canvas.style.left = \"0\";\n canvas.style.right = \"0\";\n canvas.style.top = \"0\";\n canvas.style.margin = \"auto\";\n canvas.style.maxHeight = \"100%\";\n canvas.style.maxWidth = \"100%\";\n canvas.style.outline = \"none\";\n canvas.style.position = \"absolute\";\n }\n\n private _onContentError() {\n this._imageIsReady = false;\n this._image = null;\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_IMAGE_LOAD,\n message: \"failed to load image\"\n }));\n\n return false;\n }\n\n private _triggerContentLoad() {\n this.trigger(new ComponentEvent(EVENTS.IMAGE_LOADED, {\n content: this._image as HTMLElement,\n isVideo: this._isVideo,\n projectionType: this._imageType\n }));\n }\n\n private _onContentLoad(e: OnReady) {\n if (e.errorCount > 0) return;\n\n this._imageIsReady = true;\n\n this._triggerContentLoad();\n }\n\n private _initShaderProgram() {\n const gl = this.context;\n\n if (this.shaderProgram) {\n gl.deleteProgram(this.shaderProgram);\n this.shaderProgram = null;\n }\n\n const renderer = this._renderer;\n\n const vsSource = renderer.getVertexShaderSource();\n const fsSource = renderer.getFragmentShaderSource();\n\n const vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource)!;\n const fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource)!;\n\n const shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader);\n\n if (!shaderProgram) {\n throw new Error(`Failed to initialize shaders: ${WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())}`);\n }\n\n gl.useProgram(shaderProgram);\n (shaderProgram as any).vertexPositionAttribute = gl.getAttribLocation(shaderProgram, \"aVertexPosition\");\n (shaderProgram as any).pMatrixUniform = gl.getUniformLocation(shaderProgram, \"uPMatrix\");\n (shaderProgram as any).mvMatrixUniform = gl.getUniformLocation(shaderProgram, \"uMVMatrix\");\n (shaderProgram as any).samplerUniform = gl.getUniformLocation(shaderProgram, \"uSampler\");\n (shaderProgram as any).textureCoordAttribute = gl.getAttribLocation(shaderProgram, \"aTextureCoord\");\n (shaderProgram as any).uEye = gl.getUniformLocation(shaderProgram, \"uEye\");\n\n gl.enableVertexAttribArray((shaderProgram as any).vertexPositionAttribute);\n gl.enableVertexAttribArray((shaderProgram as any).textureCoordAttribute);\n\n // clear buffer\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\n // Use TEXTURE0\n gl.uniform1i((shaderProgram as any).samplerUniform, 0);\n\n this.shaderProgram = shaderProgram;\n }\n\n private _onWebglcontextlost(e) {\n e.preventDefault();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_LOST));\n }\n\n private _onWebglcontextrestored() {\n this._initWebGL();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_RESTORE));\n }\n\n private _updateViewport() {\n mat4.perspective(\n this.pMatrix,\n glMatrix.toRadian(this.fieldOfView),\n this.canvas.width / this.canvas.height,\n 0.1,\n 100);\n\n this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight);\n }\n\n private _initWebGL() {\n let gl: WebGLRenderingContext;\n\n // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed.\n try {\n this._initRenderingContext();\n gl = this.context;\n\n this.updateViewportDimensions(this.width, this.height);\n this._initShaderProgram();\n } catch (e) {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n this.destroy();\n console.error(e); // eslint-disable-line no-console\n return;\n }\n // 캔버스를 투명으로 채운다.\n gl.clearColor(0, 0, 0, 0);\n const textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\n\n if (this.texture) {\n gl.deleteTexture(this.texture);\n }\n\n this.texture = WebGLUtils.createTexture(gl, textureTarget)!;\n\n if (this._imageType === ImageType.CUBESTRIP) {\n // TODO: Apply following options on other projection type.\n gl.enable(gl.CULL_FACE);\n // gl.enable(gl.DEPTH_TEST);\n }\n }\n\n private _initRenderingContext() {\n if (this.hasRenderingContext()) {\n return;\n }\n\n if (!window.WebGLRenderingContext) {\n throw new Error(\"WebGLRenderingContext not available.\");\n }\n\n this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes)!;\n\n if (!this.context) {\n throw new Error(\"Failed to acquire 3D rendering context\");\n }\n }\n\n private _initBuffers() {\n const image = this._image as HTMLImageElement | HTMLVideoElement;\n\n const vertexPositionData = this._renderer.getVertexPositionData();\n const indexData = this._renderer.getIndexData();\n const textureCoordData = this._renderer.getTextureCoordData({\n image,\n imageConfig: this._imageConfig!\n });\n const gl = this.context;\n\n this.vertexBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3,\n (this.shaderProgram as any).vertexPositionAttribute);\n\n this.indexBuffer = WebGLUtils.initBuffer(\n gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1);\n\n this.textureCoordBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2,\n (this.shaderProgram as any).textureCoordAttribute);\n\n this._bindBuffers();\n }\n\n private _bindTexture() {\n // Detect if it is EAC Format while CUBESTRIP mode.\n // We assume it is EAC if image is not 3/2 ratio.\n if (this._imageType === ImageType.CUBESTRIP) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const isEAC = width && height && width / height !== 1.5 ? 1 : 0;\n\n this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram!, \"uIsEAC\"), isEAC);\n } else if (this._imageType === ImageType.PANORAMA) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const imageAspectRatio = width && height && width / height;\n\n this._renderer.updateShaderData({imageAspectRatio});\n }\n\n // initialize shader buffers after image is loaded.(by updateShaderData)\n // because buffer may be differ by image size.(eg. CylinderRenderer)\n this._initBuffers();\n\n this._renderer.bindTexture(\n this.context,\n this.texture,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n this._shouldForceDraw = true;\n\n this.trigger(new ComponentEvent(EVENTS.BIND_TEXTURE));\n }\n\n private _updateTexture() {\n this._renderer.updateTexture(\n this.context,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n }\n\n private _render() {\n const yawPitchControl = this._yawPitchControl;\n const fov = yawPitchControl.getFov();\n\n if (yawPitchControl.shouldRenderWithQuaternion()) {\n const quaternion = yawPitchControl.getQuaternion();\n\n this.renderWithQuaternion(quaternion, fov);\n } else {\n const yawPitch = yawPitchControl.getYawPitch();\n\n this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov);\n }\n }\n\n private _renderStereo = (time: number, frame: XRFrame) => {\n const vr = this._vr;\n const gl = this.context;\n\n const eyeParams = vr!.getEyeParams(gl, frame);\n\n if (!eyeParams) return;\n\n vr!.beforeRender(gl, frame);\n\n // Render both eyes\n for (const eyeIndex of [0, 1]) {\n const eyeParam = eyeParams[eyeIndex];\n\n this.mvMatrix = eyeParam.mvMatrix;\n this.pMatrix = eyeParam.pMatrix;\n\n gl.viewport(...eyeParam.viewport as [number, number, number, number]);\n gl.uniform1f((this.shaderProgram as any).uEye, eyeIndex);\n\n this._bindBuffers();\n this._draw();\n }\n\n vr!.afterRender();\n };\n\n private _bindBuffers() {\n const gl = this.context;\n const program = this.shaderProgram;\n\n const vertexBuffer = this.vertexBuffer;\n const textureCoordBuffer = this.textureCoordBuffer;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray((program as any).vertexPositionAttribute);\n gl.vertexAttribPointer(\n (program as any).vertexPositionAttribute, (vertexBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);\n gl.enableVertexAttribArray((program as any).textureCoordAttribute);\n gl.vertexAttribPointer(\n (program as any).textureCoordAttribute, (textureCoordBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n }\n\n private _draw() {\n if (this._isVideo && this._keepUpdate) {\n this._updateTexture();\n }\n\n this._renderer.render({\n gl: this.context,\n shaderProgram: this.shaderProgram!,\n indexBuffer: this.indexBuffer!,\n mvMatrix: this.mvMatrix,\n pMatrix: this.pMatrix\n });\n }\n\n private _requestPresent(options) {\n const gl = this.context;\n const canvas = this.canvas;\n const animator = this._animator;\n\n this._vr = WEBXR_SUPPORTED ?\n new XRManager(options) :\n new VRManager();\n\n const vr = this._vr;\n\n animator.stop();\n return new Promise((resolve, reject) => {\n vr.requestPresent(canvas, gl)\n .then(() => {\n vr.addEndCallback(this.exitVR);\n animator.setContext(vr.context);\n animator.setCallback(this._onFirstVRFrame);\n\n if (IS_IOS) {\n this._setWrapperFullscreen();\n }\n\n this._shouldForceDraw = true;\n animator.start();\n\n resolve(\"success\");\n })\n .catch(e => {\n vr.destroy();\n this._vr = null;\n animator.start();\n\n reject(e);\n });\n });\n }\n\n private _onFirstVRFrame = (time, frame) => {\n const vr = this._vr!;\n const gl = this.context;\n const animator = this._animator;\n\n // If rendering is not ready, wait for next frame\n if (!vr.canRender(frame)) return;\n\n const minusZDir = vec3.fromValues(0, 0, -1);\n const eyeParam = vr.getEyeParams(gl, frame)![0];\n // Extract only rotation\n const mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix);\n const pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix);\n\n const mvInv = mat3.invert(mat3.create(), mvMatrix);\n const pInv = mat3.invert(mat3.create(), pMatrix);\n const viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv);\n\n vec3.transformMat3(viewDir, viewDir, mvInv);\n\n const yawOffset = mathUtil.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1));\n\n if (yawOffset === 0) {\n // If the yawOffset is exactly 0, then device sensor is not ready\n // So read it again until it has any value in it\n return;\n }\n\n vr.setYawOffset(yawOffset);\n animator.setCallback(this._renderStereo);\n };\n\n private _setWrapperFullscreen() {\n const wrapper = this._wrapper;\n\n if (!wrapper) return;\n\n this._wrapperOrigStyle = wrapper.getAttribute(\"style\");\n const wrapperStyle = wrapper.style;\n\n wrapperStyle.width = \"100vw\";\n wrapperStyle.height = \"100vh\";\n wrapperStyle.position = \"fixed\";\n wrapperStyle.left = \"0\";\n wrapperStyle.top = \"0\";\n wrapperStyle.zIndex = \"9999\";\n }\n\n private _restoreStyle() {\n const wrapper = this._wrapper;\n const canvas = this.canvas;\n\n if (!wrapper) return;\n\n if (this._wrapperOrigStyle) {\n wrapper.setAttribute(\"style\", this._wrapperOrigStyle);\n } else {\n wrapper.removeAttribute(\"style\");\n }\n\n this._wrapperOrigStyle = null;\n\n // Restore canvas style\n canvas.removeAttribute(\"style\");\n this._setDefaultCanvasStyle();\n }\n}\n\nexport default PanoImageRenderer;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Promise from \"promise-polyfill\";\nimport { quat } from \"gl-matrix\";\n\nimport { DeviceMotionEvent, checkXRSupport } from \"../utils/browserFeature\";\nimport YawPitchControl, { YawPitchControlOptions } from \"../YawPitchControl/YawPitchControl\";\nimport PanoImageRenderer from \"../PanoImageRenderer/PanoImageRenderer\";\nimport WebGLUtils from \"../PanoImageRenderer/WebGLUtils\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { CubemapConfig, ValueOf } from \"../types/internal\";\nimport { AnimationEndEvent, ReadyEvent, ViewChangeEvent, ErrorEvent } from \"../types/event\";\n\nimport { ERROR_TYPE, PANOVIEWER_EVENTS as EVENTS, GYRO_MODE, PROJECTION_TYPE, STEREO_FORMAT, DEFAULT_CANVAS_CLASS } from \"./consts\";\n\nexport interface PanoViewerOptions {\n image: string | HTMLElement;\n video: string | HTMLElement;\n projectionType: ValueOf;\n cubemapConfig: Partial;\n stereoFormat: ValueOf;\n width: number;\n height: number;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n touchDirection: ValueOf;\n canvasClass: string;\n}\n\nexport interface PanoViewerEvent {\n ready: ReadyEvent;\n viewChange: ViewChangeEvent;\n animationEnd: AnimationEndEvent;\n error: ErrorEvent;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * PanoViewer\n */\nclass PanoViewer extends Component {\n /**\n * Check whether the current environment can execute PanoViewer\n * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다.\n * @return PanoViewer executable PanoViewer 실행가능 여부\n */\n public static isSupported(): boolean {\n return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL();\n }\n\n /**\n * Check whether the current environment supports the WebGL\n * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다.\n * @return WebGL support WebGL 지원여부\n */\n public static isWebGLAvailable(): boolean {\n return WebGLUtils.isWebGLAvailable();\n }\n\n /**\n * Check whether the current environment supports the gyro sensor.\n * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다.\n * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수\n */\n public static isGyroSensorAvailable(callback: (isAvailable: boolean) => any) {\n if (!DeviceMotionEvent && callback) {\n callback(false);\n return;\n }\n\n let onDeviceMotionChange;\n\n const checkGyro = () => new Promise(res => {\n onDeviceMotionChange = deviceMotion => {\n const isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null);\n\n res(isGyroSensorAvailable);\n };\n\n window.addEventListener(\"devicemotion\", onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n Promise.race([checkGyro(), timeout()]).then((isGyroSensorAvailable: boolean) => {\n window.removeEventListener(\"devicemotion\", onDeviceMotionChange);\n\n if (callback) {\n callback(isGyroSensorAvailable);\n }\n\n PanoViewer.isGyroSensorAvailable = fb => {\n if (fb) {\n fb(isGyroSensorAvailable);\n }\n return isGyroSensorAvailable;\n };\n });\n }\n\n private static _isValidTouchDirection(direction) {\n return direction === PanoViewer.TOUCH_DIRECTION.NONE ||\n direction === PanoViewer.TOUCH_DIRECTION.YAW ||\n direction === PanoViewer.TOUCH_DIRECTION.PITCH ||\n direction === PanoViewer.TOUCH_DIRECTION.ALL;\n }\n\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @name VERSION\n * @static\n * @type {String}\n * @example\n * eg.view360.PanoViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.PanoViewer\n */\n public static VERSION = VERSION;\n public static ERROR_TYPE = ERROR_TYPE;\n public static EVENTS = EVENTS;\n public static PROJECTION_TYPE = PROJECTION_TYPE;\n public static GYRO_MODE = GYRO_MODE;\n // This should be deprecated!\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static ProjectionType = PROJECTION_TYPE;\n public static STEREO_FORMAT = STEREO_FORMAT;\n\n /**\n * Constant value for touch directions\n * @ko 터치 방향에 대한 상수 값.\n * @namespace\n * @name TOUCH_DIRECTION\n */\n public static TOUCH_DIRECTION = {\n /**\n * Constant value for none direction.\n * @ko none 방향에 대한 상수 값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 1\n */\n NONE: YawPitchControl.TOUCH_DIRECTION_NONE,\n /**\n * Constant value for horizontal(yaw) direction.\n * @ko horizontal(yaw) 방향에 대한 상수 값.\n * @name YAW\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 6\n */\n YAW: YawPitchControl.TOUCH_DIRECTION_YAW,\n /**\n * Constant value for vertical direction.\n * @ko vertical(pitch) 방향에 대한 상수 값.\n * @name PITCH\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 24\n */\n PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH,\n /**\n * Constant value for all direction.\n * @ko all 방향에 대한 상수 값.\n * @name ALL\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 30\n */\n ALL: YawPitchControl.TOUCH_DIRECTION_ALL\n };\n\n private _container: HTMLElement;\n // Options\n private _image: ConstructorParameters[0];\n private _isVideo: boolean;\n private _projectionType: ValueOf;\n private _cubemapConfig: Partial;\n private _stereoFormat: ValueOf;\n private _width: number;\n private _height: number;\n private _yaw: number;\n private _pitch: number;\n private _fov: number;\n private _gyroMode: ValueOf;\n private _quaternion: quat | null;\n private _aspectRatio: number;\n private _isReady: boolean;\n private _canvasClass: string;\n\n // Internal Values\n private _photoSphereRenderer: PanoImageRenderer | null;\n private _yawPitchControl: YawPitchControl | null;\n\n /**\n * @classdesc 360 media viewer\n * @ko 360 미디어 뷰어\n *\n * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트\n * @param options\n *\n * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
\n * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다.\n * @param {Object} [options.cubemapConfig.order = \"RLUDBF\"(ProjectionType === CUBEMAP) | \"RLUDFB\" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서\n * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다.\n * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다.\n * @param {String} [options.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
\n * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위)\n * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위)\n * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위)\n * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위)\n * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위)\n * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다\n * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다.\n * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키\n * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE}
\n * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위\n * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위\n * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위\n * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
\n * @param {String} [options.canvasClass=\"view360-canvas\"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n *\n * @example\n * ```\n * // PanoViewer Creation\n * // create PanoViewer with option\n * var PanoViewer = eg.view360.PanoViewer;\n * // Area where the image will be displayed(HTMLElement)\n * var container = document.getElementById(\"myPanoViewer\");\n *\n * var panoViewer = new PanoViewer(container, {\n * // If projectionType is not specified, the default is \"equirectangular\".\n * // Specifies an image of the \"equirectangular\" type.\n * image: \"/path/to/image/image.jpg\"\n * });\n * ```\n *\n * @example\n * ```\n * // Cubemap Config Setting Example\n * // For support Youtube EAC projection, You should set cubemapConfig as follows.\n * cubemapConfig: {\n * order: \"LFRDBU\",\n * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}]\n * }\n * ```\n */\n public constructor(container: HTMLElement, options: Partial = {}) {\n super();\n\n // Raises the error event if webgl is not supported.\n if (!WebGLUtils.isWebGLAvailable()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n }, 0);\n return this;\n }\n\n if (!WebGLUtils.isStableWebGL()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_DEVICE,\n message: \"blacklisted browser\"\n }));\n }, 0);\n\n return this;\n }\n\n if (!!options.image && !!options.video) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_RESOURCE,\n message: \"Specifying multi resouces(both image and video) is not valid.\"\n }));\n }, 0);\n return this;\n }\n\n // Check XR support at not when imported, but when created.\n // This is intended to make polyfills easier to use.\n checkXRSupport();\n\n this._container = container;\n this._image = options.image! as HTMLImageElement || options.video! as HTMLVideoElement;\n this._isVideo = !!options.video;\n this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/\n order: this._projectionType === PROJECTION_TYPE.CUBEMAP ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...options.cubemapConfig\n };\n this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n\n // If the width and height are not provided, will use the size of the container.\n this._width = options.width || parseInt(window.getComputedStyle(container).width, 10);\n this._height = options.height || parseInt(window.getComputedStyle(container).height, 10);\n\n /**\n * Cache the direction for the performance in renderLoop\n *\n * This value should be updated by \"change\" event of YawPitchControl.\n */\n this._yaw = options.yaw || 0;\n this._pitch = options.pitch || 0;\n this._fov = options.fov || 65;\n\n this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH;\n this._quaternion = null;\n\n this._aspectRatio = this._height !== 0 ? this._width / this._height : 1;\n\n this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS;\n\n const fovRange = options.fovRange || [30, 110];\n const touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ?\n options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL;\n const yawPitchConfig = {\n ...options,\n ...{\n element: container,\n yaw: this._yaw,\n pitch: this._pitch,\n fov: this._fov,\n gyroMode: this._gyroMode,\n fovRange,\n aspectRatio: this._aspectRatio,\n touchDirection\n }\n };\n\n this._isReady = false;\n\n this._initYawPitchControl(yawPitchConfig);\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n /**\n * Get the video element that the viewer is currently playing. You can use this for playback.\n * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다.\n * @return HTMLVideoElementHTMLVideoElement\n * @example\n * ```\n * var videoTag = panoViewer.getVideo();\n * videoTag.play(); // play the video!\n * ```\n */\n public getVideo() {\n if (!this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent() as HTMLVideoElement;\n }\n\n /**\n * Set the video information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정)\n * @param {object} param\n * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}(\"equirectangular\")] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setVideo(\"/path/to/video/video.mp4\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR\n * });\n * ```\n */\n public setVideo(video: string | HTMLElement | { type: string; src: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n }> = {}) {\n if (video) {\n this.setImage(video, {\n projectionType: param.projectionType,\n isVideo: true,\n cubemapConfig: param.cubemapConfig,\n stereoFormat: param.stereoFormat\n });\n }\n\n return this;\n }\n\n /**\n * Get the image information that the viewer is currently using.\n * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다.\n * @return Image Object이미지 객체\n * @example\n * var imageObj = panoViewer.getImage();\n */\n public getImage() {\n if (this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent();\n }\n\n /**\n * Set the image information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.)\n * @param {object} param Additional information이미지 추가 정보\n * @param {string} [param.projectionType=\"equirectangular\"] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setImage(\"/path/to/image/image.png\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP\n * });\n * ```\n */\n public setImage(image: string | HTMLElement | { src: string; type: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n isVideo: boolean;\n }> = {}) {\n const cubemapConfig = {\n ...{\n order: \"RLUDBF\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...param.cubemapConfig\n };\n const stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n const isVideo = !!(param.isVideo);\n\n if (this._image && this._isVideo !== isVideo) {\n /* eslint-disable no-console */\n console.warn(\"PanoViewer is not currently supporting content type changes. (Image <--> Video)\");\n /* eslint-enable no-console */\n return this;\n }\n\n if (image) {\n this._deactivate();\n\n this._image = image as HTMLImageElement;\n this._isVideo = isVideo;\n this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = cubemapConfig;\n this._stereoFormat = stereoFormat;\n\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n return this;\n }\n\n /**\n * Set whether the renderer always updates the texture and renders.\n * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다.\n * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public keepUpdate(doUpdate: boolean) {\n this._photoSphereRenderer!.keepUpdate(doUpdate);\n return this;\n }\n\n /**\n * Get the current projection type (equirectangular/cube)\n * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다.\n * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE}\n */\n public getProjectionType() {\n return this._projectionType;\n }\n\n /**\n * Activate the device's motion sensor, and return the Promise whether the sensor is enabled\n * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element.\n * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다.\n * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다.\n */\n public enableSensor() {\n return new Promise((resolve, reject) => {\n if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\") {\n DeviceMotionEvent.requestPermission().then(permissionState => {\n if (permissionState === \"granted\") {\n resolve();\n } else {\n reject(new Error(\"permission denied\"));\n }\n }).catch(e => {\n // This can happen when this method wasn't triggered by user interaction\n reject(e);\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Disable the device's motion sensor.\n * @ko 디바이스의 모션 센서를 비활성화합니다.\n * @deprecated\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public disableSensor() {\n return this;\n }\n\n /**\n * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred).\n * This method must be used in the context of user interaction, like onclick callback on the button element.\n * It can be rejected when an enabling device sensor fails or image/video is still loading(\"ready\" event not triggered).\n * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다)\n * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우(\"ready\"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다.\n * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요.\n * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error)\n */\n public enterVR(options: {\n requiredFeatures?: any[];\n optionalFeatures?: any[];\n [key: string]: any;\n } = {}): globalThis.Promise {\n if (!this._isReady) {\n return Promise.reject(new Error(\"PanoViewer is not ready to show image.\")) as any;\n }\n\n return new Promise((resolve, reject) => {\n this.enableSensor()\n .then(() => this._photoSphereRenderer!.enterVR(options))\n .then((res: string) => resolve(res))\n .catch(e => reject(e));\n }) as any;\n }\n\n /**\n * Exit VR stereo rendering mode.\n * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public exitVR() {\n this._photoSphereRenderer!.exitVR();\n return this;\n }\n\n /**\n * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}.\n * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다.\n * @param useZoom\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseZoom(useZoom: boolean): this {\n if (typeof useZoom === \"boolean\") {\n this._yawPitchControl!.option(\"useZoom\", useZoom);\n }\n\n return this;\n }\n\n /**\n * When true, enables the keyboard move key control: awsd, arrow keys\n * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키)\n * @param useKeyboard\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseKeyboard(useKeyboard: boolean): this {\n this._yawPitchControl!.option(\"useKeyboard\", useKeyboard);\n return this;\n }\n\n /**\n * Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")\n * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")\n * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE}\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setGyroMode(\"yawPitch\");\n * //equivalent\n * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH);\n * ```\n */\n public setGyroMode(gyroMode: PanoViewer[\"_gyroMode\"]) {\n this._yawPitchControl!.option(\"gyroMode\", gyroMode);\n return this;\n }\n\n /**\n * Set the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 설정합니다.\n * @param range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setFovRange([50, 90]);\n */\n public setFovRange(range: number[]) {\n this._yawPitchControl!.option(\"fovRange\", range);\n return this;\n }\n\n /**\n * Get the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 반환합니다.\n * @return FOV range\n * @example\n * var range = panoViewer.getFovRange(); // [50, 90]\n */\n public getFovRange(): [number, number] {\n return this._yawPitchControl!.option(\"fovRange\") as [number, number];\n }\n\n /**\n * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size.\n * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다.\n * @param {object} [size]\n * @param {number} [size.width=width of the container]\n * @param {number} [size.height=height of the container]\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public updateViewportDimensions(size: Partial<{\n width: number;\n height: number;\n }> = {}): this {\n if (!this._isReady) {\n return this;\n }\n\n let containerSize;\n\n if (size.width === undefined || size.height === undefined) {\n containerSize = window.getComputedStyle(this._container);\n }\n\n const width = size.width || parseInt(containerSize.width, 10);\n const height = size.height || parseInt(containerSize.height, 10);\n\n // Skip if viewport is not changed.\n if (width === this._width && height === this._height) {\n return this;\n }\n\n this._width = width;\n this._height = height;\n\n this._aspectRatio = width / height;\n this._photoSphereRenderer!.updateViewportDimensions(width, height);\n this._yawPitchControl!.option(\"aspectRatio\", this._aspectRatio);\n this._yawPitchControl!.updatePanScale({height});\n\n this.lookAt({}, 0);\n return this;\n }\n\n /**\n * Get the current field of view(FOV)\n * @ko 현재 field of view(FOV) 값을 반환합니다.\n */\n public getFov(): number {\n return this._fov;\n }\n\n /**\n * Get current yaw value\n * @ko 현재 yaw 값을 반환합니다.\n */\n public getYaw() {\n return this._yaw;\n }\n\n /**\n * Get current pitch value\n * @ko 현재 pitch 값을 반환합니다.\n */\n public getPitch() {\n return this._pitch;\n }\n\n /**\n * Get the range of controllable Yaw values\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n */\n public getYawRange(): [number, number] {\n return this._yawPitchControl!.option(\"yawRange\") as [number, number];\n }\n\n /**\n * Get the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다.\n */\n public getPitchRange(): [number, number] {\n return this._yawPitchControl!.option(\"pitchRange\") as [number, number];\n }\n\n /**\n * Set the range of controllable yaw\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setYawRange([-90, 90]);\n */\n public setYawRange(yawRange: number[]) {\n this._yawPitchControl!.option(\"yawRange\", yawRange);\n return this;\n }\n\n /**\n * Set the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 설정합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setPitchRange([-40, 40]);\n */\n public setPitchRange(pitchRange: number[]) {\n this._yawPitchControl!.option(\"pitchRange\", pitchRange);\n return this;\n }\n\n /**\n * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed.\n * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다.\n * @param showPolePoint\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setShowPolePoint(showPolePoint: boolean) {\n this._yawPitchControl!.option(\"showPolePoint\", showPolePoint);\n return this;\n }\n\n /**\n * Set a new view by setting camera configuration. Any parameters not specified remain the same.\n * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다.\n * @param {object} orientation\n * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위)\n * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위)\n * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위)\n * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초)\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * // Change the yaw angle (absolute angle) to 30 degrees for one second.\n * panoViewer.lookAt({yaw: 30}, 1000);\n * ```\n */\n public lookAt(orientation: Partial<{\n yaw: number;\n pitch: number;\n fov: number;\n }>, duration: number = 0) {\n if (!this._isReady) {\n return this;\n }\n\n const yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw;\n const pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch;\n const pitchRange = this._yawPitchControl!.option(\"pitchRange\");\n const verticalAngleOfImage = pitchRange[1] - pitchRange[0];\n let fov = orientation.fov !== undefined ? orientation.fov : this._fov;\n\n if (verticalAngleOfImage < fov) {\n fov = verticalAngleOfImage;\n }\n\n this._yawPitchControl!.lookAt({yaw, pitch, fov}, duration);\n\n if (duration === 0) {\n this._photoSphereRenderer!.renderWithYawPitch(yaw, pitch, fov);\n }\n return this;\n }\n\n /**\n * Set touch direction by which user can control.\n * @ko 사용자가 조작가능한 터치 방향을 지정합니다.\n * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @return PanoViewer instance\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Limit the touch direction to the yaw direction only.\n * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW);\n * ```\n */\n public setTouchDirection(direction: number): this {\n if (PanoViewer._isValidTouchDirection(direction)) {\n this._yawPitchControl!.option(\"touchDirection\", direction);\n }\n\n return this;\n }\n\n /**\n * Returns touch direction by which user can control\n * @ko 사용자가 조작가능한 터치 방향을 반환한다.\n * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Returns the current touch direction.\n * var dir = panoViewer.getTouchDirection();\n * ```\n */\n public getTouchDirection(): number {\n return this._yawPitchControl!.option(\"touchDirection\") ;\n }\n\n /**\n * Destroy viewer. Remove all registered event listeners and remove viewer canvas.\n * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public destroy(): this {\n this._deactivate();\n\n if (this._yawPitchControl) {\n this._yawPitchControl.destroy();\n this._yawPitchControl = null;\n }\n\n return this;\n }\n\n // TODO: Remove parameters as they're just using private values\n private _initRenderer(\n yaw: number,\n pitch: number,\n fov: number,\n projectionType: PanoViewer[\"_projectionType\"],\n cubemapConfig: PanoViewer[\"_cubemapConfig\"]\n ) {\n this._photoSphereRenderer = new PanoImageRenderer(\n this._image,\n this._width,\n this._height,\n this._isVideo,\n this._container,\n this._canvasClass,\n {\n initialYaw: yaw,\n initialPitch: pitch,\n fieldOfView: fov,\n imageType: projectionType,\n cubemapConfig,\n stereoFormat: this._stereoFormat\n },\n );\n this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl!);\n\n this._bindRendererHandler();\n\n this._photoSphereRenderer\n .bindTexture()\n .then(() => this._activate())\n .catch(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_BIND_TEXTURE,\n message: \"failed to bind texture\"\n }));\n });\n }\n\n /**\n * @private\n * update values of YawPitchControl if needed.\n * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image.\n *\n * This function should be called after isReady status is true.\n */\n private _updateYawPitchIfNeeded() {\n if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) {\n // update fov by aspect ratio\n const image = this._photoSphereRenderer!.getContent()! as HTMLImageElement;\n let imageAspectRatio = image.naturalWidth / image.naturalHeight;\n let yawSize;\n let maxFov;\n\n // If height is larger than width, then we assume it's rotated by 90 degree.\n if (imageAspectRatio < 1) {\n // So inverse the aspect ratio.\n imageAspectRatio = 1 / imageAspectRatio;\n }\n\n if (imageAspectRatio < 6) {\n yawSize = mathUtil.toDegree(imageAspectRatio);\n // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5\n maxFov = mathUtil.toDegree(Math.atan(0.5)) * 2;\n } else {\n yawSize = 360;\n maxFov = (360 / imageAspectRatio); // Make it 5 fixed as axes does.\n }\n\n // console.log(\"_updateYawPitchIfNeeded\", maxFov, \"aspectRatio\", image.naturalWidth, image.naturalHeight, \"yawSize\", yawSize);\n const minFov = (this._yawPitchControl!.option(\"fovRange\"))[0];\n\n // this option should be called after fov is set.\n this._yawPitchControl!.option({\n \"fov\": maxFov, /* parameter for internal validation for pitchrange */\n \"yawRange\": [-yawSize / 2, yawSize / 2],\n \"pitchRange\": [-maxFov / 2, maxFov / 2],\n \"fovRange\": [minFov, maxFov]\n });\n this.lookAt({fov: maxFov});\n }\n }\n\n private\t_bindRendererHandler() {\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, e));\n });\n\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, () => {\n this._deactivate();\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERING_CONTEXT_LOST,\n message: \"webgl rendering context lost\"\n }));\n });\n }\n\n private _initYawPitchControl(yawPitchConfig: Partial) {\n this._yawPitchControl = new YawPitchControl(yawPitchConfig);\n\n this._yawPitchControl.on(EVENTS.ANIMATION_END, e => {\n this.trigger(new ComponentEvent(EVENTS.ANIMATION_END, e));\n });\n\n this._yawPitchControl.on(\"change\", e => {\n this._yaw = e.yaw;\n this._pitch = e.pitch;\n this._fov = e.fov;\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(EVENTS.VIEW_CHANGE, {\n yaw: e.yaw,\n pitch: e.pitch,\n fov: e.fov,\n quaternion: e.quaternion,\n isTrusted: e.isTrusted\n }));\n });\n }\n\n private _activate() {\n this._photoSphereRenderer!.attachTo(this._container);\n this._yawPitchControl!.enable();\n\n this.updateViewportDimensions();\n\n this._isReady = true;\n\n // update yawPitchControl after isReady status is true.\n this._updateYawPitchIfNeeded();\n\n this.trigger(new ComponentEvent(EVENTS.READY));\n this._photoSphereRenderer!.startRender();\n }\n\n /**\n * Destroy webgl context and block user interaction and stop rendering\n */\n private _deactivate() {\n // Turn off the video if it has one\n const video = this.getVideo();\n if (video) {\n video.pause();\n }\n\n if (this._isReady) {\n this._photoSphereRenderer!.stopRender();\n this._yawPitchControl!.disable();\n this._isReady = false;\n }\n\n if (this._photoSphereRenderer) {\n this._photoSphereRenderer.destroy();\n this._photoSphereRenderer = null;\n }\n }\n}\n\nexport default PanoViewer;\n\n","import { SpinViewerOptions, SpinViewerEvent } from \"./SpinViewer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const SPINVIEWER_OPTIONS: { [key in keyof SpinViewerOptions]: true } = {\n imageUrl: true,\n rowCount: true,\n colCount: true,\n width: true,\n height: true,\n autoHeight: true,\n colRow: true,\n scale: true,\n frameIndex: true,\n wrapperClass: true,\n imageClass: true\n};\n\nexport const SPINVIEWER_EVENTS: {\n [key: string]: keyof SpinViewerEvent;\n} = {\n LOAD: \"load\",\n IMAGE_ERROR: \"imageError\",\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n};\n\nexport const DEFAULT_WRAPPER_CLASS = \"view360-wrapper\";\nexport const DEFAULT_IMAGE_CLASS = \"view360-image\";\n","import Component, { ComponentEvent } from \"@egjs/component\";\n\nimport { TRANSFORM, SUPPORT_WILLCHANGE } from \"../utils/browserFeature\";\nimport { VERSION } from \"../version\";\n\nimport { SpinViewerOptions } from \"./SpinViewer\";\nimport { DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS } from \"./consts\";\n\nexport interface SpriteImageEvent {\n /**\n * Events that occur when component loading is complete\n * @ko 컴포넌트 로딩이 완료되면 발생하는 이벤트\n * @name eg.view360.SpriteImage#load\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {HTMLElement} param.target The target element for which to display the image 이미지를 보여줄 대상 엘리먼트\n * @param {HTMLElement} param.bgElement Generated background image element 생성된 background 이미지 엘리먼트\n *\n * @example\n *\n * sprites.on({\n * \"load\" : function(evt) {\n * console.log(\"load event fired - e.target\", e.target, \"e.bgElement\", e.bgElement);\n * }\n * });\n */\n load: {\n target: HTMLElement;\n bgElement: HTMLDivElement;\n };\n /**\n * An event that occurs when the image index is changed by the user's left / right panning\n * @ko 사용자의 좌우 Panning 에 의해 이미지 인덱스가 변경되었을때 발생하는 이벤트\n * @name eg.view360.SpriteImage#imageError\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {String} param.imageUrl User-specified image URL 사용자가 지정한 이미지 URL\n *\n * @example\n *\n * sprites.on({\n * \"imageError\" : function(evt) {\n * // Error handling\n * console.log(e.imageUrl);\n * }\n * });\n */\n imageError: {\n imageUrl?: string;\n };\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpriteImage\n */\nclass SpriteImage extends Component {\n private static _createBgDiv(wrapperInContainer: HTMLDivElement | null, img: HTMLImageElement, rowCount: number, colCount: number, autoHeight: boolean) {\n const el = wrapperInContainer || document.createElement(\"div\");\n\n el.style.position = \"relative\";\n el.style.overflow = \"hidden\";\n\n img.style.position = \"absolute\";\n img.style.width = `${colCount * 100}%`;\n img.style.height = `${rowCount * 100}%`;\n\n /** Prevent image from being dragged on IE10, IE11, Safari especially */\n img.ondragstart = () => (false); // img.style.pointerEvents = \"none\";\n // Use hardware accelerator if available\n if (SUPPORT_WILLCHANGE) {\n (img.style.willChange = \"transform\");\n }\n\n el.appendChild(img);\n\n const unitWidth = img.naturalWidth / colCount;\n const unitHeight = img.naturalHeight / rowCount;\n\n if (autoHeight) {\n const r = unitHeight / unitWidth;\n\n el.style.paddingBottom = `${r * 100}%`;\n } else {\n el.style.height = \"100%\";\n }\n\n return el;\n }\n\n private static _getSizeString(size) {\n if (typeof size === \"number\") {\n return `${size}px`;\n }\n\n return size;\n }\n\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _rowCount: number;\n private _colCount: number;\n private _totalCount: number;\n private _width: number | string;\n private _height: number | string;\n private _autoHeight: boolean;\n private _colRow: number[];\n private _image: HTMLImageElement;\n private _bg: HTMLDivElement;\n private _autoPlayReservedInfo: { interval: number; playCount: number } | null;\n private _autoPlayTimer: number;\n\n /**\n * @class eg.view360.SpriteImage\n * @classdesc A module that displays a single or continuous image of any one of the \"sprite images\". SpinViewer internally uses SpriteImage to show each frame of the sprite image.\n * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다.\n * @extends eg.Component\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the \"Sprite image\". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n *\n * // Initialize SpriteImage\n *\n * var el = document.getElementById(\"image-div\");\n * var sprites = new eg.view360.SpriteImage(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24\n * });\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n const opt = options || {};\n\n this._el = element;\n this._rowCount = opt.rowCount || 1;\n this._colCount = opt.colCount || 1;\n this._totalCount = this._rowCount * this._colCount; // total frames\n this._width = opt.width || \"auto\";\n this._height = opt.height || \"auto\";\n this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten.\n this._colRow = [0, 0];\n\n if (opt.colRow) {\n this._colRow = opt.colRow;\n } else if (opt.frameIndex) {\n this.setFrameIndex(opt.frameIndex);\n }\n\n this._el.style.width = SpriteImage._getSizeString(this._width);\n this._el.style.height = SpriteImage._getSizeString(this._height);\n\n const wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS;\n const imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS;\n\n if (!opt.imageUrl) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n }, 0);\n return;\n }\n\n const imageInContainer = element.querySelector(`.${imageClass}`);\n const wrapperInContainer = element.querySelector(`.${wrapperClass}`);\n\n if (wrapperInContainer && imageInContainer) {\n // Set it to invisible to prevent wrapper being resized\n imageInContainer.style.display = \"none\";\n }\n\n this._image = imageInContainer || new Image();\n /**\n * Event\n */\n\n const image = this._image;\n\n image.onload = () => {\n if (wrapperInContainer && imageInContainer) {\n imageInContainer.style.display = \"\";\n }\n\n this._bg = SpriteImage._createBgDiv(\n wrapperInContainer,\n image,\n this._rowCount,\n this._colCount,\n this._autoHeight\n );\n this._el.appendChild(this._bg);\n this.setColRow(this._colRow[0], this._colRow[1]);\n\n this.trigger(new ComponentEvent(\"load\", {\n target: this._el,\n bgElement: this._bg\n }));\n\n if (this._autoPlayReservedInfo) {\n this.play(this._autoPlayReservedInfo);\n this._autoPlayReservedInfo = null;\n }\n };\n\n image.onerror = () => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n };\n\n image.src = opt.imageUrl;\n }\n\n /**\n * Specifies the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정\n * @method eg.view360.SpriteImage#setFrameIndex\n * @param {Number} frameIndex frame index of a frame프레임의 인덱스\n *\n * @example\n *\n * sprites.setFrameIndex(0, 1);// col = 0, row = 1\n */\n public setFrameIndex(index: number) {\n const colRow = this.toColRow(index);\n\n this.setColRow(colRow[0], colRow[1]);\n }\n\n /**\n * Returns the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환\n * @method eg.view360.SpriteImage#getFrameIndex\n * @return {Number} frame index frame 인덱스\n *\n * @example\n *\n * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1\n *\n */\n public getFrameIndex() {\n return this._colRow[1] * this._colCount + this._colRow[0];\n }\n\n /**\n * Specifies the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정\n * @method eg.view360.SpriteImage#setColRow\n * @param {Number} col Column number of a frame프레임의 행값\n * @param {Number} row Row number of a frame프레임의 열값\n *\n * @example\n *\n * sprites.setlColRow(1, 2); // col = 1, row = 2\n */\n public setColRow(col: number, row: number) {\n if (row > this._rowCount - 1 || col > this._colCount - 1) {\n return;\n }\n\n if (this._image && TRANSFORM) {\n // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser?\n this._image.style[TRANSFORM] = `translate(${-(col / this._colCount * 100)}%, ${-(row / this._rowCount * 100)}%)`;\n }\n\n this._colRow = [col, row];\n }\n\n /**\n * Returns the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환\n * @method eg.view360.SpriteImage#gelColRow\n * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열\n *\n * @example\n *\n * var colRow = sprites.getlColRow();\n * // colRow = [1, 2] - index of col is 1, index of row is 2\n *\n */\n public getColRow() {\n return this._colRow;\n }\n\n /**\n * Stop playing\n * @ko play 되고 있던 프레임 재생을 중지합니다.\n * @method eg.view360.SpriteImage#stop\n *\n * @example\n *\n * viewer.stop();\n *\n */\n public stop() {\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n }\n\n /**\n * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'.\n * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다.\n * @method eg.view360.SpriteImage#play\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위\n * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복\n *\n * @example\n *\n * viewer.play({angle: 16, playCount: 1});\n *\n */\n public play({ interval, playCount } = { interval: 1000 / this._totalCount, playCount: 0 }) {\n if (!this._bg) {\n this._autoPlayReservedInfo = {interval, playCount};\n return;\n }\n\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n\n let frameIndex = this.getFrameIndex();\n let count = 0;\n let frameCount = 0; // for checking 1 cycle\n\n this._autoPlayTimer = window.setInterval(() => {\n frameIndex %= this._totalCount;\n const colRow = this.toColRow(frameIndex);\n\n this.setColRow(colRow[0], colRow[1]);\n frameIndex++;\n\n // Done 1 Cycle?\n if (++frameCount === this._totalCount) {\n frameCount = 0;\n count++;\n }\n\n if (playCount > 0 && count === playCount) {\n clearInterval(this._autoPlayTimer);\n }\n }, interval);\n }\n\n public toColRow(frameIndex: number) {\n const colCount = this._colCount;\n const rowCount = this._rowCount;\n\n if (frameIndex < 0) {\n return [0, 0];\n } else if (frameIndex >= this._totalCount) {\n return [colCount - 1, rowCount - 1];\n }\n\n const col = frameIndex % colCount;\n const row = Math.floor(frameIndex / colCount);\n\n // console.log(frameIndex, col, row);\n return [col, row];\n }\n}\n\nexport default SpriteImage;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport { VERSION } from \"../version\";\nimport { AnimationEndEvent, ChangeEvent, ImageErrorEvent, LoadEvent } from \"../types/event\";\n\nimport SpriteImage from \"./SpriteImage\";\n\nconst DEFAULT_PAN_SCALE = 0.21;\n\nexport interface SpinViewerEvent {\n load: LoadEvent;\n imageError: ImageErrorEvent;\n change: ChangeEvent;\n animationEnd: AnimationEndEvent;\n}\n\nexport interface SpinViewerOptions {\n imageUrl: string;\n rowCount: number;\n colCount: number;\n width: number | string;\n height: number | string;\n autoHeight: boolean;\n colRow: number[];\n scale: number;\n frameIndex: number;\n wrapperClass: string;\n imageClass: string;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpinViewer\n */\nclass SpinViewer extends Component {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @static\n * @example\n * eg.view360.SpinViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.SpinViewer\n */\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _sprites: SpriteImage;\n private _axes: Axes;\n private _panInput: PanInput;\n\n private _scale: number;\n private _panScale: number;\n private _frameCount: number;\n\n /**\n * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object.\n * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다.\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값\n * @param {String} [options.wrapperClass=\"view360-wrapper\"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @param {String} [options.imageClass=\"view360-image\"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n * ```\n * // Initialize SpinViewer\n * var el = document.getElementById(\"product-360\");\n * var viewer = new eg.view360.SpinViewer(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24 //required\n * });\n * ```\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n\n this._el = element;\n\n const opt = {...options};\n const colCount = opt.colCount || 1;\n const rowCount = opt.rowCount || 1;\n\n this._scale = (opt.scale || 1);\n this._panScale = this._scale * DEFAULT_PAN_SCALE;\n\n this._frameCount = colCount * rowCount;\n\n // Init SpriteImage\n this._sprites = new SpriteImage(element, opt).on({\n \"load\": evt => {\n this.trigger(new ComponentEvent(\"load\", evt));\n },\n \"imageError\": evt => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: evt.imageUrl\n }));\n }\n });\n\n // Init Axes\n this._panInput = new PanInput(this._el, {\n scale: [this._panScale, this._panScale]\n });\n this._axes = new Axes({\n angle: {\n range: [0, 359],\n circular: true\n }\n }).on({\n \"change\": evt => {\n const curr = Math.floor(evt.pos.angle / (360 / this._frameCount));\n const frameIndex = this._frameCount - curr - 1;\n\n this._sprites.setFrameIndex(frameIndex);\n\n this.trigger(new ComponentEvent(\"change\", {\n frameIndex,\n colRow: this._sprites.getColRow(),\n angle: evt.pos.angle\n }));\n },\n \"animationEnd\": evt => {\n this.trigger(new ComponentEvent(\"animationEnd\", {\n isTrusted: evt.isTrusted\n }));\n }\n });\n\n this._axes.connect(\"angle\", this._panInput);\n }\n\n /**\n * Set spin scale\n * @ko scale 을 조정할 수 있는 함수\n * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.setScale(2);// It moves twice as much.\n */\n public setScale(scale: number) {\n if (isNaN(scale) || scale < 0) {\n return this;\n }\n\n this._scale = scale;\n this._panScale = scale * DEFAULT_PAN_SCALE;\n this._panInput.options.scale = [this._panScale, this._panScale];\n\n return this;\n }\n\n /**\n * Get spin scale\n * @ko scale 값을 반환한다.\n *\n * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @example\n * viewer.getScale();// It returns number\n */\n public getScale() {\n return this._scale;\n }\n\n /**\n * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle.\n * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle상대적 회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinBy(720, {duration: 500});\n */\n public spinBy(angle = 0, param = {duration: 0}) {\n this._axes.setBy({angle}, param.duration);\n return this;\n }\n\n /**\n * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle).\n * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinTo(30, {duration:100});\n */\n public spinTo(angle = 0, param = {duration: 0}) {\n this._axes.setTo({angle}, param.duration);\n return this;\n }\n\n /**\n * Returns current angles\n * @ko 현재 각도를 반환한다.\n *\n * @return {Number} Current angle 현재 각도\n */\n public getAngle() {\n return this._axes.get().angle || 0;\n }\n}\n\nexport default SpinViewer;\n","import Component from \"@egjs/component\";\n\nconst withMethods = (component: any, prototype: any, vanillaInstance: string) => {\n [Component.prototype, component.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto).filter(name => !prototype[name] && !name.startsWith(\"_\") && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[vanillaInstance], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return descriptor.get?.call(this[vanillaInstance]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[vanillaInstance], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","import { PanoViewer } from \"../PanoViewer\";\n\nimport withMethods from \"./withMethods\";\n\nconst withPanoViewerMethods = (prototype: any, name: string) => {\n withMethods(PanoViewer, prototype, name);\n};\n\nexport default withPanoViewerMethods;\n","import { SpinViewer } from \"../SpinViewer\";\n\nimport withMethods from \"./withMethods\";\n\nconst withSpinViewerMethods = (prototype: any, name: string) => {\n withMethods(SpinViewer, prototype, name);\n};\n\nexport default withSpinViewerMethods;\n","import PanoViewer, { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\n\nexport default (panoViewer: PanoViewer, newProps: Partial, prevProps: Partial) => {\n if (isPropChanged(newProps.image, prevProps.image)) {\n panoViewer.setImage(newProps.image, {\n projectionType: newProps.projectionType,\n cubemapConfig: newProps.cubemapConfig,\n stereoFormat: newProps.stereoFormat,\n isVideo: false\n });\n } else if (isPropChanged(newProps.video, prevProps.video)) {\n panoViewer.setVideo(newProps.video, {\n projectionType: newProps.projectionType,\n cubemapConfig: newProps.cubemapConfig,\n stereoFormat: newProps.stereoFormat\n });\n }\n\n const singleUpdateOptions: Array = [\n \"fovRange\",\n \"gyroMode\",\n \"pitchRange\",\n \"showPolePoint\",\n \"touchDirection\",\n \"useKeyboard\",\n \"useZoom\",\n \"yawRange\"\n ];\n\n singleUpdateOptions.forEach(optionName => {\n updateOption(panoViewer, optionName, newProps, prevProps);\n });\n};\n\nconst isPropChanged = (val: any, prevVal: any): val is true => val != null && val !== prevVal;\nconst updateOption = (panoViewer: PanoViewer, optionName: string, newProps: Partial, prevProps: Partial) => {\n if (isPropChanged(newProps[optionName], prevProps[optionName])) {\n panoViewer[`set${optionName[0].toUpperCase()}${optionName.slice(1)}`](newProps[optionName]);\n }\n};\n","export const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n\nexport const generateCanvasKey = (oldKey: number) => {\n let newKey: number;\n\n do {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n newKey = array[0];\n } while (newKey === oldKey);\n\n return newKey;\n};\n","/*\n * Copyright (c) 2017 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport * as PanoViewer from \"./PanoViewer\";\nimport * as SpinViewer from \"./SpinViewer\";\nimport * as CFC from \"./cfc\";\nimport { merge } from \"./utils/utils\";\n\nconst View360: any = {};\n\nmerge(View360, PanoViewer);\nmerge(View360, SpinViewer);\nmerge(View360, CFC);\n\nexport default View360;\n"],"names":["VERSION","win","window","Math","self","Function","doc","document","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","IS_IOS","IS_SAFARI_ON_DESKTOP","Float32Array","Array","getComputedStyle","userAgent","SUPPORT_TOUCH","SUPPORT_DEVICEMOTION","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","target","i","len","length","SUPPORT_WILLCHANGE","CSS","supports","WEBXR_SUPPORTED","checkXRSupport","xr","isSessionSupported","then","res","catch","supportsSession","quatToVec3","quaternion","baseV","vec3","fromValues","transformQuat","toDegree","a","PI","util","isPowerOfTwo","n","extractPitchFromQuat","atan2","sqrt","pow","hypot","x","y","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","getRotationDelta","prevQ","curQ","rotateKind","prevQuaternion","quat","clone","curQuaternion","normalize","prevPoint","curPoint","rotateDistance","dot","cross","create","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","distance","abs","projectedPrevPoint","subtract","scale","trigonometricRatio","theta","acos","crossVec","thetaDirection","deltaRadian","angleBetweenVec2","v1","v2","det","vec2","yawOffsetBetween","viewDir","targetDir","viewDirXZ","targetDirXZ","sign","Number","toAxis","source","offset","reduce","acc","v","version","branch","build","match","exec","parseInt","CHROME_VERSION","IS_CHROME_WITHOUT_DEVICE_MOTION","IS_ANDROID","test","CONTROL_MODE_VR","CONTROL_MODE_YAWPITCH","TOUCH_DIRECTION_NONE","TOUCH_DIRECTION_YAW","TOUCH_DIRECTION_PITCH","TOUCH_DIRECTION_ALL","MC_DECELERATION","MC_MAXIMUM_DURATION","MC_BIND_SCALE","MAX_FIELD_OF_VIEW","PAN_SCALE","YAW_RANGE_HALF","PITCH_RANGE_HALF","CIRCULAR_PITCH_RANGE_HALF","GYRO_MODE","NONE","YAWPITCH","VR","MathUtil","degToRad","radToDeg","Vector2","prototype","constructor","set","copy","subVectors","b","Vector3","z","scalar","invScalar","multiplyScalar","applyQuaternion","q","qx","qy","qz","qw","w","ix","iy","iz","iw","crossVectors","ax","ay","az","bx","by","bz","Quaternion","undefined","setFromEulerXYZ","c1","cos","c2","c3","s1","sin","s2","s3","setFromEulerYXZ","setFromAxisAngle","axis","angle","halfAngle","s","multiply","multiplyQuaternions","qax","qay","qaz","qaw","qbx","qby","qbz","qbw","inverse","l","slerp","qb","t","cosHalfTheta","halfTheta","sinHalfTheta","ratioA","ratioB","setFromUnitVectors","r","EPS","vFrom","vTo","Util","MIN_TIMESTEP","MAX_TIMESTEP","base64","mimeType","clamp","value","min","max","lerp","isIOS","platform","isWebViewAndroid","indexOf","isSafari","isFirefoxAndroid","isR7","isLandscapeMode","rtn","orientation","isTimestampDeltaValid","timestampDeltaS","isNaN","getScreenWidth","screen","width","height","getScreenHeight","requestFullscreen","element","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","exitFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","getFullscreenElement","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","linkProgram","gl","vertexSource","fragmentSource","attribLocationMap","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","program","createProgram","attachShader","attribName","bindAttribLocation","deleteShader","getProgramUniforms","uniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","uniformName","uniformInfo","getActiveUniform","replace","getUniformLocation","orthoMatrix","out","left","right","bottom","top","near","far","lr","bt","nf","copyArray","dest","isMobile","check","substr","vendor","opera","extend","src","key","hasOwnProperty","safariCssSizeWorkaround","canvas","width_1","height_1","setTimeout","isDebug","getQueryParameter","regex","RegExp","results","location","search","decodeURIComponent","frameDataFromPose","piOver180","rad45","mat4_perspectiveFromFieldOfView","fov","upTan","tan","upDegrees","downTan","downDegrees","leftTan","leftDegrees","rightTan","rightDegrees","xScale","yScale","mat4_fromRotationTranslation","x2","y2","z2","xx","xy","xz","yy","yz","zz","wx","wy","wz","mat4_translate","a00","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","mat4_invert","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b06","b07","b08","b09","b10","b11","defaultOrientation","defaultPosition","updateEyeMatrices","projection","view","pose","parameters","vrDisplay","fieldOfView","depthNear","depthFar","position","frameData","timestamp","leftProjectionMatrix","leftViewMatrix","getEyeParameters","rightProjectionMatrix","rightViewMatrix","isInsideCrossDomainIFrame","isFramed","refDomain","getDomainFromUrl","referrer","thisDomain","href","url","domain","split","predictionTimeS","previousQ","previousTimestampS","deltaQ","outQ","currentQ","gyro","timestampS","angularSpeed","console","log","toFixed","deltaT","predictAngle","STILLNESS_THRESHOLD","__extends","_super","_this","_onDeviceMotion","bind","_onDeviceOrientation","_onChromeWithoutDeviceMotion","isWithoutDeviceMotion","isAndroid","stillGyroVec","rawGyroVec","adjustedGyroVec","_timer","lastDevicemotionTimestamp","_isEnabled","enable","addEventListener","removeEventListener","e","alpha","beta","gamma","trigger","ComponentEvent","inputEvent","deviceorientation","clearTimeout","Date","getTime","isGyroSensorAvailable","rotationRate","isGravitySensorAvailable","accelerationIncludingGravity","interval","devicemotionEvent","__assign","timeStamp","type","acceleration","adjustedRotationRate","Component","sample","sensorSample","kFilter","vector","currentGyroMeasurement","previousGyroMeasurement","run_","currentAccelMeasurement","SensorSample","filterQ","previousFilterQ","accelQ","isOrientationInitialized","estimatedGravity","measuredGravity","gyroIntegralQ","accelToQuaternion_","gyroDeltaQ","gyroToQuaternionDelta_","invFilterQ","getQuaternionAngle","targetQ","accel","normAccel","dt","ComplementaryFilter","isFilterQuaternionInitialized","getOrientation","K_FILTER","PREDICTION_TIME_S","deviceMotion","DeviceMotion","accelerometer","gyroscope","_onDeviceMotionChange","_onScreenOrientationChange","filter","posePredictor","PosePredictor","filterToWorldQ","isChromeUsingDegrees","inverseWorldToScreenQ","worldToScreenQ","originalPoseAdjustQ","_setScreenTransform","resetQ","on","isEnabled","disable","_deviceOrientationQ","deviceOrientationFixQ","_alpha","outQuat","_convertFusionToPredicted","_prevOrientation","equals","predictedQ","getPrediction","_a","accGravity","rotRate","_triggerChange","addAccelMeasurement","addGyroMeasurement","getDeltaYaw","prvQ","yawDeltaByYaw","yawDeltaByRoll","getDeltaPitch","pitchDelta","el","options","_prevQuaternion","_quaternion","fusionPoseSensor","threshold","_onPoseChange","axes","observer","FusionPoseSensor","_attachEvent","_dettachEvent","destroy","disconnect","event","change","off","screenRotationAngleInst","refCount","_onOrientationChange","_spinR","_screenOrientationAngle","glMatrix","toRadian","betaR","gammaR","_useRotation","_screenRotationAngle","setUseRotation","useRotation","_userDirection","Axes","DIRECTION_ALL","unref","ScreenRotationAngle","_direction","DIRECTION_HORIZONTAL","connect","properties","useDirection","_getOffset","newOffset","getRadian","cosTheta","sinTheta","DIRECTION_VERTICAL","PanInput","Y_AXIS_VECTOR","_fusionPoseSensor","isTrusted","yaw","yawQ","setAxisAngle","conj","conjugate","DEFAULT_YAW_RANGE","DEFAULT_PITCH_RANGE","CIRCULAR_PITCH_RANGE","opt","pitch","showPolePoint","useZoom","useKeyboard","gyroMode","touchDirection","yawRange","pitchRange","fovRange","aspectRatio","_element","_initialFov","_enabled","_isAnimating","_deviceQuaternion","_initAxes","option","param","_axes","get","areaHeight","_axesPanInput","deceleration","newValue","_getOptions","newOptions","changedKeyList","push","Object","keys","_setOptions","_getValidatedOptions","_applyOptions","updatePanScale","persistOrientation","_resetOrientation","duration","pos","p","f","maximumDuration","Infinity","setBy","yawPitch","getCombinedQuaternion","_axesWheelInput","_axesTiltMotionInput","_axesPinchInput","_axesMoveKeyInput","yRange","_updateYawRange","pRange","_updatePitchRange","RotationPanInput","WheelInput","PinchInput","MoveKeyInput","range","circular","_isCircular","bounce","hold","evt","delta","_updateControlScale","release","animationEnd","_getValidYawRange","_getValidPitchRange","arguments","isVR","isYawPitch","some","setTo","prevFov","nextFov","_initDeviceQuaternion","TiltMotionInput","_togglePinchInputByOption","_enableTouch","_inputs","direction","yawEnabled","pitchEnabled","DeviceQuaternion","newYawRange","newFov","newAspectRatio","ratio","_adjustAspectRatio","horizontalFov","isValid","newPitchRange","changeEvt","verticalAngle","halfFov","isPanorama","concat","horizontalAngle","halfHorizontalFov","mathUtil","targetElement","input","inputRange","outputRange","rangeIdx","inputA","inputB","outputA","outputB","_lerp","fraction","YawPitchControl","ERROR_TYPE","INVALID_DEVICE","NO_WEBGL","FAIL_IMAGE_LOAD","FAIL_BIND_TEXTURE","INVALID_RESOURCE","RENDERING_CONTEXT_LOST","PANOVIEWER_EVENTS","READY","VIEW_CHANGE","ANIMATION_END","ERROR","PROJECTION_TYPE","EQUIRECTANGULAR","CUBEMAP","CUBESTRIP","PANORAMA","STEREOSCOPIC_EQUI","STEREO_FORMAT","TOP_BOTTOM","LEFT_RIGHT","PANOVIEWER_OPTIONS","image","video","projectionType","cubemapConfig","stereoFormat","canvasClass","DEFAULT_CANVAS_CLASS","merge","_i","srcs","forEach","isArray","toImageElement","images","parsedImages","map","img","imgEl","Image","crossOrigin","toVideoElement","videoCandidate","HTMLVideoElement","video_1","createElement","setAttribute","appendSourceElement","sourceCount","querySelectorAll","readyState","load","videoUrl","videoSrc","videoType","sourceElement","appendChild","WEBGL_ERROR_CODE","webglAvailability","WebGLUtils","shader","success","getShaderParameter","COMPILE_STATUS","error","getShaderInfoLog","LINK_STATUS","deleteProgram","data","itemSize","attr","buffer","createBuffer","bindBuffer","bufferData","STATIC_DRAW","numItems","enableVertexAttribArray","vertexAttribPointer","FLOAT","userContextAttributes","webglIdentifiers","context","contextAttributes","preserveDrawingBuffer","antialias","onWebglcontextcreationerror","statusMessage","webglIdentifiers_1","__values","identifier","getContext","textureTarget","texture","createTexture","bindTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","webglContext","getWebglContext","loseContextExtension","getExtension","loseContext","agentInfo","isStableWebgl","parseFloat","code","pixels","texImage2D","RGBA","UNSIGNED_BYTE","getParameter","MAX_TEXTURE_SIZE","isIE11","majorVersion","EVENTS","_forceDimension","_pixelCanvas","_pixelContext","shaderProgram","indexBuffer","mvMatrix","pMatrix","uniformMatrix4fv","pMatrixUniform","mvMatrixUniform","drawElements","TRIANGLES","UNSIGNED_SHORT","pixelSource","naturalWidth","videoWidth","naturalHeight","videoHeight","forceDimension","isIE11Video","getDimension","contentDimension","textureDimension","drawImage","imageConfig","tileConfig","config","flipHorizontal","rotation","message","Renderer","CubeRenderer","order","_VERTEX_POSITION_DATA","_INDEX_DATA","indexData","vertexPositionData","getVertexPositionData","vertexOrder","extractOrder","base","_extractTileConfig","elemSize","vertexPerTile","trim","texCoords","face","floor","ordermap","shift","unshift","pop","elemPerTile","tileVertex","slice","tileTemp","j","splice","coord","_shrinkCoord","faceCoords","val","coords","baseOrder","orderMap","surfaceIdx","tileIdx","TEXTURE_CUBE_MAP_POSITIVE_X","maxCubeMapTextureSize","getMaxCubeMapTextureSize","tile","extractTileFromImage","_triggerError","TEXTURE_CUBE_MAP","updateTexture","inputTextureSize","outputTextureSize","getSourceTileSize","tilePerRow","MAX_CUBE_MAP_TEXTURE_SIZE","imageWidth","coordData","SHRINK_MULTIPLIER","axisMultipliers","axisIndex","axisDir","notSameDir","_vertices","indices","cols","rows","textureSize","c","tileConfigs","_transformCoord","index","TEXTURE_2D","_getPixelSource","size","maxSize","getMaxTextureSize","_initPixelSource","activeTexture","TEXTURE0","pixelStorei","UNPACK_FLIP_Y_WEBGL","newCoord","_flipHorizontalCoord","_rotateCoord","SHRINK_Y","SHRINK_X","rotationAngle","SIZE","shiftCount","moved","rotatedCoord","latitudeBands","longitudeBands","radius","ANGLE_CORRECTION_FOR_CENTER_ALIGN","textureCoordData","latIdx","lngIdx","phi","sinPhi","cosPhi","u","format","_stereoFormat","ctx","leftEyeScaleOffset","rightEyeScaleOffset","uTexScaleOffset","uniform4fv","render","SphereRenderer","_TEXTURE_COORD_DATA","MIN_ASPECT_RATIO_FOR_FULL_PANORAMA","CylinderRenderer","resizeDimension","_b","imageAspectRatio","cylinderMaxRadian","halfCylinderY","rotated","CYLIDER_Y","startAngleForCenterAlign","yIdx","yLength","VR_DISPLAY_PRESENT_CHANGE","DEFAULT_LEFT_BOUNDS","DEFAULT_RIGHT_BOUNDS","EYES","LEFT","RIGHT","_vrDisplay","removeEndCallback","isPresenting","exitPresent","_clear","_frameData","VRFrameData","Boolean","bindFramebuffer","FRAMEBUFFER","submitFrame","display","halfWidth","drawingBufferWidth","drawingBufferHeight","getFrameData","leftMVMatrix","rightMVMatrix","mat4","rotateY","_yawOffset","viewport","callback","getVRDisplays","displays","Promise","reject","Error","capabilities","canPresent","requestPresent","leftEye","rightEye","renderWidth","renderHeight","_setDisplay","layers","getLayers","layer","_leftBounds","leftBounds","_rightBounds","rightBounds","addEndCallback","XR_REFERENCE_SPACE","xrSession","_xrSession","end","_options","frame","getViewerPose","_xrRefSpace","session","baseLayer","renderState","framebuffer","glLayer","views","getViewport","transform","matrix","rotateX","projectionMatrix","_presenting","requiredFeatures","attributes","getContextAttributes","xrCompatible","makeXRCompatible","requestSession","xrLayer","XRWebGLLayer","updateRenderState","requestReferenceSpace","refSpace","_setSession","_xrLayer","args","_callback","_rafId","_context","requestAnimationFrame","_onLoop","before","performance","now","diff","_rafTimer","_onLoopNextTick","cancelAnimationFrame","ImageType","DEVICE_PIXEL_RATIO","BIND_TEXTURE","IMAGE_LOADED","RENDERING_CONTEXT_RESTORE","RENDERER_ERROR","isVideo","container","sphericalConfig","renderingContextAttributes","vr","_vr","animator","_animator","exitVR","_restoreStyle","updateViewportDimensions","_updateViewport","_bindBuffers","_shouldForceDraw","stop","setContext","setCallback","_render","start","time","eyeParams","getEyeParams","beforeRender","eyeIndex","eyeParam","uniform1f","uEye","_draw","afterRender","canRender","minusZDir","mat3","fromMat4","mvInv","invert","pInv","transformMat3","yawOffset","setYawOffset","_renderStereo","_lastQuaternion","_lastYaw","_lastPitch","_lastFieldOfView","perspective","textureCoordBuffer","vertexBuffer","_initCanvas","_setDefaultCanvasStyle","_wrapper","_wrapperOrigStyle","_renderingContextAttributes","_image","_imageConfig","_imageIsReady","_keepUpdate","_onContentLoad","_onContentError","WebGLAnimator","setImage","imageType","yawPitchControl","_yawPitchControl","_isVideo","_setImageType","_contentLoader","ImReady","rej","contentLoader","isReady","_bindTexture","once","errorCount","parentElement","_hasExternalCanvas","detach","hasRenderingContext","removeChild","forceContextLoss","_onWebglcontextlost","_onWebglcontextrestored","isContextLost","viewPortChanged","h","doUpdate","isImageLoaded","exactEquals","updateFieldOfView","fromQuat","identity","_renderer","resolve","_requestPresent","_imageType","_isCubeMap","CubeStripRenderer","_initWebGL","canvasInContainer","querySelector","_createCanvas","className","margin","maxHeight","maxWidth","outline","content","_triggerContentLoad","renderer","vsSource","getVertexShaderSource","fsSource","getFragmentShaderSource","getErrorNameFromWebGLErrorCode","getError","useProgram","vertexPositionAttribute","getAttribLocation","samplerUniform","textureCoordAttribute","clear","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","STENCIL_BUFFER_BIT","uniform1i","preventDefault","_initRenderingContext","_initShaderProgram","clearColor","deleteTexture","CULL_FACE","WebGLRenderingContext","getIndexData","getTextureCoordData","initBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","Uint16Array","isEAC","updateShaderData","_initBuffers","getFov","shouldRenderWithQuaternion","getQuaternion","renderWithQuaternion","getYawPitch","renderWithYawPitch","_updateTexture","XRManager","VRManager","_onFirstVRFrame","_setWrapperFullscreen","wrapper","getAttribute","wrapperStyle","zIndex","removeAttribute","PanoImageRenderer","isWebGLAvailable","isStableWebGL","_container","_projectionType","_cubemapConfig","_width","_height","_yaw","_pitch","_fov","_gyroMode","_aspectRatio","_canvasClass","PanoViewer","_isValidTouchDirection","yawPitchConfig","_isReady","_initYawPitchControl","_initRenderer","onDeviceMotionChange","checkGyro","timeout","race","fb","TOUCH_DIRECTION","YAW","PITCH","ALL","_photoSphereRenderer","getContent","warn","_deactivate","keepUpdate","requestPermission","permissionState","enableSensor","enterVR","containerSize","lookAt","verticalAngleOfImage","initialYaw","initialPitch","setYawPitchControl","_bindRendererHandler","_activate","ProjectionType","yawSize","maxFov","atan","minFov","attachTo","_updateYawPitchIfNeeded","startRender","getVideo","pause","stopRender","SPINVIEWER_OPTIONS","imageUrl","rowCount","colCount","autoHeight","colRow","frameIndex","wrapperClass","imageClass","SPINVIEWER_EVENTS","LOAD","IMAGE_ERROR","CHANGE","DEFAULT_WRAPPER_CLASS","DEFAULT_IMAGE_CLASS","_el","_rowCount","_colCount","_totalCount","_autoHeight","_colRow","setFrameIndex","SpriteImage","_getSizeString","imageInContainer","wrapperInContainer","onload","_bg","_createBgDiv","setColRow","bgElement","_autoPlayReservedInfo","play","onerror","overflow","ondragstart","willChange","unitWidth","unitHeight","paddingBottom","toColRow","col","row","_autoPlayTimer","clearInterval","playCount","getFrameIndex","count","frameCount","setInterval","DEFAULT_PAN_SCALE","_scale","_panScale","_frameCount","_sprites","_panInput","curr","getColRow","SpinViewer","withMethods","component","vanillaInstance","proto","getOwnPropertyNames","startsWith","descriptor","getOwnPropertyDescriptor","defineProperty","call","getterDescriptor","withPanoViewerMethods","withSpinViewerMethods","panoViewer","newProps","prevProps","isPropChanged","setVideo","singleUpdateOptions","optionName","updateOption","prevVal","toUpperCase","getValidProps","propsObj","props","propName","generateCanvasKey","oldKey","newKey","array","Uint32Array","crypto","getRandomValues","View360","CFC"],"mappings":"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"} \ No newline at end of file diff --git a/dist/view360.min.js b/dist/view360.min.js new file mode 100644 index 000000000..af20aba75 --- /dev/null +++ b/dist/view360.min.js @@ -0,0 +1,10 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@egjs/component"),require("promise-polyfill"),require("@egjs/agent"),require("@egjs/axes"),require("gl-matrix"),require("@egjs/imready")):"function"==typeof define&&define.amd?define(["@egjs/component","promise-polyfill","@egjs/agent","@egjs/axes","gl-matrix","@egjs/imready"],e):((t="undefined"!=typeof globalThis?globalThis:t||self).eg=t.eg||{},t.eg.view360=e(t.eg.Component,t.Promise,t.eg.agent,t.eg.Axes,t.glMatrix,t.eg.ImReady))}(this,function(c,s,a,u,_,r){"use strict";var n="3.6.3",o=function(t,e){return(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)};function l(t,e){function i(){this.constructor=t}o(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)}var h=function(){return(h=Object.assign||function(t){for(var e,i=1,n=arguments.length;ia[0]&&e[1]=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function p(){for(var t=[],e=0;eMath.abs(t.z)?L.set(-t.y,t.x,0):L.set(0,-t.z,t.y)):L.crossVectors(t,e),this.x=L.x,this.y=L.y,this.z=L.z,this.w=N,this.normalize(),this}};var k,X,Y,q,j,H,K,Z,J,$=null!==(t=null==v?void 0:v.userAgent)&&void 0!==t?t:"",tt=g.Util||{};function et(t,e,i,n,r){c=t,a=n?n.fieldOfView:null,o=r.depthNear,h=r.depthFar,l=Math.tan(a?a.upDegrees*H:K),u=Math.tan(a?a.downDegrees*H:K),f=Math.tan(a?a.leftDegrees*H:K),d=Math.tan(a?a.rightDegrees*H:K),s=2/(f+d),a=2/(l+u),c[0]=s,c[1]=0,c[2]=0,c[3]=0,c[4]=0,c[5]=a,c[6]=0,c[7]=0,c[8]=-(f-d)*s*.5,c[9]=(l-u)*a*.5,c[10]=h/(o-h),c[11]=-1,c[12]=0,c[13]=0,c[14]=h*o/(o-h),c[15]=0;var o,a,s,u,h,c,l,d,f,_,p,g,m,v,y,x,w,E,R,T,C,I,b,P,A,O,t=i.orientation||Z,r=i.position||J;f=e,d=r,l=(s=t)[0],u=s[1],a=s[2],o=s[3],c=l*(h=l+l),r=l*(i=u+u),s=l*(t=a+a),l=u*i,u*=t,a*=t,h*=o,i*=o,t*=o,f[0]=1-(l+a),f[1]=r+t,f[2]=s-i,f[3]=0,f[4]=r-t,f[5]=1-(c+a),f[6]=u+h,f[7]=0,f[8]=s+i,f[9]=u-h,f[10]=1-(c+l),f[11]=0,f[12]=d[0],f[13]=d[1],f[14]=d[2],f[15]=1,n&&(C=A=e,T=n.offset,P=T[0],b=T[1],I=T[2],C===A?(A[12]=C[0]*P+C[4]*b+C[8]*I+C[12],A[13]=C[1]*P+C[5]*b+C[9]*I+C[13],A[14]=C[2]*P+C[6]*b+C[10]*I+C[14],A[15]=C[3]*P+C[7]*b+C[11]*I+C[15]):(_=C[0],m=C[1],x=C[2],E=C[3],p=C[4],v=C[5],O=C[6],R=C[7],g=C[8],y=C[9],w=C[10],T=C[11],A[0]=_,A[1]=m,A[2]=x,A[3]=E,A[4]=p,A[5]=v,A[6]=O,A[7]=R,A[8]=g,A[9]=y,A[10]=w,A[11]=T,A[12]=_*P+p*b+g*I+C[12],A[13]=m*P+v*b+y*I+C[13],A[14]=x*P+O*b+w*I+C[14],A[15]=E*P+R*b+T*I+C[15])),a=(t=r=e)[0],s=t[1],i=t[2],u=t[3],h=t[4],c=t[5],l=t[6],d=t[7],f=t[8],n=t[9],_=t[10],p=t[11],g=t[12],m=t[13],v=t[14],y=t[15],(t=(x=a*c-s*h)*(O=_*y-p*v)-(w=a*l-i*h)*(A=n*y-p*m)+(E=a*d-u*h)*(P=n*v-_*m)+(R=s*l-i*c)*(b=f*y-p*g)-(T=s*d-u*c)*(I=f*v-_*g)+(C=i*d-u*l)*(e=f*m-n*g))&&(t=1/t,r[0]=(c*O-l*A+d*P)*t,r[1]=(i*A-s*O-u*P)*t,r[2]=(m*C-v*T+y*R)*t,r[3]=(_*T-n*C-p*R)*t,r[4]=(l*b-h*O-d*I)*t,r[5]=(a*O-i*b+u*I)*t,r[6]=(v*E-g*C-y*w)*t,r[7]=(f*C-_*E+p*w)*t,r[8]=(h*A-c*b+d*e)*t,r[9]=(s*b-a*A-u*e)*t,r[10]=(g*T-m*E+y*x)*t,r[11]=(n*E-f*T-p*x)*t,r[12]=(c*I-h*P-l*e)*t,r[13]=(a*P-s*I+i*e)*t,r[14]=(m*w-g*R-v*x)*t,r[15]=(f*R-n*w+_*x)*t)}tt.MIN_TIMESTEP=.001,tt.MAX_TIMESTEP=1,tt.base64=function(t,e){return"data:"+t+";base64,"+e},tt.clamp=function(t,e,i){return Math.min(Math.max(e,t),i)},tt.lerp=function(t,e,i){return t+(e-t)*i},tt.isIOS=(k=/iPad|iPhone|iPod/.test(null==v?void 0:v.platform),function(){return k}),tt.isWebViewAndroid=(X=-1!==$.indexOf("Version")&&-1!==$.indexOf("Android")&&-1!==$.indexOf("Chrome"),function(){return X}),tt.isSafari=(Y=/^((?!chrome|android).)*safari/i.test($),function(){return Y}),tt.isFirefoxAndroid=(q=-1!==$.indexOf("Firefox")&&-1!==$.indexOf("Android"),function(){return q}),tt.isR7=(j=-1!==$.indexOf("R7 Build"),function(){return j}),tt.isLandscapeMode=function(){var t=90===g.orientation||-90===g.orientation;return tt.isR7()?!t:t},tt.isTimestampDeltaValid=function(t){return!isNaN(t)&&(!(t<=tt.MIN_TIMESTEP)&&!(t>tt.MAX_TIMESTEP))},tt.getScreenWidth=function(){return Math.max(g.screen.width,g.screen.height)*g.devicePixelRatio},tt.getScreenHeight=function(){return Math.min(g.screen.width,g.screen.height)*g.devicePixelRatio},tt.requestFullscreen=function(t){if(tt.isWebViewAndroid())return!1;if(t.requestFullscreen)t.requestFullscreen();else if(t.webkitRequestFullscreen)t.webkitRequestFullscreen();else if(t.mozRequestFullScreen)t.mozRequestFullScreen();else{if(!t.msRequestFullscreen)return!1;t.msRequestFullscreen()}return!0},tt.exitFullscreen=function(){if(m.exitFullscreen)m.exitFullscreen();else if(m.webkitExitFullscreen)m.webkitExitFullscreen();else if(m.mozCancelFullScreen)m.mozCancelFullScreen();else{if(!m.msExitFullscreen)return!1;m.msExitFullscreen()}return!0},tt.getFullscreenElement=function(){return m.fullscreenElement||m.webkitFullscreenElement||m.mozFullScreenElement||m.msFullscreenElement},tt.linkProgram=function(t,e,i,n){var r=t.createShader(t.VERTEX_SHADER);t.shaderSource(r,e),t.compileShader(r);e=t.createShader(t.FRAGMENT_SHADER);t.shaderSource(e,i),t.compileShader(e);var o,a=t.createProgram();for(o in t.attachShader(a,r),t.attachShader(a,e),n)t.bindAttribLocation(a,n[o],o);return t.linkProgram(a),t.deleteShader(r),t.deleteShader(e),a},tt.getProgramUniforms=function(t,e){for(var i={},n=t.getProgramParameter(e,t.ACTIVE_UNIFORMS),r="",o=0;oe[1]&&(n=e[1]),i!==n&&(o.setTo({fov:n},0),this._updateControlScale(),this.updatePanScale())),t.some(function(t){return"gyroMode"===t})&&C&&(this._axesTiltMotionInput&&(this._axes.disconnect(this._axesTiltMotionInput),this._axesTiltMotionInput.destroy(),this._axesTiltMotionInput=null),this._deviceQuaternion&&(this._deviceQuaternion.destroy(),this._deviceQuaternion=null),a?this._initDeviceQuaternion():s&&(this._axesTiltMotionInput=new st(this._element),this._axes.connect(["yaw","pitch"],this._axesTiltMotionInput)),this._axesPanInput.setUseRotation(a)),t.some(function(t){return"useKeyboard"===t})&&(r.useKeyboard?o.connect(["yaw","pitch"],this._axesMoveKeyInput):o.disconnect(this._axesMoveKeyInput)),t.some(function(t){return"useZoom"===t})&&(a=r.useZoom,o.disconnect(this._axesWheelInput),a&&o.connect(["fov"],this._axesWheelInput)),this._togglePinchInputByOption(r.touchDirection,r.useZoom),t.some(function(t){return"touchDirection"===t})&&this._enabled&&this._enableTouch(u)},e._togglePinchInputByOption=function(t,e){this._axesPinchInput&&(this._axes.disconnect(this._axesPinchInput),e&&6===t&&-1===this._axes._inputs.indexOf(this._axesPinchInput)&&this._axes.connect(["fov"],this._axesPinchInput))},e._enableTouch=function(t){this._axesPanInput&&this._axes.disconnect(this._axesPanInput);var e=2&t?"yaw":null,t=4&t?"pitch":null;this._axes.connect([e,t],this._axesPanInput)},e._initDeviceQuaternion=function(){var e=this;this._deviceQuaternion=new ft,this._deviceQuaternion.on("change",function(t){e._triggerChange(t)})},e._getValidYawRange=function(t,e,i){i=this._adjustAspectRatio(i||this.options.aspectRatio||1),i=(e||this._axes.get().fov)*i;return t[1]-t[0]>=i?t:this.options.yawRange||_t},e._getValidPitchRange=function(t,e){e=e||this._axes.get().fov;return t[1]-t[0]>=e?t:this.options.pitchRange||pt},e._isCircular=function(t){return t[1]-t[0]<360?[!1,!1]:[!0,!0]},e._updateControlScale=function(t){var e=this.options,i=this._axes.get().fov,n=this._updatePitchRange(e.pitchRange,i,e.showPolePoint),r=this._updateYawRange(e.yawRange,i,e.aspectRatio),i=this._axes.get(),e=i.yaw,i=i.pitch;return _.vec2.copy(this._axes.axis.yaw.range,r),_.vec2.copy(this._axes.axis.pitch.range,n),this._axes.axis.yaw.circular=this._isCircular(r),this._axes.axis.pitch.circular=this._isCircular(n),er[1]&&(e=r[1]),in[1]&&(i=n[1]),t&&t.set({yaw:e,pitch:i}),this._axes.setTo({yaw:e,pitch:i},0),this},e._updatePitchRange=function(t,e,i){if(this.options.gyroMode===B.VR)return gt;var n=t[1]-t[0],e=e/2;return!i||n<180?[t[0]+e,t[1]-e]:t.concat()},e._updateYawRange=function(t,e,i){if(this.options.gyroMode===B.VR)return _t;if(360<=t[1]-t[0])return t.concat();e=D.toDegree(Math.atan2(i,1/Math.tan(_.glMatrix.toRadian(e/2))));return[t[0]+e,t[1]-e]},e._triggerChange=function(t){var e=this._axes.get(),i=this.options,t={targetElement:i.element,isTrusted:t.isTrusted,yaw:e.yaw,pitch:e.pitch,fov:e.fov,quaternion:null};i.gyroMode===B.VR&&this._deviceQuaternion&&(t.quaternion=this._deviceQuaternion.getCombinedQuaternion(e.yaw)),this.trigger(new c.ComponentEvent("change",t))},e._adjustAspectRatio=function(t){for(var e=[.52,.54,.563,.57,.584,.59,.609,.67,.702,.72,.76,.78,.82,.92,.97,1,1.07,1.14,1.19,1.25,1.32,1.38,1.4,1.43,1.53,1.62,1.76,1.77,1.86,1.96,2.26,2.3,2.6,3,5,6],i=[.51,.54,.606,.56,.628,.63,.647,.71,.736,.757,.78,.77,.8,.89,.975,1,1.07,1.1,1.15,1.18,1.22,1.27,1.3,1.33,1.39,1.45,1.54,1.55,1.58,1.62,1.72,1.82,1.92,2,2.24,2.3],n=-1,r=0;r= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"},i.getVertexPositionData=function(){return this._vertices||(this._vertices=[1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1]),this._vertices},i.getIndexData=function(){var i=this;return function(){for(var t=[],e=0;ethis._rowCount-1||t>this._colCount-1||(this._image&&P&&(this._image.style[P]="translate("+-(t/this._colCount)*100+"%, "+-(e/this._rowCount)*100+"%)"),this._colRow=[t,e])},t.getColRow=function(){return this._colRow},t.stop=function(){this._autoPlayTimer&&(clearInterval(this._autoPlayTimer),this._autoPlayTimer=-1)},t.play=function(t){var e,i,n,r=this,o=void 0===t?{interval:1e3/this._totalCount,playCount:0}:t,t=o.interval,a=o.playCount;this._bg?(this._autoPlayTimer&&(clearInterval(this._autoPlayTimer),this._autoPlayTimer=-1),e=this.getFrameIndex(),n=i=0,this._autoPlayTimer=window.setInterval(function(){e%=r._totalCount;var t=r.toColRow(e);r.setColRow(t[0],t[1]),e++,++n===r._totalCount&&(n=0,i++),0=this._totalCount?[e-1,i-1]:[t%e,Math.floor(t/e)]},h.VERSION=n,h}(c),ge=function(o){function t(t,e){void 0===e&&(e={});var i=o.call(this)||this;i._el=t;var n=h({},e),r=n.colCount||1,e=n.rowCount||1;return i._scale=n.scale||1,i._panScale=.21*i._scale,i._frameCount=r*e,i._sprites=new pe(t,n).on({load:function(t){i.trigger(new c.ComponentEvent("load",t))},imageError:function(t){i.trigger(new c.ComponentEvent("imageError",{imageUrl:t.imageUrl}))}}),i._panInput=new u.PanInput(i._el,{scale:[i._panScale,i._panScale]}),i._axes=new u({angle:{range:[0,359],circular:!0}}).on({change:function(t){var e=Math.floor(t.pos.angle/(360/i._frameCount)),e=i._frameCount-e-1;i._sprites.setFrameIndex(e),i.trigger(new c.ComponentEvent("change",{frameIndex:e,colRow:i._sprites.getColRow(),angle:t.pos.angle}))},animationEnd:function(t){i.trigger(new c.ComponentEvent("animationEnd",{isTrusted:t.isTrusted}))}}),i._axes.connect("angle",i._panInput),i}l(t,o);var e=t.prototype;return e.setScale=function(t){return isNaN(t)||t<0||(this._scale=t,this._panScale=.21*t,this._panInput.options.scale=[this._panScale,this._panScale]),this},e.getScale=function(){return this._scale},e.spinBy=function(t,e){return void 0===t&&(t=0),void 0===e&&(e={duration:0}),this._axes.setBy({angle:t},e.duration),this},e.spinTo=function(t,e){return void 0===t&&(t=0),void 0===e&&(e={duration:0}),this._axes.setTo({angle:t},e.duration),this},e.getAngle=function(){return this._axes.get().angle||0},t.VERSION=n,t}(c),t={__proto__:null,SpinViewer:ge,SpriteImage:pe,VERSION:n,SPINVIEWER_OPTIONS:{imageUrl:!0,rowCount:!0,colCount:!0,width:!0,height:!0,autoHeight:!0,colRow:!0,scale:!0,frameIndex:!0,wrapperClass:!0,imageClass:!0},SPINVIEWER_EVENTS:{LOAD:"load",IMAGE_ERROR:"imageError",CHANGE:"change",ANIMATION_END:"animationEnd"},DEFAULT_WRAPPER_CLASS:fe,DEFAULT_IMAGE_CLASS:_e},me=function(t,e){return null!=t&&t!==e},ve=function(t,e,i,n){me(i[e],n[e])&&t["set"+e[0].toUpperCase()+e.slice(1)](i[e])},e={__proto__:null,withMethods:ue,withPanoViewerMethods:function(t,e){ue(de,t,e)},withSpinViewerMethods:function(t,e){ue(ge,t,e)},updatePanoViewer:function(e,i,n){me(i.image,n.image)?e.setImage(i.image,{projectionType:i.projectionType,cubemapConfig:i.cubemapConfig,stereoFormat:i.stereoFormat,isVideo:!1}):me(i.video,n.video)&&e.setVideo(i.video,{projectionType:i.projectionType,cubemapConfig:i.cubemapConfig,stereoFormat:i.stereoFormat});["fovRange","gyroMode","pitchRange","showPolePoint","touchDirection","useKeyboard","useZoom","yawRange"].forEach(function(t){ve(e,t,i,n)})},getValidProps:function(i){return Object.keys(i).reduce(function(t,e){return null!=i[e]&&(t[e]=i[e]),t},{})},generateCanvasKey:function(t){var e;do{var i=new Uint32Array(1)}while(crypto.getRandomValues(i),(e=i[0])===t);return e}},b={};return Rt(b,R),Rt(b,t),Rt(b,e),b}); +//# sourceMappingURL=view360.min.js.map diff --git a/dist/view360.min.js.map b/dist/view360.min.js.map new file mode 100644 index 000000000..c16743ed9 --- /dev/null +++ b/dist/view360.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.min.js","sources":["../src/version.ts","../src/utils/browser.ts","../src/utils/browserFeature.ts","../src/utils/math-util.ts","../src/YawPitchControl/utils.ts","../src/YawPitchControl/consts.ts","../src/YawPitchControl/input/lib/webvr-polyfill/math-util.ts","../src/YawPitchControl/input/lib/webvr-polyfill/util.ts","../src/YawPitchControl/input/lib/webvr-polyfill/pose-predictor.ts","../src/YawPitchControl/input/DeviceMotion.ts","../src/YawPitchControl/input/lib/webvr-polyfill/sensor-sample.ts","../src/YawPitchControl/input/lib/webvr-polyfill/complementary-filter.ts","../src/YawPitchControl/input/ComplementaryFilter.ts","../src/PanoImageRenderer/renderer/SphereRenderer.ts","../src/YawPitchControl/input/FusionPoseSensor.ts","../src/YawPitchControl/input/TiltMotionInput.ts","../src/YawPitchControl/ScreenRotationAngle.ts","../src/YawPitchControl/input/RotationPanInput.ts","../src/YawPitchControl/DeviceQuaternion.ts","../src/YawPitchControl/YawPitchControl.ts","../src/PanoViewer/consts.ts","../src/utils/utils.ts","../src/PanoImageRenderer/WebGLUtils.ts","../src/PanoImageRenderer/renderer/Renderer.ts","../src/PanoImageRenderer/renderer/CubeRenderer.ts","../src/PanoImageRenderer/renderer/CubeStripRenderer.ts","../src/PanoImageRenderer/renderer/CylinderRenderer.ts","../src/PanoImageRenderer/vr/VRManager.ts","../src/PanoImageRenderer/vr/XRManager.ts","../src/PanoImageRenderer/WebGLAnimator.ts","../src/PanoImageRenderer/PanoImageRenderer.ts","../src/cfc/withMethods.ts","../src/PanoViewer/PanoViewer.ts","../src/SpinViewer/consts.ts","../src/SpinViewer/SpriteImage.ts","../src/SpinViewer/SpinViewer.ts","../src/cfc/updatePanoViewer.ts","../src/cfc/withPanoViewerMethods.ts","../src/cfc/withSpinViewerMethods.ts","../src/cfc/utils.ts","../src/index.umd.ts"],"sourcesContent":["const VERSION = \"#__VERSION__#\";\n\nexport {\n VERSION\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","/**\n * Original Code\n * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js\n * Math Util\n * modified by egjs\n */\n/**\n * @fileoverview gl-matrix - High performance matrix and vector operations\n * @author Brandon Jones\n * @author Colin MacKenzie IV\n * @version 2.3.2\n */\n\n/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE. */\n\n// Some minimal math functionality borrowed from gl-Matrix and stripped down\n// for the purposes of this library.\n\nimport { vec2, vec3, quat } from \"gl-matrix\";\n\nimport { ValueOf } from \"../types/internal\";\n\nconst quatToVec3 = (quaternion: quat) => {\n const baseV = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(baseV, baseV, quaternion);\n return baseV;\n};\n\nconst toDegree = (a: number) => a * 180 / Math.PI;\n\nconst util: any = {};\n\nutil.isPowerOfTwo = (n: number) => n && (n & (n - 1)) === 0;\n\nutil.extractPitchFromQuat = (quaternion: quat) => {\n const baseV = quatToVec3(quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n};\n\nutil.hypot = Math.hypot || ((x: number, y: number) => Math.sqrt(x * x + y * y));\n\n// implement reference\n// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식\n// calculating angle between two vectors : http://darkpgmr.tistory.com/121\nconst ROTATE_CONSTANT: {\n PITCH_DELTA: 1;\n YAW_DELTA_BY_ROLL: 2;\n YAW_DELTA_BY_YAW: 3;\n} = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n};\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nconst getRotationDelta = (prevQ: quat, curQ: quat, rotateKind: ValueOf) => {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n // const coefficientD = -1 * vec3.dot(vecN, meshPoint1);\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance =\n coefficientA * crossVec[0] +\n coefficientB * crossVec[1] +\n coefficientC * crossVec[2];\n\n let thetaDirection;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return toDegree(deltaRadian);\n};\n\nconst angleBetweenVec2 = (v1: vec2, v2: vec2) => {\n const det = v1[0] * v2[1] - v2[0] * v1[1];\n const theta = -Math.atan2(det, vec2.dot(v1, v2));\n return theta;\n};\n\nutil.yawOffsetBetween = (viewDir: number, targetDir: number) => {\n const viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]);\n const targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]);\n\n vec2.normalize(viewDirXZ, viewDirXZ);\n vec2.normalize(targetDirXZ, targetDirXZ);\n\n const theta = -angleBetweenVec2(viewDirXZ, targetDirXZ);\n\n return theta;\n};\n\nutil.sign = (x: number) => Math.sign\n ? Math.sign(x)\n : (Number(x > 0) - Number(x < 0)) || +x;\n\nutil.toDegree = toDegree;\nutil.getRotationDelta = getRotationDelta;\nutil.angleBetweenVec2 = angleBetweenVec2;\n\nexport {\n util,\n ROTATE_CONSTANT\n};\n","import { quat } from \"gl-matrix\";\n\nimport {\n util as mathUtil,\n ROTATE_CONSTANT\n} from \"../utils/math-util\";\n\nexport const toAxis = (source, offset) => offset.reduce((acc, v, i) => {\n if (source[i]) {\n acc[source[i]] = v;\n }\n return acc;\n}, {});\n\nexport const getDeltaYaw = (prvQ: quat, curQ: quat) => {\n const yawDeltaByYaw = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(mathUtil.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nexport const getDeltaPitch = (prvQ: quat, curQ: quat) => {\n const pitchDelta = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n","import { userAgent } from \"../utils/browserFeature\";\n/**\n * Returns a number value indiciating the version of Chrome being used,\n * or otherwise `null` if not on Chrome.\n *\n * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19\n */\n/**\n * In Chrome m65, `devicemotion` events are broken but subsequently fixed\n * in 65.0.3325.148. Since many browsers use Chromium, ensure that\n * we scope this detection by branch and build numbers to provide\n * a proper fallback.\n * https://github.com/immersive-web/webvr-polyfill/issues/307\n */\nlet version = -1; // It should not be null because it will be compared with number\nlet branch: string | null = null;\nlet build: string | null = null;\n\nconst match = /Chrome\\/([0-9]+)\\.(?:[0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(userAgent);\n\nif (match) {\n version = parseInt(match[1], 10);\n branch = match[2];\n build = match[3];\n}\n\nconst CHROME_VERSION = version;\nconst IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === \"3325\" && parseInt(build!, 10) < 148;\nconst IS_ANDROID = /Android/i.test(userAgent);\n\nconst CONTROL_MODE_VR = 1;\nconst CONTROL_MODE_YAWPITCH = 2;\n\nconst TOUCH_DIRECTION_NONE = 1;\nconst TOUCH_DIRECTION_YAW = 2;\nconst TOUCH_DIRECTION_PITCH = 4;\nconst TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH;\n\n/* Const for MovableCoord */\nconst MC_DECELERATION = 0.0014;\nconst MC_MAXIMUM_DURATION = 1000;\nconst MC_BIND_SCALE = [0.20, 0.20];\n\nconst MIN_FIELD_OF_VIEW = 20;\nconst MAX_FIELD_OF_VIEW = 110;\nconst PAN_SCALE = 320;\n\n// const DELTA_THRESHOLD = 0.015;\n// const DELTA_THRESHOLD = 0.09; // Note4\n// const DELTA_THRESHOLD = 0.0825;\n// const DELTA_THRESHOLD = 0.075;\n// const DELTA_THRESHOLD = 0.06;\n// const DELTA_THRESHOLD = 0.045;\nconst DELTA_THRESHOLD = 0.0375; // Note2\n\nconst YAW_RANGE_HALF = 180;\nconst PITCH_RANGE_HALF = 90;\nconst CIRCULAR_PITCH_RANGE_HALF = 180;\nconst PINCH_EVENTS = \"pinchstart pinchmove pinchend\";\n\nconst KEYMAP = {\n LEFT_ARROW: 37,\n A: 65,\n UP_ARROW: 38,\n W: 87,\n RIGHT_ARROW: 39,\n D: 68,\n DOWN_ARROW: 40,\n S: 83\n};\n\nconst GYRO_MODE: {\n NONE: \"none\";\n YAWPITCH: \"yawPitch\";\n VR: \"VR\";\n} = {\n NONE: \"none\",\n YAWPITCH: \"yawPitch\",\n VR: \"VR\"\n};\n\nexport {\n GYRO_MODE,\n\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n\n TOUCH_DIRECTION_NONE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MIN_FIELD_OF_VIEW,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n DELTA_THRESHOLD,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n PINCH_EVENTS,\n KEYMAP,\n\n CHROME_VERSION,\n IS_CHROME_WITHOUT_DEVICE_MOTION,\n IS_ANDROID\n};\n","/* eslint-disable */\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { window as win } from \"../../../../utils/browser\";\n\nconst MathUtil = win.MathUtil || {};\n\nMathUtil.degToRad = Math.PI / 180;\nMathUtil.radToDeg = 180 / Math.PI;\n\n// Some minimal math functionality borrowed from THREE.Math and stripped down\n// for the purposes of this library.\n\n\nMathUtil.Vector2 = function( x, y ) {\n this.x = x || 0;\n this.y = y || 0;\n};\n\nMathUtil.Vector2.prototype = {\n constructor: MathUtil.Vector2,\n\n set: function( x, y ) {\n this.x = x;\n this.y = y;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n },\n\n subVectors: function( a, b ) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n\n return this;\n }\n};\n\nMathUtil.Vector3 = function( x, y, z ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n};\n\nMathUtil.Vector3.prototype = {\n constructor: MathUtil.Vector3,\n\n set: function( x, y, z ) {\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n\n return this;\n },\n\n length: function() {\n return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n },\n\n normalize: function() {\n const scalar = this.length();\n\n if ( scalar !== 0 ) {\n const invScalar = 1 / scalar;\n\n this.multiplyScalar(invScalar);\n } else {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n }\n\n return this;\n },\n\n multiplyScalar: function( scalar ) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n },\n\n applyQuaternion: function( q ) {\n const x = this.x;\n const y = this.y;\n const z = this.z;\n\n const qx = q.x;\n const qy = q.y;\n const qz = q.z;\n const qw = q.w;\n\n // calculate quat * vector\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = - qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n return this;\n },\n\n dot: function( v ) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n },\n\n crossVectors: function( a, b ) {\n const ax = a.x;\n const ay = a.y;\n const az = a.z;\n const bx = b.x;\n const by = b.y;\n const bz = b.z;\n\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n\n return this;\n }\n};\n\nMathUtil.Quaternion = function( x, y, z, w ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n this.w = ( w !== undefined ) ? w : 1;\n};\n\nMathUtil.Quaternion.prototype = {\n constructor: MathUtil.Quaternion,\n\n set: function( x, y, z, w ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n\n return this;\n },\n\n copy: function( quaternion ) {\n this.x = quaternion.x;\n this.y = quaternion.y;\n this.z = quaternion.z;\n this.w = quaternion.w;\n\n return this;\n },\n\n setFromEulerXYZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 + s1 * s2 * c3;\n this.w = c1 * c2 * c3 - s1 * s2 * s3;\n\n return this;\n },\n\n setFromEulerYXZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 - s1 * s2 * c3;\n this.w = c1 * c2 * c3 + s1 * s2 * s3;\n\n return this;\n },\n\n setFromAxisAngle: function( axis, angle ) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n // assumes axis is normalized\n\n const halfAngle = angle / 2;\n const s = Math.sin( halfAngle );\n\n this.x = axis.x * s;\n this.y = axis.y * s;\n this.z = axis.z * s;\n this.w = Math.cos( halfAngle );\n\n return this;\n },\n\n multiply: function( q ) {\n return this.multiplyQuaternions( this, q );\n },\n\n multiplyQuaternions: function( a, b ) {\n // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n const qax = a.x;\n const qay = a.y;\n const qaz = a.z;\n const qaw = a.w;\n const qbx = b.x;\n const qby = b.y;\n const qbz = b.z;\n const qbw = b.w;\n\n this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n return this;\n },\n\n inverse: function() {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n\n this.normalize();\n\n return this;\n },\n\n normalize: function() {\n let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n if ( l === 0 ) {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n this.w = 1;\n } else {\n l = 1 / l;\n\n this.x = this.x * l;\n this.y = this.y * l;\n this.z = this.z * l;\n this.w = this.w * l;\n }\n\n return this;\n },\n\n slerp: function( qb, t ) {\n if ( t === 0 ) return this;\n if ( t === 1 ) return this.copy( qb );\n\n const x = this.x;\n const y = this.y;\n const z = this.z;\n const w = this.w;\n\n // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n let cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;\n\n if ( cosHalfTheta < 0 ) {\n this.w = - qb.w;\n this.x = - qb.x;\n this.y = - qb.y;\n this.z = - qb.z;\n\n cosHalfTheta = - cosHalfTheta;\n } else {\n this.copy( qb );\n }\n\n if ( cosHalfTheta >= 1.0 ) {\n this.w = w;\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n }\n\n const halfTheta = Math.acos( cosHalfTheta );\n const sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n if ( Math.abs( sinHalfTheta ) < 0.001 ) {\n this.w = 0.5 * ( w + this.w );\n this.x = 0.5 * ( x + this.x );\n this.y = 0.5 * ( y + this.y );\n this.z = 0.5 * ( z + this.z );\n\n return this;\n }\n\n const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;\n const ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n this.w = ( w * ratioA + this.w * ratioB );\n this.x = ( x * ratioA + this.x * ratioB );\n this.y = ( y * ratioA + this.y * ratioB );\n this.z = ( z * ratioA + this.z * ratioB );\n\n return this;\n },\n\n setFromUnitVectors: function() {\n // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n // assumes direction vectors vFrom and vTo are normalized\n\n let v1;\n let r;\n const EPS = 0.000001;\n\n return function( vFrom, vTo ) {\n if ( v1 === undefined ) v1 = new MathUtil.Vector3();\n\n r = vFrom.dot( vTo ) + 1;\n\n if ( r < EPS ) {\n r = 0;\n\n if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n v1.set( - vFrom.y, vFrom.x, 0 );\n } else {\n v1.set( 0, - vFrom.z, vFrom.y );\n }\n } else {\n v1.crossVectors( vFrom, vTo );\n }\n\n this.x = v1.x;\n this.y = v1.y;\n this.z = v1.z;\n this.w = r;\n\n this.normalize();\n\n return this;\n };\n }()\n};\n\nexport default MathUtil;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tslint:disable: only-arrow-functions\n\nimport { window as win, document as doc, navigator as nav } from \"../../../../utils/browser\";\n\nconst userAgent = nav?.userAgent ?? \"\";\nconst Util = (win ).Util || {};\n\nUtil.MIN_TIMESTEP = 0.001;\nUtil.MAX_TIMESTEP = 1;\n\nUtil.base64 = function(mimeType, base64) {\n return \"data:\" + mimeType + \";base64,\" + base64;\n};\n\nUtil.clamp = function(value, min, max) {\n return Math.min(Math.max(min, value), max);\n};\n\nUtil.lerp = function(a, b, t) {\n return a + ((b - a) * t);\n};\n\nUtil.isIOS = (function() {\n const isIOS = /iPad|iPhone|iPod/.test(nav?.platform);\n return function() {\n return isIOS;\n };\n})();\n\nUtil.isWebViewAndroid = (function() {\n const isWebViewAndroid = userAgent.indexOf(\"Version\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1 &&\n userAgent.indexOf(\"Chrome\") !== -1;\n return function() {\n return isWebViewAndroid;\n };\n})();\n\nUtil.isSafari = (function() {\n const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n return function() {\n return isSafari;\n };\n})();\n\nUtil.isFirefoxAndroid = (function() {\n const isFirefoxAndroid = userAgent.indexOf(\"Firefox\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1;\n return function() {\n return isFirefoxAndroid;\n };\n})();\n\nUtil.isR7 = (function() {\n const isR7 = userAgent.indexOf(\"R7 Build\") !== -1;\n return function() {\n return isR7;\n };\n})();\n\nUtil.isLandscapeMode = function() {\n const rtn = (win.orientation === 90 || win.orientation === -90);\n return Util.isR7() ? !rtn : rtn;\n};\n\n// Helper method to validate the time steps of sensor timestamps.\nUtil.isTimestampDeltaValid = function(timestampDeltaS) {\n if (isNaN(timestampDeltaS)) {\n return false;\n }\n if (timestampDeltaS <= Util.MIN_TIMESTEP) {\n return false;\n }\n if (timestampDeltaS > Util.MAX_TIMESTEP) {\n return false;\n }\n return true;\n};\n\nUtil.getScreenWidth = function() {\n return Math.max(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.getScreenHeight = function() {\n return Math.min(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.requestFullscreen = function(element) {\n if (Util.isWebViewAndroid()) {\n return false;\n }\n if (element.requestFullscreen) {\n element.requestFullscreen();\n } else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n } else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n } else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.exitFullscreen = function() {\n if (doc.exitFullscreen) {\n doc.exitFullscreen();\n } else if (doc.webkitExitFullscreen) {\n doc.webkitExitFullscreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.getFullscreenElement = function() {\n return doc.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n};\n\nUtil.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {\n // No error checking for brevity.\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n const program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n\n for (const attribName in attribLocationMap)\n gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);\n\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n};\n\nUtil.getProgramUniforms = function(gl, program) {\n const uniforms = {};\n const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n let uniformName = \"\";\n for (let i = 0; i < uniformCount; i++) {\n const uniformInfo = gl.getActiveUniform(program, i);\n uniformName = uniformInfo.name.replace(\"[0]\", \"\");\n uniforms[uniformName] = gl.getUniformLocation(program, uniformName);\n }\n return uniforms;\n};\n\nUtil.orthoMatrix = function(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right);\n const bt = 1 / (bottom - top);\n const nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n};\n\nUtil.copyArray = function(source, dest) {\n for (let i = 0, n = source.length; i < n; i++) {\n dest[i] = source[i];\n }\n};\n\nUtil.isMobile = function() {\n let check = false;\n (function(a) {\n if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))check = true;\n })(userAgent || nav?.vendor || win.opera);\n return check;\n};\n\nUtil.extend = function(dest, src) {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n dest[key] = src[key];\n }\n }\n\n return dest;\n};\n\nUtil.safariCssSizeWorkaround = function(canvas) {\n // TODO(smus): Remove this workaround when Safari for iOS is fixed.\n // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).\n //\n // \"To the last I grapple with thee;\n // from hell's heart I stab at thee;\n // for hate's sake I spit my last breath at thee.\"\n // -- Moby Dick, by Herman Melville\n if (Util.isIOS()) {\n const width = canvas.style.width;\n const height = canvas.style.height;\n canvas.style.width = (parseInt(width) + 1) + \"px\";\n canvas.style.height = (parseInt(height)) + \"px\";\n setTimeout(function() {\n canvas.style.width = width;\n canvas.style.height = height;\n }, 100);\n }\n\n // Debug only.\n win.Util = Util;\n win.canvas = canvas;\n};\n\nUtil.isDebug = function() {\n return Util.getQueryParameter(\"debug\");\n};\n\nUtil.getQueryParameter = function(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n const results = regex.exec(location.search);\n return results === null ? \"\" : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n};\n\nUtil.frameDataFromPose = (function() {\n const piOver180 = Math.PI / 180.0;\n const rad45 = Math.PI * 0.25;\n\n // Borrowed from glMatrix.\n function mat4_perspectiveFromFieldOfView(out, fov, near, far) {\n const upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45);\n const downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45);\n const leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45);\n const rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45);\n const xScale = 2.0 / (leftTan + rightTan);\n const yScale = 2.0 / (upTan + downTan);\n\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = ((upTan - downTan) * yScale * 0.5);\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = (far * near) / (near - far);\n out[15] = 0.0;\n return out;\n }\n\n function mat4_fromRotationTranslation(out, q, v) {\n // Quaternion math\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n\n return out;\n }\n\n function mat4_translate(out, a, v) {\n const x = v[0];\n const y = v[1];\n const z = v[2];\n let a00;\n let a01;\n let a02;\n let a03;\n let a10;\n let a11;\n let a12;\n let a13;\n let a20;\n let a21;\n let a22;\n let a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];\n a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];\n a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];\n\n out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;\n out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;\n out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;\n\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n }\n\n function mat4_invert(out, a) {\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n }\n\n const defaultOrientation = new Float32Array([0, 0, 0, 1]);\n const defaultPosition = new Float32Array([0, 0, 0]);\n\n function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {\n mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);\n\n const orientation = pose.orientation || defaultOrientation;\n const position = pose.position || defaultPosition;\n\n mat4_fromRotationTranslation(view, orientation, position);\n if (parameters)\n mat4_translate(view, view, parameters.offset);\n mat4_invert(view, view);\n }\n\n return function(frameData, pose, vrDisplay) {\n if (!frameData || !pose)\n return false;\n\n frameData.pose = pose;\n frameData.timestamp = pose.timestamp;\n\n updateEyeMatrices(\n frameData.leftProjectionMatrix, frameData.leftViewMatrix,\n pose, vrDisplay.getEyeParameters(\"left\"), vrDisplay);\n updateEyeMatrices(\n frameData.rightProjectionMatrix, frameData.rightViewMatrix,\n pose, vrDisplay.getEyeParameters(\"right\"), vrDisplay);\n\n return true;\n };\n})();\n\nUtil.isInsideCrossDomainIFrame = function() {\n const isFramed = (win.self !== win.top);\n const refDomain = Util.getDomainFromUrl(doc.referrer);\n const thisDomain = Util.getDomainFromUrl(win.location.href);\n\n return isFramed && (refDomain !== thisDomain);\n};\n\n// From http://stackoverflow.com/a/23945027.\nUtil.getDomainFromUrl = function(url) {\n let domain;\n // Find & remove protocol (http, ftp, etc.) and get domain.\n if (url.indexOf(\"://\") > -1) {\n domain = url.split(\"/\")[2];\n } else {\n domain = url.split(\"/\")[0];\n }\n\n // find & remove port number\n domain = domain.split(\":\")[0];\n\n return domain;\n};\n\nexport default Util;\n","/* eslint-disable */\n\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * Given an orientation and the gyroscope data, predicts the future orientation\n * of the head. This makes rendering appear faster.\n *\n * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf\n * @param {Number} predictionTimeS time from head movement to the appearance of\n * the corresponding image.\n */\nclass PosePredictor {\n public predictionTimeS;\n public previousQ;\n public previousTimestampS;\n public deltaQ;\n public outQ;\n\n public constructor(predictionTimeS) {\n this.predictionTimeS = predictionTimeS;\n\n // The quaternion corresponding to the previous state.\n this.previousQ = new MathUtil.Quaternion();\n // Previous time a prediction occurred.\n this.previousTimestampS = null;\n\n // The delta quaternion that adjusts the current pose.\n this.deltaQ = new MathUtil.Quaternion();\n // The output quaternion.\n this.outQ = new MathUtil.Quaternion();\n }\n\n public getPrediction(currentQ, gyro, timestampS) {\n if (!this.previousTimestampS) {\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n return currentQ;\n }\n\n // Calculate axis and angle based on gyroscope rotation rate data.\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n\n const angularSpeed = gyro.length();\n\n // If we're rotating slowly, don't do prediction.\n if (angularSpeed < MathUtil.degToRad * 20) {\n if (Util.isDebug()) {\n console.log(\"Moving slowly, at %s deg/s: no prediction\",\n (MathUtil.radToDeg * angularSpeed).toFixed(1));\n }\n this.outQ.copy(currentQ);\n this.previousQ.copy(currentQ);\n return this.outQ;\n }\n\n // Get the predicted angle based on the time delta and latency.\n const deltaT = timestampS - this.previousTimestampS;\n const predictAngle = angularSpeed * this.predictionTimeS;\n\n this.deltaQ.setFromAxisAngle(axis, predictAngle);\n this.outQ.copy(this.previousQ);\n this.outQ.multiply(this.deltaQ);\n\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n\n return this.outQ;\n }\n}\n\nexport default PosePredictor;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3 } from \"gl-matrix\";\n\nimport { Mutable } from \"../../types/internal\";\nimport { window } from \"../../utils/browser\";\nimport { IS_CHROME_WITHOUT_DEVICE_MOTION, IS_ANDROID } from \"../consts\";\n\nconst STILLNESS_THRESHOLD = 200; // millisecond\n\nexport default class DeviceMotion extends Component<{\n devicemotion: {\n inputEvent: DeviceMotionEvent | {\n deviceorientation: {\n alpha: number;\n beta: number;\n gamma: number;\n };\n };\n };\n}> {\n public readonly isWithoutDeviceMotion: boolean;\n public readonly isAndroid: boolean;\n\n public stillGyroVec: vec3;\n public rawGyroVec: vec3;\n public adjustedGyroVec: vec3;\n public lastDevicemotionTimestamp: number;\n\n private _timer: number;\n private _isEnabled: boolean;\n\n public constructor() {\n super();\n this._onDeviceMotion = this._onDeviceMotion.bind(this);\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onChromeWithoutDeviceMotion = this._onChromeWithoutDeviceMotion.bind(this);\n\n this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION;\n this.isAndroid = IS_ANDROID;\n\n this.stillGyroVec = vec3.create();\n this.rawGyroVec = vec3.create();\n this.adjustedGyroVec = vec3.create();\n\n this._timer = -1;\n\n this.lastDevicemotionTimestamp = 0;\n this._isEnabled = false;\n this.enable();\n }\n\n public enable() {\n if (this.isAndroid) {\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n }\n if (this.isWithoutDeviceMotion) {\n window.addEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n } else {\n window.addEventListener(\"devicemotion\", this._onDeviceMotion);\n }\n this._isEnabled = true;\n }\n\n public disable() {\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n window.removeEventListener(\"devicemotion\", this._onDeviceMotion);\n this._isEnabled = false;\n }\n\n private _onChromeWithoutDeviceMotion(e: DeviceOrientationEvent) {\n let {alpha, beta, gamma} = e;\n\n // There is deviceorientation event trigged with empty values\n // on Headless Chrome.\n if (alpha === null) {\n return;\n }\n\n // convert to radian\n alpha = (alpha || 0) * Math.PI / 180;\n beta = (beta || 0) * Math.PI / 180;\n gamma = (gamma || 0) * Math.PI / 180;\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: {\n deviceorientation: {\n alpha,\n beta,\n gamma: -gamma\n }\n }\n }));\n }\n\n private _onDeviceOrientation() {\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timer = window.setTimeout(() => {\n if ((new Date().getTime() - this.lastDevicemotionTimestamp) < STILLNESS_THRESHOLD) {\n vec3.copy(this.stillGyroVec, this.rawGyroVec);\n }\n }, STILLNESS_THRESHOLD);\n }\n\n private _onDeviceMotion(e: DeviceMotionEvent) {\n // desktop chrome triggers devicemotion event with empthy sensor values.\n // Those events should ignored.\n const isGyroSensorAvailable = !(e.rotationRate!.alpha == null);\n const isGravitySensorAvailable = !(e.accelerationIncludingGravity!.x == null);\n\n if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) {\n return;\n }\n\n const devicemotionEvent = {...e} as Mutable;\n\n devicemotionEvent.interval = e.interval;\n devicemotionEvent.timeStamp = e.timeStamp;\n devicemotionEvent.type = e.type;\n devicemotionEvent.rotationRate = {\n alpha: e.rotationRate!.alpha,\n beta: e.rotationRate!.beta,\n gamma: e.rotationRate!.gamma\n };\n devicemotionEvent.accelerationIncludingGravity = {\n x: e.accelerationIncludingGravity!.x,\n y: e.accelerationIncludingGravity!.y,\n z: e.accelerationIncludingGravity!.z\n };\n devicemotionEvent.acceleration = {\n x: e.acceleration!.x,\n y: e.acceleration!.y,\n z: e.acceleration!.z\n };\n\n if (this.isAndroid) {\n vec3.set(\n this.rawGyroVec,\n e.rotationRate!.alpha || 0,\n e.rotationRate!.beta || 0,\n e.rotationRate!.gamma || 0);\n vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec);\n this.lastDevicemotionTimestamp = new Date().getTime();\n\n (devicemotionEvent as any).adjustedRotationRate = {\n alpha: this.adjustedGyroVec[0],\n beta: this.adjustedGyroVec[1],\n gamma: this.adjustedGyroVec[2]};\n }\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: devicemotionEvent\n }));\n }\n}\n","class SensorSample {\n public sample;\n public timestampS;\n\n public constructor(sample?, timestampS?) {\n this.set(sample, timestampS);\n }\n\n public set(sample, timestampS) {\n this.sample = sample;\n this.timestampS = timestampS;\n }\n\n public copy(sensorSample) {\n this.set(sensorSample.sample, sensorSample.timestampS);\n }\n}\n\nexport default SensorSample;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SensorSample from \"./sensor-sample\";\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * An implementation of a simple complementary filter, which fuses gyroscope and\n * accelerometer data from the 'devicemotion' event.\n *\n * Accelerometer data is very noisy, but stable over the long term.\n * Gyroscope data is smooth, but tends to drift over the long term.\n *\n * This fusion is relatively simple:\n * 1. Get orientation estimates from accelerometer by applying a low-pass filter\n * on that data.\n * 2. Get orientation estimates from gyroscope by integrating over time.\n * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the\n * short term.\n */\nclass ComplementaryFilter {\n public kFilter;\n public currentAccelMeasurement;\n public currentGyroMeasurement;\n public previousGyroMeasurement;\n public filterQ;\n public previousFilterQ;\n public accelQ;\n public isOrientationInitialized;\n public estimatedGravity;\n public measuredGravity;\n public gyroIntegralQ;\n\n constructor(kFilter) {\n this.kFilter = kFilter;\n\n // Raw sensor measurements.\n this.currentAccelMeasurement = new SensorSample();\n this.currentGyroMeasurement = new SensorSample();\n this.previousGyroMeasurement = new SensorSample();\n\n // Set default look direction to be in the correct direction.\n if (Util.isIOS()) {\n this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);\n } else {\n this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);\n }\n this.previousFilterQ = new MathUtil.Quaternion();\n this.previousFilterQ.copy(this.filterQ);\n\n // Orientation based on the accelerometer.\n this.accelQ = new MathUtil.Quaternion();\n // Whether or not the orientation has been initialized.\n this.isOrientationInitialized = false;\n // Running estimate of gravity based on the current orientation.\n this.estimatedGravity = new MathUtil.Vector3();\n // Measured gravity based on accelerometer.\n this.measuredGravity = new MathUtil.Vector3();\n\n // Debug only quaternion of gyro-based orientation.\n this.gyroIntegralQ = new MathUtil.Quaternion();\n }\n\n public addAccelMeasurement(vector, timestampS) {\n this.currentAccelMeasurement.set(vector, timestampS);\n }\n\n public addGyroMeasurement = function(vector, timestampS) {\n this.currentGyroMeasurement.set(vector, timestampS);\n\n const deltaT = timestampS - this.previousGyroMeasurement.timestampS;\n if (Util.isTimestampDeltaValid(deltaT)) {\n this.run_();\n }\n\n this.previousGyroMeasurement.copy(this.currentGyroMeasurement);\n };\n\n public getOrientation() {\n return this.filterQ;\n }\n\n public run_() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n if (Util.isDebug()) {\n console.log(\"Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)\",\n MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),\n (this.estimatedGravity.x).toFixed(1),\n (this.estimatedGravity.y).toFixed(1),\n (this.estimatedGravity.z).toFixed(1),\n (this.measuredGravity.x).toFixed(1),\n (this.measuredGravity.y).toFixed(1),\n (this.measuredGravity.z).toFixed(1));\n }\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n }\n\n private accelToQuaternion_(accel) {\n const normAccel = new MathUtil.Vector3();\n normAccel.copy(accel);\n normAccel.normalize();\n const quat = new MathUtil.Quaternion();\n quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);\n quat.inverse();\n return quat;\n }\n\n private gyroToQuaternionDelta_(gyro, dt) {\n // Extract axis and angle from the gyroscope data.\n const quat = new MathUtil.Quaternion();\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n quat.setFromAxisAngle(axis, gyro.length() * dt);\n return quat;\n }\n}\n\nexport default ComplementaryFilter;\n","import MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport ComplementaryFilter from \"./lib/webvr-polyfill/complementary-filter\";\n\nComplementaryFilter.prototype.run_ = function() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n\n if (!this.isFilterQuaternionInitialized) {\n this.isFilterQuaternionInitialized = true;\n }\n};\n\nComplementaryFilter.prototype.getOrientation = function() {\n if (this.isFilterQuaternionInitialized) {\n return this.filterQ;\n } else {\n return null;\n }\n};\n\nexport default ComplementaryFilter;\n","import WebGLUtils from \"../WebGLUtils\";\nimport { STEREO_FORMAT } from \"../../PanoViewer/consts\";\nimport { ValueOf } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nconst latitudeBands = 60;\nconst longitudeBands = 60;\nconst radius = 2;\nconst ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\nlet latIdx: number;\nlet lngIdx: number;\n\nfor (latIdx = 0; latIdx <= latitudeBands; latIdx++) {\n const theta = (latIdx / latitudeBands - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / longitudeBands;\n const v = latIdx / latitudeBands;\n\n textureCoordData.push(u, v);\n vertexPositionData.push(radius * x, radius * y, radius * z);\n\n if (lngIdx !== longitudeBands && latIdx !== latitudeBands) {\n const a = latIdx * (longitudeBands + 1) + lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n}\n\nclass SphereRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n private _stereoFormat: ValueOf;\n\n public constructor(format: SphereRenderer[\"_stereoFormat\"]) {\n super();\n\n this._stereoFormat = format;\n }\n\n public render(ctx: Parameters[0]) {\n const {gl, shaderProgram} = ctx;\n\n let leftEyeScaleOffset: number[];\n let rightEyeScaleOffset: number[];\n\n switch (this._stereoFormat) {\n case STEREO_FORMAT.TOP_BOTTOM:\n leftEyeScaleOffset = [1, 0.5, 0, 0];\n rightEyeScaleOffset = [1, 0.5, 0, 0.5];\n break;\n case STEREO_FORMAT.LEFT_RIGHT:\n leftEyeScaleOffset = [0.5, 1, 0, 0];\n rightEyeScaleOffset = [0.5, 1, 0.5, 0];\n break;\n default:\n leftEyeScaleOffset = [1, 1, 0, 0];\n rightEyeScaleOffset = [1, 1, 0, 0];\n }\n\n const uTexScaleOffset = gl.getUniformLocation(shaderProgram, \"uTexScaleOffset\");\n\n gl.uniform4fv(uTexScaleOffset, [...leftEyeScaleOffset, ...rightEyeScaleOffset]);\n\n super.render(ctx);\n }\n\n public getVertexPositionData() {\n return SphereRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return SphereRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return SphereRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const { width, height } = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n}\n\nexport default SphereRenderer;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\n\nimport { window, IS_IOS, IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { CHROME_VERSION } from \"../consts\";\n\nimport PosePredictor from \"./lib/webvr-polyfill/pose-predictor\";\nimport MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport Util from \"./lib/webvr-polyfill/util\";\nimport DeviceMotion from \"./DeviceMotion\";\nimport ComplementaryFilter from \"./ComplementaryFilter\";\n\n\nconst K_FILTER = 0.98;\nconst PREDICTION_TIME_S = 0.040;\n\nexport default class FusionPoseSensor extends Component<{\n change: {\n quaternion: quat;\n };\n}> {\n public deviceMotion: DeviceMotion | null;\n public accelerometer: any;\n public gyroscope: any;\n public filter: ComplementaryFilter;\n public posePredictor: PosePredictor;\n public filterToWorldQ: any;\n public isFirefoxAndroid: boolean;\n public isIOS: boolean;\n public isChromeUsingDegrees: boolean;\n public inverseWorldToScreenQ: any;\n public worldToScreenQ: any;\n public originalPoseAdjustQ: any;\n public resetQ: any;\n public deviceOrientationFixQ: any;\n public predictedQ: any;\n public previousTimestampS: number;\n\n private _isEnabled: boolean;\n private _deviceOrientationQ: any;\n private _prevOrientation: quat;\n private _alpha: number;\n\n public constructor() {\n super();\n\n this.deviceMotion = new DeviceMotion();\n\n this.accelerometer = new MathUtil.Vector3();\n this.gyroscope = new MathUtil.Vector3();\n\n this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);\n this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);\n\n this.filter = new ComplementaryFilter(K_FILTER);\n this.posePredictor = new PosePredictor(PREDICTION_TIME_S);\n\n this.filterToWorldQ = new MathUtil.Quaternion();\n\n this.isFirefoxAndroid = Util.isFirefoxAndroid();\n // This includes iPhone & iPad(both desktop and mobile mode) ref #326\n this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP;\n\n // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18\n this.isChromeUsingDegrees = CHROME_VERSION >= 66;\n\n this._isEnabled = false;\n\n // Set the filter to world transform, depending on OS.\n if (this.isIOS) {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);\n } else {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n this.inverseWorldToScreenQ = new MathUtil.Quaternion();\n this.worldToScreenQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),\n -window.orientation * Math.PI / 180);\n\n this._setScreenTransform();\n // Adjust this filter for being in landscape mode.\n if (Util.isLandscapeMode()) {\n this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);\n }\n\n // Keep track of a reset transform for resetSensor.\n this.resetQ = new MathUtil.Quaternion();\n\n this.deviceMotion.on(\"devicemotion\", this._onDeviceMotionChange);\n this.enable();\n }\n\n public enable() {\n if (this.isEnabled()) {\n return;\n }\n this.deviceMotion!.enable();\n this._isEnabled = true;\n window.addEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public disable() {\n if (!this.isEnabled()) {\n return;\n }\n this.deviceMotion!.disable();\n this._isEnabled = false;\n window.removeEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public isEnabled() {\n return this._isEnabled;\n }\n\n public destroy() {\n this.disable();\n this.deviceMotion = null;\n }\n\n public getOrientation() {\n let orientation;\n\n // Hack around using deviceorientation instead of devicemotion\n if (this.deviceMotion!.isWithoutDeviceMotion && this._deviceOrientationQ) {\n this.deviceOrientationFixQ = this.deviceOrientationFixQ || (() => {\n const y = new MathUtil.Quaternion()\n .setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -this._alpha);\n\n return y;\n })();\n\n orientation = this._deviceOrientationQ;\n const out = new MathUtil.Quaternion();\n\n out.copy(orientation);\n out.multiply(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.worldToScreenQ);\n out.multiplyQuaternions(this.deviceOrientationFixQ, out);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n } else {\n // Convert from filter space to the the same system used by the\n // deviceorientation event.\n orientation = this.filter.getOrientation();\n\n if (!orientation) {\n return null;\n }\n\n const out = this._convertFusionToPredicted(orientation);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n }\n }\n\n private _triggerChange() {\n const orientation = this.getOrientation();\n\n // if orientation is not prepared. don't trigger change event\n if (!orientation) {\n return;\n }\n\n if (!this._prevOrientation) {\n this._prevOrientation = orientation;\n return;\n }\n\n if (quat.equals(this._prevOrientation, orientation)) {\n return;\n }\n\n this.trigger(new ComponentEvent(\"change\", { quaternion: orientation }));\n }\n\n private _convertFusionToPredicted(orientation: quat) {\n // Predict orientation.\n this.predictedQ =\n this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);\n\n // Convert to THREE coordinate system: -Z forward, Y up, X right.\n const out = new MathUtil.Quaternion();\n\n out.copy(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.predictedQ);\n out.multiply(this.worldToScreenQ);\n\n return out;\n }\n\n private _onDeviceMotionChange({ inputEvent }) {\n const deviceorientation = inputEvent.deviceorientation;\n const deviceMotion = inputEvent;\n const accGravity = deviceMotion.accelerationIncludingGravity;\n const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;\n let timestampS = deviceMotion.timeStamp / 1000;\n\n if (deviceorientation) {\n if (!this._alpha) {\n this._alpha = deviceorientation.alpha;\n }\n this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();\n this._deviceOrientationQ.setFromEulerYXZ(\n deviceorientation.beta,\n deviceorientation.alpha,\n deviceorientation.gamma\n );\n\n this._triggerChange();\n } else {\n // Firefox Android timeStamp returns one thousandth of a millisecond.\n if (this.isFirefoxAndroid) {\n timestampS /= 1000;\n }\n\n this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);\n this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);\n\n // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate`\n // is reported in degrees, so we first convert to radians.\n if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) {\n this.gyroscope.multiplyScalar(Math.PI / 180);\n }\n\n this.filter.addAccelMeasurement(this.accelerometer, timestampS);\n this.filter.addGyroMeasurement(this.gyroscope, timestampS);\n\n this._triggerChange();\n\n this.previousTimestampS = timestampS;\n }\n }\n\n private _onScreenOrientationChange() {\n this._setScreenTransform();\n }\n\n private _setScreenTransform() {\n this.worldToScreenQ.set(0, 0, 0, 1);\n\n const orientation = window.orientation;\n\n switch (orientation) {\n case 0:\n break;\n case 90:\n case -90:\n case 180:\n this.worldToScreenQ\n .setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI);\n break;\n default:\n break;\n }\n this.inverseWorldToScreenQ.copy(this.worldToScreenQ);\n this.inverseWorldToScreenQ.inverse();\n }\n}\n","import Component from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\n\nimport { toAxis } from \"../utils\";\nimport { util, ROTATE_CONSTANT } from \"../../utils/math-util\";\n\nimport FusionPoseSensor from \"./FusionPoseSensor\";\n\nconst getDeltaYaw = (prvQ: quat, curQ: quat): number => {\n const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(util.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nconst getDeltaPitch = (prvQ: quat, curQ: quat): number => {\n const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport default class TiltMotionInput extends Component<{}> {\n public element: HTMLElement;\n public options: { scale: number; threshold: number };\n public fusionPoseSensor: FusionPoseSensor | null;\n public axes: string[];\n public observer: InputTypeObserver | null;\n\n private _prevQuaternion: quat | null;\n private _quaternion: quat | null;\n\n public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {\n super();\n this.element = el;\n\n this._prevQuaternion = null;\n this._quaternion = null;\n\n this.fusionPoseSensor = null;\n\n this.options = {\n ...{\n scale: 1,\n threshold: 0\n }, ...options\n };\n\n this._onPoseChange = this._onPoseChange.bind(this);\n }\n\n public mapAxes(axes: string[]) {\n this.axes = axes;\n }\n\n public connect(observer: InputTypeObserver) {\n if (this.observer) {\n return this;\n }\n this.observer = observer;\n this.fusionPoseSensor = new FusionPoseSensor();\n this.fusionPoseSensor.enable();\n this._attachEvent();\n return this;\n }\n\n public disconnect() {\n if (!this.observer) {\n return this;\n }\n\n this._dettachEvent();\n this.fusionPoseSensor!.disable();\n this.fusionPoseSensor!.destroy();\n this.fusionPoseSensor = null;\n this.observer = null;\n return this;\n }\n\n public destroy() {\n this.disconnect();\n (this.element as any) = null;\n (this.options as any) = null;\n (this.axes as any) = null;\n this._prevQuaternion = null;\n this._quaternion = null;\n }\n\n private _onPoseChange(event) {\n if (!this._prevQuaternion) {\n this._prevQuaternion = quat.clone(event.quaternion);\n this._quaternion = quat.clone(event.quaternion);\n return;\n }\n\n quat.copy(this._prevQuaternion, this._quaternion!);\n quat.copy(this._quaternion!, event.quaternion);\n\n this.observer!.change(this, event, toAxis(this.axes, [\n getDeltaYaw(this._prevQuaternion, this._quaternion as quat),\n getDeltaPitch(this._prevQuaternion, this._quaternion as quat)\n ]));\n }\n\n private _attachEvent() {\n this.fusionPoseSensor!.on(\"change\", this._onPoseChange);\n }\n\n private _dettachEvent() {\n this.fusionPoseSensor!.off(\"change\", this._onPoseChange);\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport { window } from \"../utils/browser\";\n\n// Singleton\nlet screenRotationAngleInst: ScreenRotationAngle | null = null;\nlet refCount = 0;\n\nexport default class ScreenRotationAngle {\n private _spinR: number;\n private _screenOrientationAngle: number;\n\n public constructor() {\n refCount++;\n\n if (screenRotationAngleInst) {\n return screenRotationAngleInst;\n }\n /* eslint-disable */\n screenRotationAngleInst = this;\n /* eslint-enable */\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n\n this._spinR = 0;\n\n this._screenOrientationAngle = 0;\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.addEventListener(\"orientationchange\", this._onOrientationChange);\n }\n\n public getRadian() {\n // Join with screen orientation\n // this._testVal = this._spinR + \", \" + this._screenOrientationAngle + \", \" + window.orientation;\n return this._spinR + glMatrix.toRadian(this._screenOrientationAngle);\n }\n\n public unref() {\n if (--refCount > 0) {\n return;\n }\n\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"orientationchange\", this._onOrientationChange);\n\n this._spinR = 0;\n this._screenOrientationAngle = 0;\n /* eslint-disable */\n screenRotationAngleInst = null;\n /* eslint-enable */\n refCount = 0;\n }\n\n private _onDeviceOrientation(e: DeviceOrientationEvent) {\n if (e.beta === null || e.gamma === null) {\n // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it.\n return;\n }\n\n // Radian\n const betaR = glMatrix.toRadian(e.beta);\n const gammaR = glMatrix.toRadian(e.gamma);\n\n /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */\n this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR));\n }\n\n private _onOrientationChange() {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientationAngle = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n /* iOS */\n this._screenOrientationAngle = window.orientation >= 0 ?\n window.orientation : 360 + (window.orientation as number);\n }\n }\n}\n","import Axes, { PanInput } from \"@egjs/axes\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\nimport { PanInputOption } from \"@egjs/axes/declaration/inputType/PanInput\";\n\nimport ScreenRotationAngle from \"../ScreenRotationAngle\";\n\n/**\n * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle.\n *\n * The reason for using this function is that in VR mode,\n * the roll angle is adjusted in the direction opposite to the screen rotation angle.\n *\n * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move.\n * @extends PanInput\n */\nexport default class RotationPanInput extends PanInput {\n private _useRotation: boolean;\n private _screenRotationAngle: ScreenRotationAngle | null;\n private _userDirection: number;\n\n /**\n * Constructor\n * @private\n * @param {HTMLElement} el target element\n * @param {Object} [options] The option object\n * @param {Boolean} [options.useRotation] Whether to use rotation(or VR)\n */\n public constructor(el: HTMLElement, options: Partial<{ useRotation: boolean } & PanInputOption> = {}) {\n super(el, options);\n\n this._useRotation = false;\n this._screenRotationAngle = null;\n\n this.setUseRotation(!!(options && options.useRotation));\n\n this._userDirection = Axes.DIRECTION_ALL;\n }\n\n public setUseRotation(useRotation: boolean) {\n this._useRotation = useRotation;\n\n if (this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n this._screenRotationAngle = null;\n }\n\n if (this._useRotation) {\n this._screenRotationAngle = new ScreenRotationAngle();\n }\n }\n\n public connect(observer: InputTypeObserver) {\n // User intetened direction\n this._userDirection = this._direction;\n\n // In VR Mode, Use ALL direction if direction is not none\n // Because horizontal and vertical is changed dynamically by screen rotation.\n // this._direction is used to initialize hammerjs\n if (this._useRotation && (this._direction & Axes.DIRECTION_ALL)) {\n this._direction = Axes.DIRECTION_HORIZONTAL;\n }\n\n return super.connect(observer);\n }\n\n public destroy() {\n if (this._useRotation && this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n }\n\n super.destroy();\n }\n\n protected _getOffset(properties: number[], useDirection: boolean[]) {\n if (this._useRotation === false) {\n return super._getOffset(properties, useDirection);\n }\n\n const offset = super._getOffset(properties, [true, true]);\n const newOffset = [0, 0];\n\n const theta = this._screenRotationAngle!.getRadian();\n\n const cosTheta = Math.cos(theta);\n const sinTheta = Math.sin(theta);\n\n // RotateZ\n newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta;\n newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta;\n\n // Use only user allowed direction.\n if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) {\n newOffset[0] = 0;\n } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) {\n newOffset[1] = 0;\n }\n\n return newOffset;\n }\n}\n\n/**\n * Override getDirectionByAngle to return DIRECTION_ALL\n * Ref: https://github.com/naver/egjs-axes/issues/99\n *\n * But we obey axes's rule. If axes's rule is problem, let's apply following code.\n */\n// PanInput.getDirectionByAngle = function (angle, thresholdAngle) {\n// \treturn DIRECTION_ALL;\n// };\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3, glMatrix, quat } from \"gl-matrix\";\n\nimport FusionPoseSensor from \"./input/FusionPoseSensor\";\n\nconst Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0);\n\nexport default class DeviceQuaternion extends Component<{\n change: {\n isTrusted: boolean;\n };\n}> {\n private _fusionPoseSensor: FusionPoseSensor | null;\n private _quaternion: quat;\n\n public constructor() {\n super();\n\n this._fusionPoseSensor = new FusionPoseSensor();\n this._quaternion = quat.create();\n\n this._fusionPoseSensor.enable();\n this._fusionPoseSensor.on(\"change\", e => {\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(\"change\", { isTrusted: true }));\n });\n }\n\n public getCombinedQuaternion(yaw: number) {\n const yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw));\n const conj = quat.conjugate(quat.create(), this._quaternion);\n // Multiply pitch quaternion -> device quaternion -> yaw quaternion\n const outQ = quat.multiply(quat.create(), conj, yawQ);\n\n return outQ;\n }\n\n public destroy() {\n // detach all event handler\n this.off();\n\n if (this._fusionPoseSensor) {\n this._fusionPoseSensor.off();\n this._fusionPoseSensor.destroy();\n this._fusionPoseSensor = null;\n }\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PinchInput, MoveKeyInput, WheelInput } from \"@egjs/axes\";\nimport { vec2, quat, glMatrix } from \"gl-matrix\";\n\nimport { SUPPORT_TOUCH, SUPPORT_DEVICEMOTION } from \"../utils/browserFeature\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { ValueOf } from \"../types/internal\";\n\nimport TiltMotionInput from \"./input/TiltMotionInput\";\nimport RotationPanInput from \"./input/RotationPanInput\";\nimport DeviceQuaternion from \"./DeviceQuaternion\";\nimport {\n GYRO_MODE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n TOUCH_DIRECTION_NONE\n} from \"./consts\";\n\n\nconst DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF];\nconst DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF];\nconst CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF];\n\nexport interface YawPitchControlOptions {\n element: HTMLElement | null;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n touchDirection: number;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n aspectRatio: number;\n}\ninterface YawPitchControlEvents {\n change: ComponentEvent<{\n yaw: number;\n pitch: number;\n fov: number;\n quaternion: quat | null;\n targetElement: HTMLElement;\n isTrusted: boolean;\n }>;\n hold: ComponentEvent<{\n isTrusted: boolean;\n }>;\n animationEnd: ComponentEvent<{\n isTrusted: boolean;\n }>;\n}\n\n/**\n * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates.\n * @alias eg.YawPitchControl\n * @extends eg.Component\n *\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass YawPitchControl extends Component {\n public static VERSION = VERSION;\n // Expose DeviceOrientationControls sub module for test purpose\n public static CONTROL_MODE_VR = CONTROL_MODE_VR;\n public static CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH;\n public static TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL;\n public static TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW;\n public static TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH;\n public static TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE;\n\n public options: YawPitchControlOptions;\n\n private _element: HTMLElement | null;\n private _initialFov: number;\n private _enabled: boolean;\n private _isAnimating: boolean;\n private _deviceQuaternion: DeviceQuaternion | null;\n\n private _axes: Axes;\n private _axesPanInput: RotationPanInput;\n private _axesWheelInput: WheelInput;\n private _axesTiltMotionInput: TiltMotionInput | null;\n private _axesPinchInput: PinchInput | null;\n private _axesMoveKeyInput: MoveKeyInput;\n\n /**\n * @param {object} options The option object of the eg.YawPitch module\n * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module\n * @param {number} [options.yaw=0] initial yaw (degree)\n * @param {number} [options.pitch=0] initial pitch (degree)\n * @param {number} [options.fov=65] initial field of view (degree)\n * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown\n * @param {boolean} [options.useZoom=true] Indicates whether zoom is available\n * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled\n * @param {string} [config.gyroMode=yawPitch] Enables control through device motion.\n * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move)\n * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw\n * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch\n * @param {number[]} [options.fovRange=[30, 110] Range of FOV\n * @param {number} [options.aspectRatio=1] Aspect Ratio\n */\n public constructor(options: Partial) {\n super();\n this.options = {} as any;\n\n const opt = {\n ...{\n element: null,\n yaw: 0,\n pitch: 0,\n fov: 65,\n showPolePoint: false,\n useZoom: true,\n useKeyboard: true,\n gyroMode: GYRO_MODE.YAWPITCH,\n touchDirection: TOUCH_DIRECTION_ALL,\n yawRange: DEFAULT_YAW_RANGE,\n pitchRange: DEFAULT_PITCH_RANGE,\n fovRange: [30, 110],\n aspectRatio: 1 /* TODO: Need Mandatory? */\n }, ...options\n };\n\n this._element = opt.element;\n this._initialFov = opt.fov;\n this._enabled = false;\n this._isAnimating = false;\n this._deviceQuaternion = null;\n\n this._initAxes(opt);\n this.option(opt);\n }\n\n /**\n * Update Pan Scale\n *\n * Scale(Sensitivity) values of panning is related with fov and height.\n * If at least one of them is changed, this function need to be called.\n * @param {*} param\n */\n public updatePanScale(param: Partial<{\n height: number;\n }> = {}) {\n const fov = this._axes.get().fov;\n const areaHeight = param.height || parseInt(window.getComputedStyle(this._element!).height, 10);\n const scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight;\n\n this._axesPanInput.options.scale = [scale, scale];\n this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW;\n\n return this;\n }\n\n public option(): YawPitchControlOptions;\n public option(key: K): YawPitchControlOptions[K];\n public option(key: K, newValue: YawPitchControlOptions[K]): YawPitchControl;\n public option(newOptions: Partial): YawPitchControl;\n /*\n * Override component's option method\n * to call method for updating values which is affected by option change.\n *\n * @param {*} args\n */\n public option(key?: K | Partial, newValue?: YawPitchControlOptions[K]) {\n // Getter\n if (!key) {\n return this._getOptions();\n } else if (key && typeof key === \"string\" && typeof newValue === \"undefined\") {\n return this._getOptions(key);\n }\n\n // Setter\n let newOptions: Partial = {};\n let changedKeyList: string[] = []; // TODO: if value is not changed, then do not push on changedKeyList.\n\n if (typeof key === \"string\") {\n changedKeyList.push(key);\n newOptions[key] = newValue;\n } else {\n const options = key; // Retrieving object here\n changedKeyList = Object.keys(options);\n newOptions = {...options};\n }\n\n this._setOptions(this._getValidatedOptions(newOptions));\n this._applyOptions(changedKeyList);\n return this;\n }\n\n /**\n * Enable YawPitch functionality\n * @method eg.YawPitch#enable\n */\n public enable() {\n if (this._enabled) {\n return this;\n }\n\n this._enabled = true;\n\n // touchDirection is decided by parameter is valid string (Ref. Axes.connect)\n this._applyOptions(Object.keys(this.options));\n\n // TODO: Is this code is needed? Check later.\n this.updatePanScale();\n\n return this;\n }\n\n /**\n * Disable YawPitch functionality\n * @method eg.YawPitch#disable\n */\n public disable(persistOrientation: boolean = false) {\n if (!this._enabled) {\n return this;\n }\n\n // TODO: Check peristOrientation is needed!\n if (!persistOrientation) {\n this._resetOrientation();\n }\n this._axes.disconnect();\n this._enabled = false;\n return this;\n }\n\n /**\n * Set one or more of yaw, pitch, fov\n * @param {Object} coordinate yaw, pitch, fov\n * @param {Number} duration Animation duration. if it is above 0 then it's animated.\n */\n public lookAt({yaw, pitch, fov}, duration) {\n const pos = this._axes.get();\n\n const y = yaw === undefined ? 0 : yaw - pos.yaw;\n const p = pitch === undefined ? 0 : pitch - pos.pitch;\n const f = fov === undefined ? 0 : fov - pos.fov;\n\n // Allow duration of animation to have more than MC_MAXIMUM_DURATION.\n this._axes.options.maximumDuration = Infinity;\n\n this._axes.setBy({\n yaw: y,\n pitch: p,\n fov: f\n }, duration);\n }\n\n public getYawPitch() {\n const yawPitch = this._axes.get();\n\n return {\n yaw: yawPitch.yaw,\n pitch: yawPitch.pitch\n };\n }\n\n public getFov() {\n return this._axes.get().fov;\n }\n\n public getQuaternion() {\n const pos = this._axes.get();\n\n return this._deviceQuaternion!.getCombinedQuaternion(pos.yaw);\n }\n\n public shouldRenderWithQuaternion() {\n return this.options.gyroMode === GYRO_MODE.VR;\n }\n\n /**\n * Destroys objects\n */\n public destroy() {\n /* eslint-disable @typescript-eslint/no-unused-expressions */\n this._axes && this._axes.destroy();\n this._axesPanInput && this._axesPanInput.destroy();\n this._axesWheelInput && this._axesWheelInput.destroy();\n this._axesTiltMotionInput && this._axesTiltMotionInput.destroy();\n this._axesPinchInput && this._axesPinchInput.destroy();\n this._axesMoveKeyInput && this._axesMoveKeyInput.destroy();\n this._deviceQuaternion && this._deviceQuaternion.destroy();\n /* eslint-enable @typescript-eslint/no-unused-expressions */\n }\n\n private _initAxes(opt: YawPitchControlOptions) {\n const yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio);\n const pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint);\n const useRotation = opt.gyroMode === GYRO_MODE.VR;\n\n this._axesPanInput = new RotationPanInput(this._element!, {useRotation});\n this._axesWheelInput = new WheelInput(this._element, {scale: -4});\n this._axesTiltMotionInput = null;\n this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, {scale: -1}) : null;\n this._axesMoveKeyInput = new MoveKeyInput(this._element, {scale: [-6, 6]});\n\n this._axes = new Axes({\n yaw: {\n range: yRange,\n circular: this._isCircular(yRange),\n bounce: [0, 0]\n },\n pitch: {\n range: pRange,\n circular: this._isCircular(pRange),\n bounce: [0, 0]\n },\n fov: {\n range: opt.fovRange,\n circular: [false, false],\n bounce: [0, 0]\n }\n }, {\n deceleration: MC_DECELERATION,\n maximumDuration: MC_MAXIMUM_DURATION\n }, {\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }).on({\n // TODO: change event type after Axes event type inference update\n hold: (evt: any) => {\n // Restore maximumDuration not to be spin too mush.\n this._axes.options.maximumDuration = MC_MAXIMUM_DURATION;\n\n this.trigger(new ComponentEvent(\"hold\", { isTrusted: evt.isTrusted }));\n },\n change: (evt: any) => {\n if (evt.delta.fov !== 0) {\n this._updateControlScale(evt);\n this.updatePanScale();\n }\n this._triggerChange(evt);\n },\n release: evt => {\n this._triggerChange(evt);\n },\n animationEnd: (evt: any) => {\n this.trigger(new ComponentEvent(\"animationEnd\", { isTrusted: evt.isTrusted }));\n }\n });\n }\n\n private _getValidatedOptions(newOptions: Partial) {\n if (newOptions.yawRange) {\n newOptions.yawRange =\n this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio);\n }\n if (newOptions.pitchRange) {\n newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov);\n }\n return newOptions;\n }\n\n private _getOptions(): YawPitchControlOptions;\n private _getOptions(key: K): YawPitchControlOptions[K];\n private _getOptions(key?: K) {\n let value;\n\n if (typeof key === \"string\") {\n value = this.options[key];\n } else if (arguments.length === 0) {\n value = this.options;\n }\n return value;\n }\n\n private _setOptions(options: Partial): void {\n for (const key in options) {\n this.options[key] = options[key];\n }\n }\n\n private _applyOptions(keys: string[]) {\n const options = this.options;\n const axes = this._axes;\n const isVR = options.gyroMode === GYRO_MODE.VR;\n const isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH;\n // If it's VR mode, restrict user interaction to yaw direction only\n const touchDirection = isVR ?\n (TOUCH_DIRECTION_YAW & options.touchDirection) :\n options.touchDirection;\n\n // If one of below is changed, call updateControlScale()\n if (keys.some(key =>\n key === \"showPolePoint\" || key === \"fov\" || key === \"aspectRatio\" ||\n key === \"yawRange\" || key === \"pitchRange\"\n )) {\n // If fov is changed, update pan scale\n if (keys.indexOf(\"fov\") >= 0) {\n axes.setTo({\"fov\": options.fov});\n this.updatePanScale();\n }\n\n this._updateControlScale();\n }\n\n if (keys.some(key => key === \"fovRange\")) {\n const fovRange = options.fovRange;\n const prevFov = axes.get().fov;\n let nextFov = axes.get().fov;\n\n vec2.copy(axes.axis.fov.range as vec2, fovRange as vec2);\n\n if (nextFov < fovRange[0]) {\n nextFov = fovRange[0];\n } else if (prevFov > fovRange[1]) {\n nextFov = fovRange[1];\n }\n\n if (prevFov !== nextFov) {\n axes.setTo({\n fov: nextFov\n }, 0);\n this._updateControlScale();\n this.updatePanScale();\n }\n }\n\n if (keys.some(key => key === \"gyroMode\") && SUPPORT_DEVICEMOTION) {\n // Disconnect first\n if (this._axesTiltMotionInput) {\n this._axes.disconnect(this._axesTiltMotionInput);\n this._axesTiltMotionInput.destroy();\n this._axesTiltMotionInput = null;\n }\n\n if (this._deviceQuaternion) {\n this._deviceQuaternion.destroy();\n this._deviceQuaternion = null;\n }\n\n if (isVR) {\n this._initDeviceQuaternion();\n } else if (isYawPitch) {\n this._axesTiltMotionInput = new TiltMotionInput(this._element!);\n this._axes.connect([\"yaw\", \"pitch\"], this._axesTiltMotionInput);\n }\n\n this._axesPanInput.setUseRotation(isVR);\n }\n\n if (keys.some(key => key === \"useKeyboard\")) {\n const useKeyboard = options.useKeyboard;\n\n if (useKeyboard) {\n axes.connect([\"yaw\", \"pitch\"], this._axesMoveKeyInput);\n } else {\n axes.disconnect(this._axesMoveKeyInput);\n }\n }\n\n if (keys.some(key => key === \"useZoom\")) {\n const useZoom = options.useZoom;\n\n // Disconnect first\n axes.disconnect(this._axesWheelInput);\n if (useZoom) {\n axes.connect([\"fov\"], this._axesWheelInput);\n }\n }\n\n this._togglePinchInputByOption(options.touchDirection, options.useZoom);\n\n if (keys.some(key => key === \"touchDirection\") && this._enabled) {\n this._enableTouch(touchDirection);\n }\n }\n\n private _togglePinchInputByOption(touchDirection: YawPitchControlOptions[\"touchDirection\"], useZoom: boolean) {\n if (this._axesPinchInput) {\n // disconnect first\n this._axes.disconnect(this._axesPinchInput);\n\n // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll.\n if (\n useZoom &&\n touchDirection === TOUCH_DIRECTION_ALL &&\n // TODO: Get rid of using private property of axes instance.\n (this._axes as any)._inputs.indexOf(this._axesPinchInput) === -1\n ) {\n this._axes.connect([\"fov\"], this._axesPinchInput);\n }\n }\n }\n\n private _enableTouch(direction: YawPitchControlOptions[\"touchDirection\"]) {\n // Disconnect first\n if (this._axesPanInput) {\n this._axes.disconnect(this._axesPanInput);\n }\n\n const yawEnabled = direction & TOUCH_DIRECTION_YAW ? \"yaw\" : null;\n const pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? \"pitch\" : null;\n\n this._axes.connect([yawEnabled, pitchEnabled] as string[], this._axesPanInput);\n }\n\n private _initDeviceQuaternion() {\n this._deviceQuaternion = new DeviceQuaternion();\n this._deviceQuaternion.on(\"change\", e => {\n this._triggerChange(e);\n });\n }\n\n private _getValidYawRange(newYawRange: number[], newFov?: number, newAspectRatio?: number) {\n const ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1);\n const fov = newFov || this._axes.get().fov;\n const horizontalFov = fov * ratio;\n const isValid = newYawRange[1] - newYawRange[0] >= horizontalFov;\n\n if (isValid) {\n return newYawRange;\n } else {\n return this.options.yawRange || DEFAULT_YAW_RANGE;\n }\n }\n\n private _getValidPitchRange(newPitchRange: number[], newFov?: number) {\n const fov = newFov || this._axes.get().fov;\n const isValid = newPitchRange[1] - newPitchRange[0] >= fov;\n\n if (isValid) {\n return newPitchRange;\n } else {\n return this.options.pitchRange || DEFAULT_PITCH_RANGE;\n }\n }\n\n private _isCircular(range: number[]) {\n return range[1] - range[0] < 360 ? [false, false] : [true, true];\n }\n\n /**\n * Update yaw/pitch min/max by 5 factor\n *\n * 1. showPolePoint\n * 2. fov\n * 3. yawRange\n * 4. pitchRange\n * 5. aspectRatio\n *\n * If one of above is changed, call this function\n */\n private _updateControlScale(changeEvt?: any) { // TODO: Change type after Axes type inference update\n const opt = this.options;\n const fov = this._axes.get().fov;\n\n const pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint);\n const yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio);\n\n // TODO: If not changed!?\n const pos = this._axes.get();\n let y = pos.yaw;\n let p = pos.pitch;\n\n vec2.copy(this._axes.axis.yaw.range as any, yRange as any);\n vec2.copy(this._axes.axis.pitch.range as any, pRange as any);\n this._axes.axis.yaw.circular = this._isCircular(yRange);\n this._axes.axis.pitch.circular = this._isCircular(pRange);\n\n /**\n * update yaw/pitch by it's range.\n */\n if (y < yRange[0]) {\n y = yRange[0];\n } else if (y > yRange[1]) {\n y = yRange[1];\n }\n\n if (p < pRange[0]) {\n p = pRange[0];\n } else if (p > pRange[1]) {\n p = pRange[1];\n }\n\n if (changeEvt) {\n changeEvt.set({\n yaw: y,\n pitch: p\n });\n }\n\n this._axes.setTo({\n yaw: y,\n pitch: p\n }, 0);\n\n return this;\n }\n\n private _updatePitchRange(pitchRange: number[], fov: number, showPolePoint: boolean) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n // Circular pitch on VR\n return CIRCULAR_PITCH_RANGE;\n }\n\n const verticalAngle = pitchRange[1] - pitchRange[0];\n const halfFov = fov / 2;\n const isPanorama = verticalAngle < 180;\n\n if (showPolePoint && !isPanorama) {\n // Use full pinch range\n return pitchRange.concat();\n }\n\n // Round value as movableCood do.\n return [pitchRange[0] + halfFov, pitchRange[1] - halfFov];\n }\n\n private _updateYawRange(yawRange: number[], fov: number, aspectRatio: number) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n return DEFAULT_YAW_RANGE;\n }\n\n const horizontalAngle = yawRange[1] - yawRange[0];\n\n /**\n * Full 360 Mode\n */\n if (horizontalAngle >= 360) {\n // Don't limit yaw range on Full 360 mode.\n return yawRange.concat();\n }\n\n /**\n * Panorama mode\n */\n // Ref : https://github.com/naver/egjs-view360/issues/290\n const halfHorizontalFov =\n mathUtil.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))) as number;\n\n // Round value as movableCood do.\n return [\n yawRange[0] + halfHorizontalFov,\n yawRange[1] - halfHorizontalFov\n ];\n }\n\n // TODO: update param type after Axes event type inference update\n private _triggerChange(evt: any) {\n const pos = this._axes.get();\n const opt = this.options;\n const event: YawPitchControlEvents[\"change\"] extends ComponentEvent ? T : never = {\n targetElement: opt.element as HTMLElement,\n isTrusted: evt.isTrusted,\n yaw: pos.yaw,\n pitch: pos.pitch,\n fov: pos.fov,\n quaternion: null\n };\n\n if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) {\n event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw);\n }\n\n this.trigger(new ComponentEvent(\"change\", event));\n }\n\n // TODO: makes constant to be logic\n private _adjustAspectRatio(input: number) {\n const inputRange = [\n 0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670,\n 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19,\n 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26,\n 2.30, 2.60, 3.00, 5.00, 6.00\n ];\n const outputRange = [\n 0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710,\n 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15,\n 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72,\n 1.82, 1.92, 2.00, 2.24, 2.30\n ];\n\n let rangeIdx = -1;\n\n for (let i = 0; i < inputRange.length - 1; i++) {\n if (inputRange[i] <= input && inputRange[i + 1] >= input) {\n rangeIdx = i;\n break;\n }\n }\n\n if (rangeIdx === -1) {\n if (inputRange[0] > input) {\n return outputRange[0];\n } else {\n // FIXME: this looks definitely wrong\n return outputRange[(outputRange[0] as any).length - 1];\n }\n }\n\n const inputA = inputRange[rangeIdx];\n const inputB = inputRange[rangeIdx + 1];\n const outputA = outputRange[rangeIdx];\n const outputB = outputRange[rangeIdx + 1];\n\n return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA));\n }\n\n private _lerp(a: number, b: number, fraction: number) {\n return a + fraction * (b - a);\n }\n\n private _resetOrientation() {\n const opt = this.options;\n\n this._axes.setTo({\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }, 0);\n\n return this;\n }\n}\n\nexport default YawPitchControl;\n","/**\n * Constant value for gyro mode.
(Reference {@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide})\n * @ko gyro 모드 대한 상수 값.
({@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide} 참고)\n * @namespace\n * @name GYRO_MODE\n * @memberof eg.view360.PanoViewer\n */\n/**\n * Disable gyro\n * @ko gyro 비활성화\n * @name NONE\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"none\"\n */\n/**\n * YawPitch Mode\n * @ko YawPitch Mode\n * @name YAWPITCH\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"yawPitch\"\n */\n/**\n * VR Mode\n * @ko VR Mode\n * @name VR\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"VR\"\n */\nimport { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\nimport { GYRO_MODE } from \"../YawPitchControl/consts\";\n\n/**\n * Constant value for errors\n * @ko 에러에 대한 상수 값\n * @namespace\n * @name ERROR_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst ERROR_TYPE = {\n /**\n * Unsupported device\n * @ko 미지원 기기\n * @name INVALID_DEVICE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 10\n */\n INVALID_DEVICE: 10,\n /**\n * Webgl not support\n * @ko WEBGL 미지원\n * @name NO_WEBGL\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 11\n */\n NO_WEBGL: 11,\n /**\n * Failed to load image\n * @ko 이미지 로드 실패\n * @name FAIL_IMAGE_LOAD\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 12\n */\n FAIL_IMAGE_LOAD: 12,\n /**\n * Failed to bind texture\n * @ko 텍스쳐 바인딩 실패\n * @name FAIL_BIND_TEXTURE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 13\n */\n FAIL_BIND_TEXTURE: 13,\n /**\n * Only one resource(image or video) should be specified\n * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함)\n * @name INVALID_RESOURCE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 14\n */\n INVALID_RESOURCE: 14,\n /**\n * WebGL context lost occurred\n * @ko WebGL context lost 발생\n * @name RENDERING_CONTEXT_LOST\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 15\n */\n RENDERING_CONTEXT_LOST: 15\n};\n\n/**\n * Constant value for events\n * @ko 이벤트에 대한 상수 값\n * @namespace\n * @name EVENTS\n * @memberof eg.view360.PanoViewer\n */\nconst PANOVIEWER_EVENTS: {\n READY: \"ready\";\n VIEW_CHANGE: \"viewChange\";\n ANIMATION_END: \"animationEnd\";\n ERROR: \"error\";\n} = {\n /**\n * Events that is fired when PanoViewer is ready to show image and handle user interaction.\n * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트\n * @name READY\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default ready\n */\n READY: \"ready\",\n /**\n * Events that is fired when direction or fov is changed.\n * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트\n * @name VIEW_CHANGE\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default viewChange\n */\n VIEW_CHANGE: \"viewChange\",\n /**\n * Events that is fired when animation which is triggered by inertia is ended.\n * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트\n * @name ANIMATION_END\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default animationEnd\n */\n ANIMATION_END: \"animationEnd\",\n /**\n * Events that is fired when error occurs\n * @ko 에러 발생 시 발생하는 이벤트\n * @name ERROR\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default error\n */\n ERROR: \"error\"\n};\n\n/**\n * Constant value for projection type\n * @ko 프로젝션 타입 대한 상수 값\n * @namespace\n * @name PROJECTION_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst PROJECTION_TYPE: {\n EQUIRECTANGULAR: \"equirectangular\";\n CUBEMAP: \"cubemap\";\n CUBESTRIP: \"cubestrip\";\n PANORAMA: \"panorama\";\n STEREOSCOPIC_EQUI: \"stereoequi\";\n} = {\n /**\n * Constant value for equirectangular type.\n * @ko equirectangular 에 대한 상수 값.\n * @name EQUIRECTANGULAR\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default equirectangular\n */\n EQUIRECTANGULAR: \"equirectangular\",\n /**\n * Constant value for cubemap type.\n * @ko cubemap 에 대한 상수 값.\n * @name CUBEMAP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubemap\n */\n CUBEMAP: \"cubemap\",\n /**\n * Constant value for cubestrip type.\n * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC.\n * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다.\n * @name CUBESTRIP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubestrip\n */\n CUBESTRIP: \"cubestrip\",\n /**\n * Constant value for PANORAMA type.\n *\n * PANORAMA is a format for a panorma image which is taken from smartphone.\n * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다.\n *\n * @name PANORAMA\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default panorama\n */\n PANORAMA: \"panorama\",\n /**\n * Constant value for EQUI_STEREOSCOPY type.\n *\n * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present.\n * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다.\n *\n * @name STEREOSCOPIC_EQUI\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default stereoequi\n */\n STEREOSCOPIC_EQUI: \"stereoequi\"\n};\n\n/**\n * A constant value for the format of the stereoscopic equirectangular projection type.\n * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값\n * @namespace\n * @name STEREO_FORMAT\n * @memberof eg.view360.PanoViewer\n */\nconst STEREO_FORMAT: {\n TOP_BOTTOM: \"3dv\";\n LEFT_RIGHT: \"3dh\";\n NONE: \"\";\n} = {\n /**\n * A constant value for format of top bottom stereoscopic 360 equirectangular projection.\n * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name TOP_BOTTOM\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dv\"\n */\n TOP_BOTTOM: \"3dv\",\n /**\n * A constant value for format of left right stereoscopic 360 equirectangular projection.\n * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name LEFT_RIGHT\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dh\"\n */\n LEFT_RIGHT: \"3dh\",\n /**\n * A constant value specifying media is not in stereoscopic format.\n * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"\"\n */\n NONE: \"\"\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst PANOVIEWER_OPTIONS: { [key in keyof PanoViewerOptions]: true } = {\n image: true,\n video: true,\n projectionType: true,\n cubemapConfig: true,\n stereoFormat: true,\n width: true,\n height: true,\n yaw: true,\n pitch: true,\n fov: true,\n showPolePoint: true,\n useZoom: true,\n useKeyboard: true,\n gyroMode: true,\n yawRange: true,\n pitchRange: true,\n fovRange: true,\n touchDirection: true,\n canvasClass: true\n};\n\nconst DEFAULT_CANVAS_CLASS = \"view360-canvas\";\n\nexport {\n GYRO_MODE,\n PANOVIEWER_EVENTS,\n ERROR_TYPE,\n PROJECTION_TYPE,\n STEREO_FORMAT,\n PANOVIEWER_OPTIONS,\n DEFAULT_CANVAS_CLASS\n};\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","import agent from \"@egjs/agent\";\n\nimport { TypedArray } from \"../types/internal\";\n\nconst WEBGL_ERROR_CODE = {\n \"0\": \"NO_ERROR\",\n \"1280\": \"INVALID_ENUM\",\n \"1281\": \"INVALID_VALUE\",\n \"1282\": \"INVALID_OPERATION\",\n \"1285\": \"OUT_OF_MEMORY\",\n \"1286\": \"INVALID_FRAMEBUFFER_OPERATION\",\n \"37442\": \"CONTEXT_LOST_WEBGL\"\n};\n\nlet webglAvailability: boolean | null = null;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet MAX_TEXTURE_SIZE_FOR_TEST: number | null = null;\n\nexport default class WebGLUtils {\n public static createShader(gl: WebGLRenderingContext, type: number, source: string) {\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (success) {\n return shader;\n }\n\n // eslint-disable-next-line\n console.error(gl.getShaderInfoLog(shader));\n\n return null;\n }\n\n public static createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = gl.createProgram()!;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (success) {\n return program;\n }\n\n gl.deleteProgram(program);\n return null;\n }\n\n public static initBuffer(gl: WebGLRenderingContext, target: number /* bind point */, data: TypedArray, itemSize: number, attr?: number) {\n const buffer = gl.createBuffer()!;\n\n gl.bindBuffer(target, buffer);\n gl.bufferData(target, data, gl.STATIC_DRAW);\n\n if (buffer) {\n (buffer as any).itemSize = itemSize;\n (buffer as any).numItems = data.length / itemSize;\n }\n\n if (attr !== undefined) {\n gl.enableVertexAttribArray(attr);\n gl.vertexAttribPointer(attr, (buffer as any).itemSize, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n }\n\n public static getWebglContext(canvas: HTMLCanvasElement, userContextAttributes?: WebGLContextAttributes) {\n const webglIdentifiers = [\"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n const contextAttributes = {\n ...{\n preserveDrawingBuffer: false,\n antialias: false\n }, ...userContextAttributes\n };\n\n const onWebglcontextcreationerror = e => e.statusMessage;\n\n canvas.addEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n return context;\n }\n\n public static createTexture(gl: WebGLRenderingContext, textureTarget: number) {\n const texture = gl.createTexture();\n\n gl.bindTexture(textureTarget, texture);\n gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(textureTarget, null);\n\n return texture;\n }\n\n /**\n * Returns the webgl availability of the current browser.\n * @method WebGLUtils#isWebGLAvailable\n * @retuen {Boolean} isWebGLAvailable\n */\n public static isWebGLAvailable(): boolean {\n if (webglAvailability === null) {\n const canvas = document.createElement(\"canvas\");\n const webglContext = WebGLUtils.getWebglContext(canvas);\n\n webglAvailability = !!webglContext;\n\n // webglContext Resource forced collection\n if (webglContext) {\n const loseContextExtension = webglContext.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n return !!webglAvailability;\n }\n\n /**\n * Returns whether webgl is stable in the current browser.\n * @method WebGLUtils#isStableWebGL\n * @retuen {Boolean} isStableWebGL\n */\n public static isStableWebGL() {\n const agentInfo = agent();\n let isStableWebgl = true;\n\n if (agentInfo.os.name === \"android\") {\n const version = parseFloat(agentInfo.os.version);\n\n if (version <= 4.3 && version >= 1) {\n isStableWebgl = false;\n } else if (version === 4.4) {\n if (agentInfo.browser.name !== \"chrome\") {\n isStableWebgl = false;\n }\n }\n }\n return isStableWebgl;\n }\n\n public static getErrorNameFromWebGLErrorCode(code: number | string) {\n if (!(code in WEBGL_ERROR_CODE)) {\n return \"UNKNOWN_ERROR\";\n }\n\n return WEBGL_ERROR_CODE[code];\n }\n\n\n /**\n * This function is wrapper for texImage2D to handle exceptions on texImage2D.\n * Purpose is to prevent service from being stopped by script error.\n */\n public static texImage2D(gl: WebGLRenderingContext, target: number, pixels: TexImageSource) {\n try {\n gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n } catch (error) {\n /* eslint-disable no-console */\n console.error(\"WebGLUtils.texImage2D error:\", error);\n /* eslint-enable no-console */\n }\n }\n\n public static getMaxTextureSize(gl: WebGLRenderingContext) {\n // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test\n return MAX_TEXTURE_SIZE_FOR_TEST || gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n}\n\n/**\n * This function should not be used in service code. It's provided only for test purpose.\n * It should be set to null or 0 when test is done.\n * @param {Number} size\n */\nconst setMaxTextureSizeForTestOnlyPurpose = (size: number) => {\n MAX_TEXTURE_SIZE_FOR_TEST = size;\n};\n\nexport {\n setMaxTextureSizeForTestOnlyPurpose\n};\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport agent from \"@egjs/agent\";\nimport { mat4 } from \"gl-matrix\";\n\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nconst agentInfo = agent();\nconst isIE11 = agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11;\n\nconst EVENTS: {\n ERROR: \"error\";\n} = {\n ERROR: \"error\"\n};\n\n/**\n *\n * Extends Component for firing errors occurs internally.\n */\nabstract class Renderer extends Component<{\n [EVENTS.ERROR]: {\n message: string;\n };\n}> {\n public static EVENTS = EVENTS;\n\n private _forceDimension: { width: number; height: number } | null;\n private _pixelCanvas: HTMLCanvasElement | null;\n private _pixelContext: CanvasRenderingContext2D | null;\n\n public constructor() {\n super();\n\n this._forceDimension = null;\n this._pixelCanvas = null;\n this._pixelContext = null;\n }\n\n public abstract getVertexPositionData(): number[];\n public abstract getIndexData(): number[];\n public abstract getTextureCoordData(textureData: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }): number[];\n\n public abstract getVertexShaderSource(): string;\n public abstract getFragmentShaderSource(): string;\n public abstract bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n public abstract updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n\n public render({ gl, shaderProgram, indexBuffer, mvMatrix, pMatrix }: {\n gl: WebGLRenderingContext;\n shaderProgram: WebGLProgram;\n indexBuffer: WebGLBuffer;\n mvMatrix: mat4;\n pMatrix: mat4;\n }) {\n gl.uniformMatrix4fv((shaderProgram as any).pMatrixUniform, false, pMatrix);\n gl.uniformMatrix4fv((shaderProgram as any).mvMatrixUniform, false, mvMatrix);\n\n if (indexBuffer) {\n gl.drawElements(gl.TRIANGLES, (indexBuffer as any).numItems, gl.UNSIGNED_SHORT, 0);\n }\n }\n\n // Define interface for Renderers\n /**\n * Following MUST BE DEFINED on Child of Renderer\n *\n * DATA\n *\n * - getVertexPositionData\n * - getIndexData\n * - getTextureCoordData\n *\n * SOURCE\n *\n * - getVertexShaderSource\n * - getFragmentShaderSource\n *\n * TEXTURE\n *\n * - bindTexture\n */\n public getDimension(pixelSource: HTMLImageElement | HTMLVideoElement) {\n const width = (pixelSource as HTMLImageElement).naturalWidth\n || (pixelSource as HTMLVideoElement).videoWidth;\n const height = (pixelSource as HTMLImageElement).naturalHeight\n || (pixelSource as HTMLVideoElement).videoHeight;\n\n return { width, height };\n }\n\n /**\n * Update data used by shader\n */\n public updateShaderData(param) { // eslint-disable-line @typescript-eslint/no-unused-vars\n /*\n * Update following data in implementation layer.\n * If the data is not changed, it does not need to implement this function.\n *\n * - _VERTEX_POSITION_DATA\n * - _TEXTURE_COORD_DATA\n * - _INDEX_DATA\n */\n }\n\n /**\n *\n * @param {HTMLImageElement | HTMLVideoElement} image\n * @param {Object = {width, height}} forceDimension Forced dimension to resize\n */\n protected _initPixelSource(image: HTMLImageElement | HTMLVideoElement, forceDimension: Renderer[\"_forceDimension\"] = null) {\n const isIE11Video = isIE11 && (image instanceof HTMLVideoElement);\n\n if (isIE11Video || forceDimension) {\n const {width, height} = forceDimension || this.getDimension(image);\n\n this._pixelCanvas = document.createElement(\"canvas\");\n this._pixelCanvas.width = width;\n this._pixelCanvas.height = height;\n this._pixelContext = this._pixelCanvas.getContext(\"2d\");\n }\n this._forceDimension = forceDimension;\n }\n\n protected _getPixelSource(image: HTMLImageElement | HTMLVideoElement) {\n if (!this._pixelCanvas) {\n return image;\n }\n\n /**\n * IE11 && Video\n * or\n * Dimension is forced (Image is larger than texture size.)\n */\n const contentDimension = this.getDimension(image);\n const textureDimension = this._forceDimension || contentDimension;\n\n if (this._pixelCanvas.width !== textureDimension.width) {\n this._pixelCanvas.width = textureDimension.width;\n }\n\n if (this._pixelCanvas.height !== textureDimension.height) {\n this._pixelCanvas.height = textureDimension.height;\n }\n\n if (this._forceDimension) {\n this._pixelContext!.drawImage(image,\n 0, 0, contentDimension.width, contentDimension.height,\n 0, 0, textureDimension.width, textureDimension.height);\n } else {\n this._pixelContext!.drawImage(image, 0, 0);\n }\n\n return this._pixelCanvas;\n }\n\n protected _extractTileConfig(imageConfig: CubemapConfig) {\n let tileConfig: TileConfig[] =\n Array.isArray(imageConfig.tileConfig) ?\n imageConfig.tileConfig : Array(...Array(6)).map(() => imageConfig.tileConfig) as TileConfig[];\n\n tileConfig = tileConfig.map(\n config => ({\n ...{\n flipHorizontal: false,\n rotation: 0\n }, ...config\n })\n );\n\n return tileConfig;\n }\n\n protected _triggerError(error) {\n /* eslint-disable no-console */\n console.error(\"Renderer Error:\", error);\n /* eslint-enable no-console */\n\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n message: typeof error === \"string\" ? error : error.message\n }));\n }\n}\n\nexport default Renderer;\n","import agent from \"@egjs/agent\";\n\nimport WebGLUtils from \"../WebGLUtils\";\nimport { util as mathUtil } from \"../../utils/math-util\";\nimport { CubemapConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nclass CubeRenderer extends Renderer {\n public static extractOrder(imageConfig: CubemapConfig) {\n return imageConfig.order || \"RLUDBF\";\n }\n\n private static _VERTEX_POSITION_DATA: number[] | null = null;\n private static _INDEX_DATA: number[] | null = null;\n\n public getVertexPositionData() {\n CubeRenderer._VERTEX_POSITION_DATA =\n CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // top\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // bottom\n 1, -1, -1,\n -1, -1, -1,\n -1, -1, 1,\n 1, -1, 1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n return CubeRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n if (CubeRenderer._INDEX_DATA) {\n return CubeRenderer._INDEX_DATA;\n }\n\n const indexData: number[] = [];\n const vertexPositionData = this.getVertexPositionData();\n\n for (let i = 0; i < (vertexPositionData.length / 3); i += 4) {\n indexData.push(\n i,\n i + 2,\n i + 1,\n i,\n i + 3,\n i + 2\n );\n }\n\n CubeRenderer._INDEX_DATA = indexData;\n return indexData;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n const vertexOrder = \"BFUDRL\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const base = this.getVertexPositionData();\n const tileConfig = this._extractTileConfig(imageConfig);\n const elemSize = 3;\n const vertexPerTile = 4;\n const { trim } = imageConfig;\n\n const texCoords = vertexOrder.split(\"\")\n .map(face => tileConfig[order.indexOf(face)])\n .map((config, i) => {\n const rotation = Math.floor(config.rotation / 90);\n const ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2];\n\n for (let r = 0; r < Math.abs(rotation); r++) {\n if ((config.flipHorizontal && rotation > 0) ||\n (!config.flipHorizontal && rotation < 0)) {\n ordermap.push(ordermap.shift()!);\n } else {\n ordermap.unshift(ordermap.pop()!);\n }\n }\n\n const elemPerTile = elemSize * vertexPerTile;\n const tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile);\n const tileTemp: number[][] = [];\n\n for (let j = 0; j < vertexPerTile; j++) {\n tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize);\n }\n return tileTemp;\n })\n .map(coord => this._shrinkCoord({ image, faceCoords: coord, trim }))\n .reduce((acc: number[], val: number[][]) => [\n ...acc,\n ...val.reduce((coords, coord) => [...coords, ...coord], [])\n ], []);\n\n return texCoords;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n const baseOrder = \"RLUDBF\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const orderMap = {};\n\n order.split(\"\").forEach((v, i) => {\n orderMap[v] = i;\n });\n\n try {\n if (image instanceof Array) {\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]);\n }\n } else {\n const maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image);\n\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n const tile = this.extractTileFromImage(\n image, tileIdx, maxCubeMapTextureSize\n );\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile);\n }\n }\n } catch (e) {\n this._triggerError(e);\n }\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n this.updateTexture(gl, image, imageConfig);\n }\n\n public getSourceTileSize(image: HTMLImageElement | HTMLVideoElement) {\n const {width, height} = this.getDimension(image);\n const aspectRatio = width / height;\n let inputTextureSize;\n\n if (aspectRatio === 1 / 6) {\n inputTextureSize = width;\n } else if (aspectRatio === 6) {\n inputTextureSize = height;\n } else if (aspectRatio === 2 / 3) {\n inputTextureSize = width / 2;\n } else {\n inputTextureSize = width / 3;\n }\n return inputTextureSize;\n }\n\n public extractTileFromImage(image: HTMLImageElement | HTMLVideoElement, tileIdx: number, outputTextureSize: number) {\n const {width} = this.getDimension(image);\n const inputTextureSize = this.getSourceTileSize(image);\n\n const canvas = document.createElement(\"canvas\");\n\n canvas.width = outputTextureSize;\n canvas.height = outputTextureSize;\n const context = canvas.getContext(\"2d\");\n const tilePerRow = width / inputTextureSize;\n\n const x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow);\n const y = Math.floor(tileIdx / tilePerRow) * (inputTextureSize);\n\n context!.drawImage(\n image, x, y,\n inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize\n );\n return canvas;\n }\n\n public getMaxCubeMapTextureSize(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n const agentInfo = agent();\n const maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n let imageWidth = this.getSourceTileSize(image);\n\n if (agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11) {\n if (!mathUtil.isPowerOfTwo(imageWidth)) {\n for (let i = 1; i < maxCubeMapTextureSize; i *= 2) {\n if (i < imageWidth) {\n continue;\n } else {\n imageWidth = i;\n break;\n }\n }\n }\n }\n if (agentInfo.os.name === \"ios\") {\n const majorVersion = agentInfo.os.majorVersion;\n\n // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다.\n if (majorVersion === 9) {\n imageWidth = 1024;\n }\n // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다.\n if (majorVersion === 8) {\n imageWidth = 512;\n }\n }\n // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수\n return Math.min(maxCubeMapTextureSize, imageWidth);\n }\n\n private _shrinkCoord(coordData: {\n image: HTMLImageElement | HTMLVideoElement;\n faceCoords: number[][];\n trim: number;\n }) {\n const { image, faceCoords, trim } = coordData;\n\n const inputTextureSize = Array.isArray(image)\n ? this.getDimension(image[0]).width\n : this.getSourceTileSize(image);\n\n // Shrink by \"trim\" px\n const SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize);\n\n const axisMultipliers = [0, 1, 2].map(axisIndex => {\n const axisDir = mathUtil.sign(faceCoords[0][axisIndex]);\n const notSameDir = faceCoords.some(coord => mathUtil.sign(coord[axisIndex]) !== axisDir);\n\n return notSameDir;\n }).map(notSameDir => notSameDir ? SHRINK_MULTIPLIER : 1);\n\n return faceCoords.map(coords => coords.map((coord, axisIndex) => coord * axisMultipliers[axisIndex]));\n }\n}\n\nexport default CubeRenderer;\n","\nimport WebGLUtils from \"../WebGLUtils\";\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nexport default class CubeStripRenderer extends Renderer {\n private _vertices: number[];\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}`;\n }\n\n public getVertexPositionData() {\n if (!this._vertices) {\n this._vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n }\n\n return this._vertices;\n }\n\n public getIndexData() {\n // TODO: 한번만 계산하도록 수정하기\n const indices = (() => {\n const indexData: number[] = [];\n\n for (let i = 0; i < (this._vertices.length / 3); i += 4) {\n indexData.push(\n i,\n i + 1,\n i + 2,\n i,\n i + 2,\n i + 3\n );\n }\n return indexData;\n })();\n\n return indices;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n // TODO: make it cols, rows as config.\n const cols = 3;\n const rows = 2;\n\n const textureSize = this.getDimension(image);\n const { trim } = imageConfig;\n\n const order = imageConfig.order || \"RLUDFB\";\n let coords: number[][] = [];\n\n // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다.\n for (let r = rows - 1; r >= 0; r--) {\n for (let c = 0; c < cols; c++) {\n const coord = [\n c / cols, r / rows,\n (c + 1) / cols, r / rows,\n (c + 1) / cols, (r + 1) / rows,\n c / cols, (r + 1) / rows\n ];\n\n coords.push(coord);\n }\n }\n\n const tileConfigs = this._extractTileConfig(imageConfig);\n\n // Transform Coord By Flip & Rotation\n coords = coords\n // shrink coord to avoid pixel bleeding\n .map(coord => this._shrinkCoord(coord, textureSize, trim))\n .map((coord, i) => this._transformCoord(coord, tileConfigs[i]));\n\n // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치\n return \"BFUDRL\".split(\"\")\n .map(face => order.indexOf(face))\n .map(index => coords[index])\n .reduce((acc, val) => acc.concat(val), []);\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n private _transformCoord(coord: number[], tileConfig: TileConfig) {\n let newCoord = coord.slice();\n\n if (tileConfig.flipHorizontal) {\n newCoord = this._flipHorizontalCoord(newCoord);\n }\n\n if (tileConfig.rotation) {\n newCoord = this._rotateCoord(newCoord, tileConfig.rotation);\n }\n\n return newCoord;\n }\n\n private _shrinkCoord(coord: number[], textureSize: { width: number; height: number }, trim: number) {\n const { width, height } = textureSize;\n\n // Shrink by \"trim\" px\n const SHRINK_Y = trim * (1 / height);\n const SHRINK_X = trim * (1 / width);\n\n return [\n coord[0] + SHRINK_X, coord[1] + SHRINK_Y,\n coord[2] - SHRINK_X, coord[3] + SHRINK_Y,\n coord[4] - SHRINK_X, coord[5] - SHRINK_Y,\n coord[6] + SHRINK_X, coord[7] - SHRINK_Y\n ];\n }\n\n private _rotateCoord(coord: number[], rotationAngle: number) {\n const SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord.\n const shiftCount = Math.floor(rotationAngle / 90) % 4;\n\n if (shiftCount === 0) {\n return coord;\n }\n\n let moved;\n let rotatedCoord: number[] = [];\n\n if (shiftCount > 0) {\n moved = coord.splice(0, shiftCount * SIZE);\n rotatedCoord = coord.concat(moved);\n } else {\n moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE);\n rotatedCoord = moved.concat(coord);\n }\n\n return rotatedCoord;\n }\n\n private _flipHorizontalCoord(coord: number[]) {\n return [\n coord[2], coord[3],\n coord[0], coord[1],\n coord[6], coord[7],\n coord[4], coord[5]\n ];\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport WebGLUtils from \"../WebGLUtils\";\n\nimport Renderer from \"./Renderer\";\n\n// const latitudeBands = 60;\nconst MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6;\nconst longitudeBands = 60;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\n\nclass CylinderRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n public getVertexPositionData() {\n return CylinderRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return CylinderRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return CylinderRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n let resizeDimension: { width: number; height: number } | undefined;\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device texture limit(${maxSize}))`);\n\n // Request resizing texture.\n /**\n * TODO: Is it need to apply on another projection type?\n */\n resizeDimension = width > height ?\n {width: maxSize, height: maxSize * height / width} :\n {width: maxSize * width / height, height: maxSize};\n }\n\n // Pixel Source for IE11 & Video or resizing needed\n this._initPixelSource(image, resizeDimension);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n public updateShaderData({ imageAspectRatio = MIN_ASPECT_RATIO_FOR_FULL_PANORAMA }) {\n let lngIdx: number;\n let cylinderMaxRadian: number;\n let halfCylinderY: number;\n let rotated: boolean;\n let aspectRatio: number;\n\n // Exception case: orientation is rotated.\n if (imageAspectRatio < 1) {\n /**\n * If rotated is true, we assume that image is rotated counter clockwise.\n * TODO: If there's other rotation, it is need to implement by each rotation.\n */\n rotated = true;\n aspectRatio = 1 / imageAspectRatio;\n } else {\n rotated = false;\n aspectRatio = imageAspectRatio;\n }\n\n if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) {\n const fov = 360 / aspectRatio;\n\n cylinderMaxRadian = 2 * Math.PI; // 360 deg\n halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2));\n } else {\n cylinderMaxRadian = aspectRatio;\n halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1.\n }\n\n // initialize shader data before update\n textureCoordData.length = 0;\n vertexPositionData.length = 0;\n indexData.length = 0;\n\n const CYLIDER_Y = [-halfCylinderY, halfCylinderY];\n const startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360)\n\n // console.log(\"cylinderMaxRadian:\", glMatrix.toDegree(cylinderMaxRadian), \"CYLIDER_Y\", CYLIDER_Y, \"start angle\", glMatrix.toDegree(startAngleForCenterAlign));\n for (let yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength/* bottom & top */; yIdx++) {\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const angle = startAngleForCenterAlign + (lngIdx / longitudeBands * cylinderMaxRadian);\n const x = Math.cos(angle);\n const y = CYLIDER_Y[yIdx];\n const z = Math.sin(angle);\n let u: number;\n let v: number;\n\n if (rotated) {\n // Rotated 90 degree (counter clock wise)\n u = 1 - yIdx; // yLength - yIdx;\n v = lngIdx / longitudeBands;\n } else {\n // \t// Normal case (Not rotated)\n u = lngIdx / longitudeBands;\n v = yIdx;\n }\n\n textureCoordData.push(u, v);\n vertexPositionData.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < longitudeBands) {\n const a = lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n }\n}\n\nexport default CylinderRenderer;\n","import Promise from \"promise-polyfill\";\nimport { mat4 } from \"gl-matrix\";\n\nconst VR_DISPLAY_PRESENT_CHANGE = \"vrdisplaypresentchange\";\nconst DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1];\nconst DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1];\nconst EYES = {\n LEFT: \"left\",\n RIGHT: \"right\"\n} as const;\n\nclass VRManager {\n private _vrDisplay: VRDisplay | null;\n private _frameData: VRFrameData;\n private _yawOffset: number;\n private _leftBounds: number[];\n private _rightBounds: number[];\n\n public constructor() {\n this._frameData = new window.VRFrameData();\n this._clear();\n }\n\n public get context() { return this._vrDisplay; }\n\n public destroy = () => {\n const vrDisplay = this._vrDisplay;\n\n this.removeEndCallback(this.destroy);\n\n if (vrDisplay && vrDisplay.isPresenting) {\n void vrDisplay.exitPresent();\n }\n\n this._clear();\n };\n\n public canRender() {\n return Boolean(this._vrDisplay);\n }\n\n public beforeRender(gl: WebGLRenderingContext) {\n // Render to the default backbuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public afterRender() {\n this._vrDisplay!.submitFrame();\n }\n\n public getEyeParams(gl: WebGLRenderingContext) {\n const display = this._vrDisplay!;\n const halfWidth = gl.drawingBufferWidth * 0.5;\n const height = gl.drawingBufferHeight;\n const frameData = this._frameData;\n\n display.getFrameData(frameData);\n\n const leftMVMatrix = frameData.leftViewMatrix;\n const rightMVMatrix = frameData.rightViewMatrix;\n\n mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset);\n mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset);\n\n return [\n {\n viewport: [0, 0, halfWidth, height],\n mvMatrix: leftMVMatrix,\n pMatrix: frameData.leftProjectionMatrix\n },\n {\n viewport: [halfWidth, 0, halfWidth, height],\n mvMatrix: rightMVMatrix,\n pMatrix: frameData.rightProjectionMatrix\n }\n ];\n }\n\n public isPresenting() {\n return Boolean(this._vrDisplay && this._vrDisplay.isPresenting);\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public requestPresent(canvas: HTMLCanvasElement) {\n return navigator.getVRDisplays().then(displays => {\n const vrDisplay = displays.length && displays[0];\n\n if (!vrDisplay) {\n return Promise.reject(new Error(\"No displays available.\"));\n }\n if (!vrDisplay.capabilities.canPresent) {\n return Promise.reject(new Error(\"Display lacking capability to present.\"));\n }\n\n return vrDisplay.requestPresent([{source: canvas}]).then(() => {\n const leftEye = vrDisplay.getEyeParameters(EYES.LEFT);\n const rightEye = vrDisplay.getEyeParameters(EYES.RIGHT);\n\n canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;\n canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);\n\n this._setDisplay(vrDisplay);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setDisplay(vrDisplay: VRDisplay) {\n this._vrDisplay = vrDisplay;\n\n const layers = vrDisplay.getLayers();\n\n if (layers.length) {\n const layer = layers[0];\n\n this._leftBounds = layer.leftBounds as number[];\n this._rightBounds = layer.rightBounds as number[];\n }\n\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._vrDisplay = null;\n this._leftBounds = DEFAULT_LEFT_BOUNDS;\n this._rightBounds = DEFAULT_RIGHT_BOUNDS;\n this._yawOffset = 0;\n }\n}\n\nexport default VRManager;\n","import { mat4, glMatrix } from \"gl-matrix\";\nimport { XRFrame, XRLayer, XRReferenceSpace, XRSession, XRSessionInit } from \"webxr\";\n\nimport { IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { merge } from \"../../utils/utils\";\n\nconst XR_REFERENCE_SPACE = \"local\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\nclass XRManager {\n private _xrSession: XRSession | null;\n private _xrLayer: XRLayer | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n private _yawOffset: number;\n private _presenting: boolean;\n\n public constructor(options: XRSessionOptions = {}) {\n this._clear();\n this._options = options;\n }\n\n public get context() { return this._xrSession; }\n\n public destroy = () => {\n const xrSession = this._xrSession;\n\n this.removeEndCallback(this.destroy);\n\n if (xrSession) {\n // Capture to avoid errors\n xrSession.end().then(() => void 0, () => void 0);\n }\n this._clear();\n };\n\n public canRender(frame: XRFrame) {\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n return Boolean(pose);\n }\n\n public beforeRender(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer!.framebuffer);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n public afterRender() {}\n\n public getEyeParams(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) {\n // Can't render\n return null;\n }\n\n const glLayer = session.renderState.baseLayer;\n\n return pose.views.map(view => {\n const viewport = glLayer!.getViewport(view);\n const mvMatrix = view.transform.inverse.matrix;\n\n if (IS_SAFARI_ON_DESKTOP) {\n mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180));\n }\n\n mat4.rotateY(mvMatrix, mvMatrix, this._yawOffset);\n\n return {\n viewport: [viewport.x, viewport.y, viewport.width, viewport.height],\n mvMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n public isPresenting() {\n return this._presenting;\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.addEventListener(\"end\", callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.removeEventListener(\"end\", callback);\n }\n\n public async requestPresent(canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {\n const options = merge({\n requiredFeatures: [XR_REFERENCE_SPACE]\n }, this._options);\n\n const attributes = gl.getContextAttributes();\n if (attributes && (attributes as any).xrCompatible !== true) {\n await (gl as any).makeXRCompatible();\n }\n\n return (navigator as any).xr.requestSession(\"immersive-vr\", options).then(session => {\n const xrLayer = new (window as any).XRWebGLLayer(session, gl);\n\n session.updateRenderState({baseLayer: xrLayer});\n return session.requestReferenceSpace(XR_REFERENCE_SPACE)\n .then(refSpace => {\n this._setSession(session, xrLayer, refSpace);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setSession(session: XRSession, xrLayer: XRLayer, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrLayer = xrLayer;\n this._xrRefSpace = refSpace;\n this._presenting = true;\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._xrSession = null;\n this._xrLayer = null;\n this._xrRefSpace = null;\n this._presenting = false;\n this._yawOffset = 0;\n this._options = {};\n }\n}\n\nexport default XRManager;\n","import { IS_SAFARI_ON_DESKTOP } from \"../utils/browser\";\n\nclass WebGLAnimator {\n private _callback: ((...args: any[]) => any) | null;\n private _context: any;\n private _rafId: number;\n private _rafTimer: number;\n\n public constructor() {\n this._callback = null;\n this._context = window;\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public setCallback(callback: (...args: any[]) => any) {\n this._callback = callback;\n }\n\n public setContext(context: any) {\n this._context = context;\n }\n\n public start() {\n const context = this._context;\n const callback = this._callback;\n\n // No context / callback set\n if (!context || !callback) return;\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n if (IS_SAFARI_ON_DESKTOP) {\n this._rafId = context.requestAnimationFrame(this._onLoopNextTick);\n } else {\n this._rafId = context.requestAnimationFrame(this._onLoop);\n }\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n /**\n * There can be more than 1 argument when we use XRSession's raf\n */\n private _onLoop = (...args: any[]) => {\n this._callback!(...args);\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n };\n\n /**\n * MacOS X Safari Bug Fix\n * This code guarantees that rendering should be occurred.\n *\n * In MacOS X(10.14.2), Safari (12.0.2)\n * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term\n * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms)\n * So browser cannot render the frame and may be freezing.\n */\n private _onLoopNextTick = (...args: any[]) => {\n const before = performance.now();\n\n this._callback!(...args);\n\n const diff = performance.now() - before;\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n this._rafTimer = -1;\n }\n\n /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */\n if (diff < 16) {\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n } else {\n /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */\n this._rafTimer = window.setTimeout(this._onLoop, 0);\n }\n };\n}\n\nexport default WebGLAnimator;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { XRFrame } from \"webxr\";\nimport Promise from \"promise-polyfill\";\nimport { glMatrix, vec3, mat3, mat4, quat } from \"gl-matrix\";\nimport ImReady, { OnReady } from \"@egjs/imready\";\n\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { devicePixelRatio, WEBXR_SUPPORTED } from \"../utils/browserFeature\";\nimport { PROJECTION_TYPE, STEREO_FORMAT } from \"../PanoViewer/consts\";\nimport { IS_IOS } from \"../utils/browser\";\nimport { CubemapConfig, ImageCandidate, ValueOf, VideoCandidate } from \"../types/internal\";\nimport YawPitchControl from \"../YawPitchControl/YawPitchControl\";\nimport { toImageElement, toVideoElement } from \"../utils/utils\";\n\nimport WebGLUtils from \"./WebGLUtils\";\nimport Renderer from \"./renderer/Renderer\";\nimport CubeRenderer from \"./renderer/CubeRenderer\";\nimport CubeStripRenderer from \"./renderer/CubeStripRenderer\";\nimport SphereRenderer from \"./renderer/SphereRenderer\";\nimport CylinderRenderer from \"./renderer/CylinderRenderer\";\nimport VRManager from \"./vr/VRManager\";\nimport XRManager from \"./vr/XRManager\";\nimport WebGLAnimator from \"./WebGLAnimator\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ImageType = PROJECTION_TYPE;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet DEVICE_PIXEL_RATIO = devicePixelRatio || 1;\n\n// DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다.\nif (DEVICE_PIXEL_RATIO > 2) {\n DEVICE_PIXEL_RATIO = 2;\n}\n\n// define custom events name\n/**\n * TODO: how to manage events/errortype with PanoViewer\n *\n * I think renderer events should be seperated from viewer events although it has same name.\n */\nconst EVENTS: {\n BIND_TEXTURE: \"bindTexture\";\n IMAGE_LOADED: \"imageLoaded\";\n ERROR: \"error\";\n RENDERING_CONTEXT_LOST: \"renderingContextLost\";\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\";\n} = {\n BIND_TEXTURE: \"bindTexture\",\n IMAGE_LOADED: \"imageLoaded\",\n ERROR: \"error\",\n RENDERING_CONTEXT_LOST: \"renderingContextLost\",\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\"\n};\n\nconst ERROR_TYPE = {\n INVALID_DEVICE: 10,\n NO_WEBGL: 11,\n FAIL_IMAGE_LOAD: 12,\n RENDERER_ERROR: 13\n};\n\nclass PanoImageRenderer extends Component<{\n [EVENTS.ERROR]: {\n type: number;\n message: string;\n };\n [EVENTS.IMAGE_LOADED]: {\n content: HTMLElement;\n isVideo: boolean;\n projectionType: ValueOf;\n };\n [EVENTS.BIND_TEXTURE]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_LOST]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_RESTORE]: ComponentEvent;\n}> {\n public static EVENTS = EVENTS;\n public static ERROR_TYPE = ERROR_TYPE;\n\n public sphericalConfig: {\n initialYaw: number;\n initialPitch: number;\n fieldOfView: number;\n imageType: ValueOf;\n stereoFormat: ValueOf;\n cubemapConfig: Partial;\n };\n\n public fieldOfView: number;\n public width: number;\n public height: number;\n\n public canvas: HTMLCanvasElement;\n public context: WebGLRenderingContext;\n public shaderProgram: WebGLProgram | null;\n public texture: WebGLTexture;\n\n public pMatrix: mat4;\n public mvMatrix: mat4;\n\n public textureCoordBuffer: WebGLBuffer | null = null;\n public vertexBuffer: WebGLBuffer | null = null;\n public indexBuffer: WebGLBuffer | null = null;\n\n private _wrapper: HTMLElement | null;\n private _wrapperOrigStyle: string | null;\n private _lastQuaternion: quat | null;\n private _lastYaw: number | null;\n private _lastPitch: number | null;\n private _lastFieldOfView: number | null;\n private _renderingContextAttributes?: WebGLContextAttributes;\n\n private _renderer: Renderer;\n private _contentLoader: ImReady | null;\n private _image: HTMLImageElement | HTMLImageElement[] | HTMLVideoElement | null;\n private _imageConfig: CubemapConfig | null;\n private _imageType: ValueOf;\n private _imageIsReady: boolean;\n private _isVideo: boolean;\n private _isCubeMap: boolean;\n private _shouldForceDraw: boolean;\n private _keepUpdate: boolean;\n private _hasExternalCanvas: boolean;\n\n private _yawPitchControl: YawPitchControl;\n private _animator: WebGLAnimator;\n private _vr: VRManager | XRManager | null;\n\n public constructor(\n image: ImageCandidate | VideoCandidate,\n width: number,\n height: number,\n isVideo: boolean,\n container: HTMLElement,\n canvasClass: string,\n sphericalConfig: PanoImageRenderer[\"sphericalConfig\"],\n renderingContextAttributes?: WebGLContextAttributes\n ) {\n // Super constructor\n super();\n\n this.sphericalConfig = sphericalConfig;\n this.fieldOfView = sphericalConfig.fieldOfView;\n\n this.width = width;\n this.height = height;\n\n this._lastQuaternion = null;\n this._lastYaw = null;\n this._lastPitch = null;\n this._lastFieldOfView = null;\n\n this.pMatrix = mat4.create();\n this.mvMatrix = mat4.create();\n\n // initialzie pMatrix\n mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), width / height, 0.1, 100);\n\n this.textureCoordBuffer = null;\n this.vertexBuffer = null;\n this.indexBuffer = null;\n\n this.canvas = this._initCanvas(container, canvasClass, width, height);\n\n this._setDefaultCanvasStyle();\n this._wrapper = null; // canvas wrapper\n this._wrapperOrigStyle = null;\n\n this._renderingContextAttributes = renderingContextAttributes;\n this._image = null;\n this._imageConfig = null;\n this._imageIsReady = false;\n this._shouldForceDraw = false;\n this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still.\n\n this._onContentLoad = this._onContentLoad.bind(this);\n this._onContentError = \tthis._onContentError.bind(this);\n\n this._animator = new WebGLAnimator();\n\n // VR/XR manager\n this._vr = null;\n\n if (image) {\n this.setImage({\n image,\n imageType: sphericalConfig.imageType,\n isVideo,\n cubemapConfig: sphericalConfig.cubemapConfig\n });\n }\n }\n\n // FIXME: Please refactor me to have more loose connection to yawpitchcontrol\n public setYawPitchControl(yawPitchControl: YawPitchControl) {\n this._yawPitchControl = yawPitchControl;\n }\n\n public getContent() {\n return this._image;\n }\n\n public setImage({\n image,\n imageType,\n isVideo = false,\n cubemapConfig\n }: {\n image: ImageCandidate | VideoCandidate;\n imageType: PanoImageRenderer[\"_imageType\"];\n isVideo: boolean;\n cubemapConfig: Partial;\n }) {\n this._imageIsReady = false;\n this._isVideo = isVideo;\n this._imageConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only */\n order: (imageType === ImageType.CUBEMAP) ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n },\n ...cubemapConfig\n };\n this._setImageType(imageType);\n\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._contentLoader = new ImReady()\n .on(\"ready\", this._onContentLoad)\n .on(\"error\", this._onContentError);\n\n if (isVideo) {\n this._image = toVideoElement(image as VideoCandidate);\n this._contentLoader.check([this._image]);\n this._keepUpdate = true;\n } else {\n this._image = toImageElement(image as ImageCandidate);\n this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n this._keepUpdate = false;\n }\n }\n\n public isImageLoaded() {\n return !!this._image && this._imageIsReady &&\n (!this._isVideo || (this._image as HTMLVideoElement).readyState >= 2 /* HAVE_CURRENT_DATA */);\n }\n\n public bindTexture() {\n return new Promise((res, rej) => {\n const contentLoader = this._contentLoader;\n\n if (!this._image) {\n return rej(\"Image is not defined\");\n }\n\n if (!contentLoader) {\n return rej(\"ImageLoader is not initialized\");\n }\n\n if (contentLoader.isReady()) {\n this._bindTexture();\n res();\n } else {\n contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n contentLoader.once(\"ready\", e => {\n if (e.errorCount > 0) {\n rej(\"Failed to load images.\");\n } else {\n this._bindTexture();\n res();\n }\n });\n }\n });\n }\n\n // 부모 엘리먼트에 canvas 를 붙임\n public attachTo(parentElement) {\n if (!this._hasExternalCanvas) {\n this.detach();\n parentElement.appendChild(this.canvas);\n }\n this._wrapper = parentElement;\n }\n\n public forceContextLoss() {\n if (this.hasRenderingContext()) {\n const loseContextExtension = this.context.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n\n // 부모 엘리먼트에서 canvas 를 제거\n public detach() {\n if (!this._hasExternalCanvas && this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n\n public destroy() {\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._animator.stop();\n this.detach();\n this.forceContextLoss();\n\n this.off();\n\n this.canvas.removeEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n this.canvas.removeEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n }\n\n public hasRenderingContext() {\n const ctx = this.context;\n if (\n !ctx\n || ctx.isContextLost()\n || !ctx.getProgramParameter(this.shaderProgram!, ctx.LINK_STATUS)) {\n return false;\n }\n return true;\n }\n\n public updateFieldOfView(fieldOfView) {\n this.fieldOfView = fieldOfView;\n this._updateViewport();\n }\n\n public updateViewportDimensions(width, height) {\n let viewPortChanged = false;\n\n this.width = width;\n this.height = height;\n\n const w = width * DEVICE_PIXEL_RATIO;\n const h = height * DEVICE_PIXEL_RATIO;\n\n if (w !== this.canvas.width) {\n this.canvas.width = w;\n viewPortChanged = true;\n }\n\n if (h !== this.canvas.height) {\n this.canvas.height = h;\n viewPortChanged = true;\n }\n\n if (!viewPortChanged) {\n return;\n }\n\n this._updateViewport();\n this._shouldForceDraw = true;\n }\n\n public keepUpdate(doUpdate) {\n if (doUpdate && this.isImageLoaded() === false) {\n // Force to draw a frame after image is loaded on render()\n this._shouldForceDraw = true;\n }\n\n this._keepUpdate = doUpdate;\n }\n\n public startRender() {\n this._animator.setCallback(this._render.bind(this));\n this._animator.start();\n }\n\n public stopRender() {\n this._animator.stop();\n }\n\n public renderWithQuaternion(quaternion, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // updatefieldOfView only if fieldOfView is changed.\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion);\n\n this._draw();\n\n this._lastQuaternion = quat.clone(quaternion);\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n public renderWithYawPitch(yaw, pitch, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastYaw !== null && this._lastYaw === yaw &&\n this._lastPitch !== null && this._lastPitch === pitch &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n mat4.identity(this.mvMatrix);\n mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch));\n mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw));\n\n this._draw();\n\n this._lastYaw = yaw;\n this._lastPitch = pitch;\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n /**\n * Returns projection renderer by each type\n */\n public getProjectionRenderer() {\n return this._renderer;\n }\n\n /**\n * @return Promise\n */\n public enterVR(options) {\n const vr = this._vr;\n\n if (!WEBXR_SUPPORTED && !(navigator as any).getVRDisplays) {\n return Promise.reject(\"VR is not available on this browser.\");\n }\n if (vr && vr.isPresenting()) {\n return Promise.resolve(\"VR already enabled.\");\n }\n\n return this._requestPresent(options);\n }\n\n public exitVR = () => {\n const vr = this._vr;\n const gl = this.context;\n const animator = this._animator;\n\n if (!vr) return;\n\n vr.removeEndCallback(this.exitVR);\n vr.destroy();\n this._vr = null;\n\n // Restore canvas & context on iOS\n if (IS_IOS) {\n this._restoreStyle();\n }\n this.updateViewportDimensions(this.width, this.height);\n this._updateViewport();\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._bindBuffers();\n this._shouldForceDraw = true;\n\n animator.stop();\n animator.setContext(window);\n animator.setCallback(this._render.bind(this));\n animator.start();\n };\n\n private _setImageType(imageType) {\n if (!imageType || this._imageType === imageType) {\n return;\n }\n\n this._imageType = imageType;\n this._isCubeMap = imageType === ImageType.CUBEMAP;\n\n if (this._renderer) {\n this._renderer.off();\n }\n\n switch (imageType) {\n case ImageType.CUBEMAP:\n this._renderer = new CubeRenderer();\n break;\n case ImageType.CUBESTRIP:\n this._renderer = new CubeStripRenderer();\n break;\n case ImageType.PANORAMA:\n this._renderer = new CylinderRenderer();\n break;\n case ImageType.STEREOSCOPIC_EQUI:\n this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat);\n break;\n default:\n this._renderer = new SphereRenderer(STEREO_FORMAT.NONE);\n break;\n }\n\n this._renderer.on(Renderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERER_ERROR,\n message: e.message\n }));\n });\n\n this._initWebGL();\n }\n\n private _initCanvas(container: HTMLElement, canvasClass: string, width: number, height: number) {\n const canvasInContainer = container.querySelector(`.${canvasClass}`);\n const canvas = canvasInContainer || this._createCanvas(canvasClass);\n\n this._hasExternalCanvas = !!canvasInContainer;\n\n canvas.width = width;\n canvas.height = height;\n\n this._onWebglcontextlost = this._onWebglcontextlost.bind(this);\n this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this);\n\n canvas.addEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n canvas.addEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n\n return canvas;\n }\n\n private _createCanvas(className: string) {\n const canvas = document.createElement(\"canvas\");\n\n canvas.className = className;\n\n return canvas;\n }\n\n private _setDefaultCanvasStyle() {\n const canvas = this.canvas;\n\n canvas.style.bottom = \"0\";\n canvas.style.left = \"0\";\n canvas.style.right = \"0\";\n canvas.style.top = \"0\";\n canvas.style.margin = \"auto\";\n canvas.style.maxHeight = \"100%\";\n canvas.style.maxWidth = \"100%\";\n canvas.style.outline = \"none\";\n canvas.style.position = \"absolute\";\n }\n\n private _onContentError() {\n this._imageIsReady = false;\n this._image = null;\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_IMAGE_LOAD,\n message: \"failed to load image\"\n }));\n\n return false;\n }\n\n private _triggerContentLoad() {\n this.trigger(new ComponentEvent(EVENTS.IMAGE_LOADED, {\n content: this._image as HTMLElement,\n isVideo: this._isVideo,\n projectionType: this._imageType\n }));\n }\n\n private _onContentLoad(e: OnReady) {\n if (e.errorCount > 0) return;\n\n this._imageIsReady = true;\n\n this._triggerContentLoad();\n }\n\n private _initShaderProgram() {\n const gl = this.context;\n\n if (this.shaderProgram) {\n gl.deleteProgram(this.shaderProgram);\n this.shaderProgram = null;\n }\n\n const renderer = this._renderer;\n\n const vsSource = renderer.getVertexShaderSource();\n const fsSource = renderer.getFragmentShaderSource();\n\n const vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource)!;\n const fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource)!;\n\n const shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader);\n\n if (!shaderProgram) {\n throw new Error(`Failed to initialize shaders: ${WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())}`);\n }\n\n gl.useProgram(shaderProgram);\n (shaderProgram as any).vertexPositionAttribute = gl.getAttribLocation(shaderProgram, \"aVertexPosition\");\n (shaderProgram as any).pMatrixUniform = gl.getUniformLocation(shaderProgram, \"uPMatrix\");\n (shaderProgram as any).mvMatrixUniform = gl.getUniformLocation(shaderProgram, \"uMVMatrix\");\n (shaderProgram as any).samplerUniform = gl.getUniformLocation(shaderProgram, \"uSampler\");\n (shaderProgram as any).textureCoordAttribute = gl.getAttribLocation(shaderProgram, \"aTextureCoord\");\n (shaderProgram as any).uEye = gl.getUniformLocation(shaderProgram, \"uEye\");\n\n gl.enableVertexAttribArray((shaderProgram as any).vertexPositionAttribute);\n gl.enableVertexAttribArray((shaderProgram as any).textureCoordAttribute);\n\n // clear buffer\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\n // Use TEXTURE0\n gl.uniform1i((shaderProgram as any).samplerUniform, 0);\n\n this.shaderProgram = shaderProgram;\n }\n\n private _onWebglcontextlost(e) {\n e.preventDefault();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_LOST));\n }\n\n private _onWebglcontextrestored() {\n this._initWebGL();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_RESTORE));\n }\n\n private _updateViewport() {\n mat4.perspective(\n this.pMatrix,\n glMatrix.toRadian(this.fieldOfView),\n this.canvas.width / this.canvas.height,\n 0.1,\n 100);\n\n this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight);\n }\n\n private _initWebGL() {\n let gl: WebGLRenderingContext;\n\n // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed.\n try {\n this._initRenderingContext();\n gl = this.context;\n\n this.updateViewportDimensions(this.width, this.height);\n this._initShaderProgram();\n } catch (e) {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n this.destroy();\n console.error(e); // eslint-disable-line no-console\n return;\n }\n // 캔버스를 투명으로 채운다.\n gl.clearColor(0, 0, 0, 0);\n const textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\n\n if (this.texture) {\n gl.deleteTexture(this.texture);\n }\n\n this.texture = WebGLUtils.createTexture(gl, textureTarget)!;\n\n if (this._imageType === ImageType.CUBESTRIP) {\n // TODO: Apply following options on other projection type.\n gl.enable(gl.CULL_FACE);\n // gl.enable(gl.DEPTH_TEST);\n }\n }\n\n private _initRenderingContext() {\n if (this.hasRenderingContext()) {\n return;\n }\n\n if (!window.WebGLRenderingContext) {\n throw new Error(\"WebGLRenderingContext not available.\");\n }\n\n this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes)!;\n\n if (!this.context) {\n throw new Error(\"Failed to acquire 3D rendering context\");\n }\n }\n\n private _initBuffers() {\n const image = this._image as HTMLImageElement | HTMLVideoElement;\n\n const vertexPositionData = this._renderer.getVertexPositionData();\n const indexData = this._renderer.getIndexData();\n const textureCoordData = this._renderer.getTextureCoordData({\n image,\n imageConfig: this._imageConfig!\n });\n const gl = this.context;\n\n this.vertexBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3,\n (this.shaderProgram as any).vertexPositionAttribute);\n\n this.indexBuffer = WebGLUtils.initBuffer(\n gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1);\n\n this.textureCoordBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2,\n (this.shaderProgram as any).textureCoordAttribute);\n\n this._bindBuffers();\n }\n\n private _bindTexture() {\n // Detect if it is EAC Format while CUBESTRIP mode.\n // We assume it is EAC if image is not 3/2 ratio.\n if (this._imageType === ImageType.CUBESTRIP) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const isEAC = width && height && width / height !== 1.5 ? 1 : 0;\n\n this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram!, \"uIsEAC\"), isEAC);\n } else if (this._imageType === ImageType.PANORAMA) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const imageAspectRatio = width && height && width / height;\n\n this._renderer.updateShaderData({imageAspectRatio});\n }\n\n // initialize shader buffers after image is loaded.(by updateShaderData)\n // because buffer may be differ by image size.(eg. CylinderRenderer)\n this._initBuffers();\n\n this._renderer.bindTexture(\n this.context,\n this.texture,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n this._shouldForceDraw = true;\n\n this.trigger(new ComponentEvent(EVENTS.BIND_TEXTURE));\n }\n\n private _updateTexture() {\n this._renderer.updateTexture(\n this.context,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n }\n\n private _render() {\n const yawPitchControl = this._yawPitchControl;\n const fov = yawPitchControl.getFov();\n\n if (yawPitchControl.shouldRenderWithQuaternion()) {\n const quaternion = yawPitchControl.getQuaternion();\n\n this.renderWithQuaternion(quaternion, fov);\n } else {\n const yawPitch = yawPitchControl.getYawPitch();\n\n this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov);\n }\n }\n\n private _renderStereo = (time: number, frame: XRFrame) => {\n const vr = this._vr;\n const gl = this.context;\n\n const eyeParams = vr!.getEyeParams(gl, frame);\n\n if (!eyeParams) return;\n\n vr!.beforeRender(gl, frame);\n\n // Render both eyes\n for (const eyeIndex of [0, 1]) {\n const eyeParam = eyeParams[eyeIndex];\n\n this.mvMatrix = eyeParam.mvMatrix;\n this.pMatrix = eyeParam.pMatrix;\n\n gl.viewport(...eyeParam.viewport as [number, number, number, number]);\n gl.uniform1f((this.shaderProgram as any).uEye, eyeIndex);\n\n this._bindBuffers();\n this._draw();\n }\n\n vr!.afterRender();\n };\n\n private _bindBuffers() {\n const gl = this.context;\n const program = this.shaderProgram;\n\n const vertexBuffer = this.vertexBuffer;\n const textureCoordBuffer = this.textureCoordBuffer;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray((program as any).vertexPositionAttribute);\n gl.vertexAttribPointer(\n (program as any).vertexPositionAttribute, (vertexBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);\n gl.enableVertexAttribArray((program as any).textureCoordAttribute);\n gl.vertexAttribPointer(\n (program as any).textureCoordAttribute, (textureCoordBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n }\n\n private _draw() {\n if (this._isVideo && this._keepUpdate) {\n this._updateTexture();\n }\n\n this._renderer.render({\n gl: this.context,\n shaderProgram: this.shaderProgram!,\n indexBuffer: this.indexBuffer!,\n mvMatrix: this.mvMatrix,\n pMatrix: this.pMatrix\n });\n }\n\n private _requestPresent(options) {\n const gl = this.context;\n const canvas = this.canvas;\n const animator = this._animator;\n\n this._vr = WEBXR_SUPPORTED ?\n new XRManager(options) :\n new VRManager();\n\n const vr = this._vr;\n\n animator.stop();\n return new Promise((resolve, reject) => {\n vr.requestPresent(canvas, gl)\n .then(() => {\n vr.addEndCallback(this.exitVR);\n animator.setContext(vr.context);\n animator.setCallback(this._onFirstVRFrame);\n\n if (IS_IOS) {\n this._setWrapperFullscreen();\n }\n\n this._shouldForceDraw = true;\n animator.start();\n\n resolve(\"success\");\n })\n .catch(e => {\n vr.destroy();\n this._vr = null;\n animator.start();\n\n reject(e);\n });\n });\n }\n\n private _onFirstVRFrame = (time, frame) => {\n const vr = this._vr!;\n const gl = this.context;\n const animator = this._animator;\n\n // If rendering is not ready, wait for next frame\n if (!vr.canRender(frame)) return;\n\n const minusZDir = vec3.fromValues(0, 0, -1);\n const eyeParam = vr.getEyeParams(gl, frame)![0];\n // Extract only rotation\n const mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix);\n const pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix);\n\n const mvInv = mat3.invert(mat3.create(), mvMatrix);\n const pInv = mat3.invert(mat3.create(), pMatrix);\n const viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv);\n\n vec3.transformMat3(viewDir, viewDir, mvInv);\n\n const yawOffset = mathUtil.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1));\n\n if (yawOffset === 0) {\n // If the yawOffset is exactly 0, then device sensor is not ready\n // So read it again until it has any value in it\n return;\n }\n\n vr.setYawOffset(yawOffset);\n animator.setCallback(this._renderStereo);\n };\n\n private _setWrapperFullscreen() {\n const wrapper = this._wrapper;\n\n if (!wrapper) return;\n\n this._wrapperOrigStyle = wrapper.getAttribute(\"style\");\n const wrapperStyle = wrapper.style;\n\n wrapperStyle.width = \"100vw\";\n wrapperStyle.height = \"100vh\";\n wrapperStyle.position = \"fixed\";\n wrapperStyle.left = \"0\";\n wrapperStyle.top = \"0\";\n wrapperStyle.zIndex = \"9999\";\n }\n\n private _restoreStyle() {\n const wrapper = this._wrapper;\n const canvas = this.canvas;\n\n if (!wrapper) return;\n\n if (this._wrapperOrigStyle) {\n wrapper.setAttribute(\"style\", this._wrapperOrigStyle);\n } else {\n wrapper.removeAttribute(\"style\");\n }\n\n this._wrapperOrigStyle = null;\n\n // Restore canvas style\n canvas.removeAttribute(\"style\");\n this._setDefaultCanvasStyle();\n }\n}\n\nexport default PanoImageRenderer;\n","import Component from \"@egjs/component\";\n\nconst withMethods = (component: any, prototype: any, vanillaInstance: string) => {\n [Component.prototype, component.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto).filter(name => !prototype[name] && !name.startsWith(\"_\") && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[vanillaInstance], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return descriptor.get?.call(this[vanillaInstance]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[vanillaInstance], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Promise from \"promise-polyfill\";\nimport { quat } from \"gl-matrix\";\n\nimport { DeviceMotionEvent, checkXRSupport } from \"../utils/browserFeature\";\nimport YawPitchControl, { YawPitchControlOptions } from \"../YawPitchControl/YawPitchControl\";\nimport PanoImageRenderer from \"../PanoImageRenderer/PanoImageRenderer\";\nimport WebGLUtils from \"../PanoImageRenderer/WebGLUtils\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { CubemapConfig, ValueOf } from \"../types/internal\";\nimport { AnimationEndEvent, ReadyEvent, ViewChangeEvent, ErrorEvent } from \"../types/event\";\n\nimport { ERROR_TYPE, PANOVIEWER_EVENTS as EVENTS, GYRO_MODE, PROJECTION_TYPE, STEREO_FORMAT, DEFAULT_CANVAS_CLASS } from \"./consts\";\n\nexport interface PanoViewerOptions {\n image: string | HTMLElement;\n video: string | HTMLElement;\n projectionType: ValueOf;\n cubemapConfig: Partial;\n stereoFormat: ValueOf;\n width: number;\n height: number;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n touchDirection: ValueOf;\n canvasClass: string;\n}\n\nexport interface PanoViewerEvent {\n ready: ReadyEvent;\n viewChange: ViewChangeEvent;\n animationEnd: AnimationEndEvent;\n error: ErrorEvent;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * PanoViewer\n */\nclass PanoViewer extends Component {\n /**\n * Check whether the current environment can execute PanoViewer\n * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다.\n * @return PanoViewer executable PanoViewer 실행가능 여부\n */\n public static isSupported(): boolean {\n return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL();\n }\n\n /**\n * Check whether the current environment supports the WebGL\n * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다.\n * @return WebGL support WebGL 지원여부\n */\n public static isWebGLAvailable(): boolean {\n return WebGLUtils.isWebGLAvailable();\n }\n\n /**\n * Check whether the current environment supports the gyro sensor.\n * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다.\n * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수\n */\n public static isGyroSensorAvailable(callback: (isAvailable: boolean) => any) {\n if (!DeviceMotionEvent && callback) {\n callback(false);\n return;\n }\n\n let onDeviceMotionChange;\n\n const checkGyro = () => new Promise(res => {\n onDeviceMotionChange = deviceMotion => {\n const isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null);\n\n res(isGyroSensorAvailable);\n };\n\n window.addEventListener(\"devicemotion\", onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n Promise.race([checkGyro(), timeout()]).then((isGyroSensorAvailable: boolean) => {\n window.removeEventListener(\"devicemotion\", onDeviceMotionChange);\n\n if (callback) {\n callback(isGyroSensorAvailable);\n }\n\n PanoViewer.isGyroSensorAvailable = fb => {\n if (fb) {\n fb(isGyroSensorAvailable);\n }\n return isGyroSensorAvailable;\n };\n });\n }\n\n private static _isValidTouchDirection(direction) {\n return direction === PanoViewer.TOUCH_DIRECTION.NONE ||\n direction === PanoViewer.TOUCH_DIRECTION.YAW ||\n direction === PanoViewer.TOUCH_DIRECTION.PITCH ||\n direction === PanoViewer.TOUCH_DIRECTION.ALL;\n }\n\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @name VERSION\n * @static\n * @type {String}\n * @example\n * eg.view360.PanoViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.PanoViewer\n */\n public static VERSION = VERSION;\n public static ERROR_TYPE = ERROR_TYPE;\n public static EVENTS = EVENTS;\n public static PROJECTION_TYPE = PROJECTION_TYPE;\n public static GYRO_MODE = GYRO_MODE;\n // This should be deprecated!\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static ProjectionType = PROJECTION_TYPE;\n public static STEREO_FORMAT = STEREO_FORMAT;\n\n /**\n * Constant value for touch directions\n * @ko 터치 방향에 대한 상수 값.\n * @namespace\n * @name TOUCH_DIRECTION\n */\n public static TOUCH_DIRECTION = {\n /**\n * Constant value for none direction.\n * @ko none 방향에 대한 상수 값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 1\n */\n NONE: YawPitchControl.TOUCH_DIRECTION_NONE,\n /**\n * Constant value for horizontal(yaw) direction.\n * @ko horizontal(yaw) 방향에 대한 상수 값.\n * @name YAW\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 6\n */\n YAW: YawPitchControl.TOUCH_DIRECTION_YAW,\n /**\n * Constant value for vertical direction.\n * @ko vertical(pitch) 방향에 대한 상수 값.\n * @name PITCH\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 24\n */\n PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH,\n /**\n * Constant value for all direction.\n * @ko all 방향에 대한 상수 값.\n * @name ALL\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 30\n */\n ALL: YawPitchControl.TOUCH_DIRECTION_ALL\n };\n\n private _container: HTMLElement;\n // Options\n private _image: ConstructorParameters[0];\n private _isVideo: boolean;\n private _projectionType: ValueOf;\n private _cubemapConfig: Partial;\n private _stereoFormat: ValueOf;\n private _width: number;\n private _height: number;\n private _yaw: number;\n private _pitch: number;\n private _fov: number;\n private _gyroMode: ValueOf;\n private _quaternion: quat | null;\n private _aspectRatio: number;\n private _isReady: boolean;\n private _canvasClass: string;\n\n // Internal Values\n private _photoSphereRenderer: PanoImageRenderer | null;\n private _yawPitchControl: YawPitchControl | null;\n\n /**\n * @classdesc 360 media viewer\n * @ko 360 미디어 뷰어\n *\n * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트\n * @param options\n *\n * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
\n * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다.\n * @param {Object} [options.cubemapConfig.order = \"RLUDBF\"(ProjectionType === CUBEMAP) | \"RLUDFB\" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서\n * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다.\n * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다.\n * @param {String} [options.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
\n * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위)\n * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위)\n * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위)\n * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위)\n * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위)\n * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다\n * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다.\n * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키\n * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE}
\n * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위\n * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위\n * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위\n * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
\n * @param {String} [options.canvasClass=\"view360-canvas\"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n *\n * @example\n * ```\n * // PanoViewer Creation\n * // create PanoViewer with option\n * var PanoViewer = eg.view360.PanoViewer;\n * // Area where the image will be displayed(HTMLElement)\n * var container = document.getElementById(\"myPanoViewer\");\n *\n * var panoViewer = new PanoViewer(container, {\n * // If projectionType is not specified, the default is \"equirectangular\".\n * // Specifies an image of the \"equirectangular\" type.\n * image: \"/path/to/image/image.jpg\"\n * });\n * ```\n *\n * @example\n * ```\n * // Cubemap Config Setting Example\n * // For support Youtube EAC projection, You should set cubemapConfig as follows.\n * cubemapConfig: {\n * order: \"LFRDBU\",\n * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}]\n * }\n * ```\n */\n public constructor(container: HTMLElement, options: Partial = {}) {\n super();\n\n // Raises the error event if webgl is not supported.\n if (!WebGLUtils.isWebGLAvailable()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n }, 0);\n return this;\n }\n\n if (!WebGLUtils.isStableWebGL()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_DEVICE,\n message: \"blacklisted browser\"\n }));\n }, 0);\n\n return this;\n }\n\n if (!!options.image && !!options.video) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_RESOURCE,\n message: \"Specifying multi resouces(both image and video) is not valid.\"\n }));\n }, 0);\n return this;\n }\n\n // Check XR support at not when imported, but when created.\n // This is intended to make polyfills easier to use.\n checkXRSupport();\n\n this._container = container;\n this._image = options.image! as HTMLImageElement || options.video! as HTMLVideoElement;\n this._isVideo = !!options.video;\n this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/\n order: this._projectionType === PROJECTION_TYPE.CUBEMAP ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...options.cubemapConfig\n };\n this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n\n // If the width and height are not provided, will use the size of the container.\n this._width = options.width || parseInt(window.getComputedStyle(container).width, 10);\n this._height = options.height || parseInt(window.getComputedStyle(container).height, 10);\n\n /**\n * Cache the direction for the performance in renderLoop\n *\n * This value should be updated by \"change\" event of YawPitchControl.\n */\n this._yaw = options.yaw || 0;\n this._pitch = options.pitch || 0;\n this._fov = options.fov || 65;\n\n this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH;\n this._quaternion = null;\n\n this._aspectRatio = this._height !== 0 ? this._width / this._height : 1;\n\n this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS;\n\n const fovRange = options.fovRange || [30, 110];\n const touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ?\n options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL;\n const yawPitchConfig = {\n ...options,\n ...{\n element: container,\n yaw: this._yaw,\n pitch: this._pitch,\n fov: this._fov,\n gyroMode: this._gyroMode,\n fovRange,\n aspectRatio: this._aspectRatio,\n touchDirection\n }\n };\n\n this._isReady = false;\n\n this._initYawPitchControl(yawPitchConfig);\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n /**\n * Get the video element that the viewer is currently playing. You can use this for playback.\n * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다.\n * @return HTMLVideoElementHTMLVideoElement\n * @example\n * ```\n * var videoTag = panoViewer.getVideo();\n * videoTag.play(); // play the video!\n * ```\n */\n public getVideo() {\n if (!this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent() as HTMLVideoElement;\n }\n\n /**\n * Set the video information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정)\n * @param {object} param\n * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}(\"equirectangular\")] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setVideo(\"/path/to/video/video.mp4\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR\n * });\n * ```\n */\n public setVideo(video: string | HTMLElement | { type: string; src: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n }> = {}) {\n if (video) {\n this.setImage(video, {\n projectionType: param.projectionType,\n isVideo: true,\n cubemapConfig: param.cubemapConfig,\n stereoFormat: param.stereoFormat\n });\n }\n\n return this;\n }\n\n /**\n * Get the image information that the viewer is currently using.\n * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다.\n * @return Image Object이미지 객체\n * @example\n * var imageObj = panoViewer.getImage();\n */\n public getImage() {\n if (this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent();\n }\n\n /**\n * Set the image information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.)\n * @param {object} param Additional information이미지 추가 정보\n * @param {string} [param.projectionType=\"equirectangular\"] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setImage(\"/path/to/image/image.png\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP\n * });\n * ```\n */\n public setImage(image: string | HTMLElement | { src: string; type: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n isVideo: boolean;\n }> = {}) {\n const cubemapConfig = {\n ...{\n order: \"RLUDBF\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...param.cubemapConfig\n };\n const stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n const isVideo = !!(param.isVideo);\n\n if (this._image && this._isVideo !== isVideo) {\n /* eslint-disable no-console */\n console.warn(\"PanoViewer is not currently supporting content type changes. (Image <--> Video)\");\n /* eslint-enable no-console */\n return this;\n }\n\n if (image) {\n this._deactivate();\n\n this._image = image as HTMLImageElement;\n this._isVideo = isVideo;\n this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = cubemapConfig;\n this._stereoFormat = stereoFormat;\n\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n return this;\n }\n\n /**\n * Set whether the renderer always updates the texture and renders.\n * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다.\n * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public keepUpdate(doUpdate: boolean) {\n this._photoSphereRenderer!.keepUpdate(doUpdate);\n return this;\n }\n\n /**\n * Get the current projection type (equirectangular/cube)\n * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다.\n * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE}\n */\n public getProjectionType() {\n return this._projectionType;\n }\n\n /**\n * Activate the device's motion sensor, and return the Promise whether the sensor is enabled\n * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element.\n * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다.\n * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다.\n */\n public enableSensor() {\n return new Promise((resolve, reject) => {\n if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\") {\n DeviceMotionEvent.requestPermission().then(permissionState => {\n if (permissionState === \"granted\") {\n resolve();\n } else {\n reject(new Error(\"permission denied\"));\n }\n }).catch(e => {\n // This can happen when this method wasn't triggered by user interaction\n reject(e);\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Disable the device's motion sensor.\n * @ko 디바이스의 모션 센서를 비활성화합니다.\n * @deprecated\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public disableSensor() {\n return this;\n }\n\n /**\n * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred).\n * This method must be used in the context of user interaction, like onclick callback on the button element.\n * It can be rejected when an enabling device sensor fails or image/video is still loading(\"ready\" event not triggered).\n * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다)\n * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우(\"ready\"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다.\n * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요.\n * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error)\n */\n public enterVR(options: {\n requiredFeatures?: any[];\n optionalFeatures?: any[];\n [key: string]: any;\n } = {}): globalThis.Promise {\n if (!this._isReady) {\n return Promise.reject(new Error(\"PanoViewer is not ready to show image.\")) as any;\n }\n\n return new Promise((resolve, reject) => {\n this.enableSensor()\n .then(() => this._photoSphereRenderer!.enterVR(options))\n .then((res: string) => resolve(res))\n .catch(e => reject(e));\n }) as any;\n }\n\n /**\n * Exit VR stereo rendering mode.\n * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public exitVR() {\n this._photoSphereRenderer!.exitVR();\n return this;\n }\n\n /**\n * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}.\n * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다.\n * @param useZoom\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseZoom(useZoom: boolean): this {\n if (typeof useZoom === \"boolean\") {\n this._yawPitchControl!.option(\"useZoom\", useZoom);\n }\n\n return this;\n }\n\n /**\n * When true, enables the keyboard move key control: awsd, arrow keys\n * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키)\n * @param useKeyboard\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseKeyboard(useKeyboard: boolean): this {\n this._yawPitchControl!.option(\"useKeyboard\", useKeyboard);\n return this;\n }\n\n /**\n * Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")\n * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")\n * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE}\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setGyroMode(\"yawPitch\");\n * //equivalent\n * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH);\n * ```\n */\n public setGyroMode(gyroMode: PanoViewer[\"_gyroMode\"]) {\n this._yawPitchControl!.option(\"gyroMode\", gyroMode);\n return this;\n }\n\n /**\n * Set the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 설정합니다.\n * @param range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setFovRange([50, 90]);\n */\n public setFovRange(range: number[]) {\n this._yawPitchControl!.option(\"fovRange\", range);\n return this;\n }\n\n /**\n * Get the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 반환합니다.\n * @return FOV range\n * @example\n * var range = panoViewer.getFovRange(); // [50, 90]\n */\n public getFovRange(): [number, number] {\n return this._yawPitchControl!.option(\"fovRange\") as [number, number];\n }\n\n /**\n * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size.\n * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다.\n * @param {object} [size]\n * @param {number} [size.width=width of the container]\n * @param {number} [size.height=height of the container]\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public updateViewportDimensions(size: Partial<{\n width: number;\n height: number;\n }> = {}): this {\n if (!this._isReady) {\n return this;\n }\n\n let containerSize;\n\n if (size.width === undefined || size.height === undefined) {\n containerSize = window.getComputedStyle(this._container);\n }\n\n const width = size.width || parseInt(containerSize.width, 10);\n const height = size.height || parseInt(containerSize.height, 10);\n\n // Skip if viewport is not changed.\n if (width === this._width && height === this._height) {\n return this;\n }\n\n this._width = width;\n this._height = height;\n\n this._aspectRatio = width / height;\n this._photoSphereRenderer!.updateViewportDimensions(width, height);\n this._yawPitchControl!.option(\"aspectRatio\", this._aspectRatio);\n this._yawPitchControl!.updatePanScale({height});\n\n this.lookAt({}, 0);\n return this;\n }\n\n /**\n * Get the current field of view(FOV)\n * @ko 현재 field of view(FOV) 값을 반환합니다.\n */\n public getFov(): number {\n return this._fov;\n }\n\n /**\n * Get current yaw value\n * @ko 현재 yaw 값을 반환합니다.\n */\n public getYaw() {\n return this._yaw;\n }\n\n /**\n * Get current pitch value\n * @ko 현재 pitch 값을 반환합니다.\n */\n public getPitch() {\n return this._pitch;\n }\n\n /**\n * Get the range of controllable Yaw values\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n */\n public getYawRange(): [number, number] {\n return this._yawPitchControl!.option(\"yawRange\") as [number, number];\n }\n\n /**\n * Get the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다.\n */\n public getPitchRange(): [number, number] {\n return this._yawPitchControl!.option(\"pitchRange\") as [number, number];\n }\n\n /**\n * Set the range of controllable yaw\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setYawRange([-90, 90]);\n */\n public setYawRange(yawRange: number[]) {\n this._yawPitchControl!.option(\"yawRange\", yawRange);\n return this;\n }\n\n /**\n * Set the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 설정합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setPitchRange([-40, 40]);\n */\n public setPitchRange(pitchRange: number[]) {\n this._yawPitchControl!.option(\"pitchRange\", pitchRange);\n return this;\n }\n\n /**\n * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed.\n * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다.\n * @param showPolePoint\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setShowPolePoint(showPolePoint: boolean) {\n this._yawPitchControl!.option(\"showPolePoint\", showPolePoint);\n return this;\n }\n\n /**\n * Set a new view by setting camera configuration. Any parameters not specified remain the same.\n * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다.\n * @param {object} orientation\n * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위)\n * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위)\n * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위)\n * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초)\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * // Change the yaw angle (absolute angle) to 30 degrees for one second.\n * panoViewer.lookAt({yaw: 30}, 1000);\n * ```\n */\n public lookAt(orientation: Partial<{\n yaw: number;\n pitch: number;\n fov: number;\n }>, duration: number = 0) {\n if (!this._isReady) {\n return this;\n }\n\n const yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw;\n const pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch;\n const pitchRange = this._yawPitchControl!.option(\"pitchRange\");\n const verticalAngleOfImage = pitchRange[1] - pitchRange[0];\n let fov = orientation.fov !== undefined ? orientation.fov : this._fov;\n\n if (verticalAngleOfImage < fov) {\n fov = verticalAngleOfImage;\n }\n\n this._yawPitchControl!.lookAt({yaw, pitch, fov}, duration);\n\n if (duration === 0) {\n this._photoSphereRenderer!.renderWithYawPitch(yaw, pitch, fov);\n }\n return this;\n }\n\n /**\n * Set touch direction by which user can control.\n * @ko 사용자가 조작가능한 터치 방향을 지정합니다.\n * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @return PanoViewer instance\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Limit the touch direction to the yaw direction only.\n * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW);\n * ```\n */\n public setTouchDirection(direction: number): this {\n if (PanoViewer._isValidTouchDirection(direction)) {\n this._yawPitchControl!.option(\"touchDirection\", direction);\n }\n\n return this;\n }\n\n /**\n * Returns touch direction by which user can control\n * @ko 사용자가 조작가능한 터치 방향을 반환한다.\n * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Returns the current touch direction.\n * var dir = panoViewer.getTouchDirection();\n * ```\n */\n public getTouchDirection(): number {\n return this._yawPitchControl!.option(\"touchDirection\") ;\n }\n\n /**\n * Destroy viewer. Remove all registered event listeners and remove viewer canvas.\n * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public destroy(): this {\n this._deactivate();\n\n if (this._yawPitchControl) {\n this._yawPitchControl.destroy();\n this._yawPitchControl = null;\n }\n\n return this;\n }\n\n // TODO: Remove parameters as they're just using private values\n private _initRenderer(\n yaw: number,\n pitch: number,\n fov: number,\n projectionType: PanoViewer[\"_projectionType\"],\n cubemapConfig: PanoViewer[\"_cubemapConfig\"]\n ) {\n this._photoSphereRenderer = new PanoImageRenderer(\n this._image,\n this._width,\n this._height,\n this._isVideo,\n this._container,\n this._canvasClass,\n {\n initialYaw: yaw,\n initialPitch: pitch,\n fieldOfView: fov,\n imageType: projectionType,\n cubemapConfig,\n stereoFormat: this._stereoFormat\n },\n );\n this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl!);\n\n this._bindRendererHandler();\n\n this._photoSphereRenderer\n .bindTexture()\n .then(() => this._activate())\n .catch(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_BIND_TEXTURE,\n message: \"failed to bind texture\"\n }));\n });\n }\n\n /**\n * @private\n * update values of YawPitchControl if needed.\n * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image.\n *\n * This function should be called after isReady status is true.\n */\n private _updateYawPitchIfNeeded() {\n if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) {\n // update fov by aspect ratio\n const image = this._photoSphereRenderer!.getContent()! as HTMLImageElement;\n let imageAspectRatio = image.naturalWidth / image.naturalHeight;\n let yawSize;\n let maxFov;\n\n // If height is larger than width, then we assume it's rotated by 90 degree.\n if (imageAspectRatio < 1) {\n // So inverse the aspect ratio.\n imageAspectRatio = 1 / imageAspectRatio;\n }\n\n if (imageAspectRatio < 6) {\n yawSize = mathUtil.toDegree(imageAspectRatio);\n // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5\n maxFov = mathUtil.toDegree(Math.atan(0.5)) * 2;\n } else {\n yawSize = 360;\n maxFov = (360 / imageAspectRatio); // Make it 5 fixed as axes does.\n }\n\n // console.log(\"_updateYawPitchIfNeeded\", maxFov, \"aspectRatio\", image.naturalWidth, image.naturalHeight, \"yawSize\", yawSize);\n const minFov = (this._yawPitchControl!.option(\"fovRange\"))[0];\n\n // this option should be called after fov is set.\n this._yawPitchControl!.option({\n \"fov\": maxFov, /* parameter for internal validation for pitchrange */\n \"yawRange\": [-yawSize / 2, yawSize / 2],\n \"pitchRange\": [-maxFov / 2, maxFov / 2],\n \"fovRange\": [minFov, maxFov]\n });\n this.lookAt({fov: maxFov});\n }\n }\n\n private\t_bindRendererHandler() {\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, e));\n });\n\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, () => {\n this._deactivate();\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERING_CONTEXT_LOST,\n message: \"webgl rendering context lost\"\n }));\n });\n }\n\n private _initYawPitchControl(yawPitchConfig: Partial) {\n this._yawPitchControl = new YawPitchControl(yawPitchConfig);\n\n this._yawPitchControl.on(EVENTS.ANIMATION_END, e => {\n this.trigger(new ComponentEvent(EVENTS.ANIMATION_END, e));\n });\n\n this._yawPitchControl.on(\"change\", e => {\n this._yaw = e.yaw;\n this._pitch = e.pitch;\n this._fov = e.fov;\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(EVENTS.VIEW_CHANGE, {\n yaw: e.yaw,\n pitch: e.pitch,\n fov: e.fov,\n quaternion: e.quaternion,\n isTrusted: e.isTrusted\n }));\n });\n }\n\n private _activate() {\n this._photoSphereRenderer!.attachTo(this._container);\n this._yawPitchControl!.enable();\n\n this.updateViewportDimensions();\n\n this._isReady = true;\n\n // update yawPitchControl after isReady status is true.\n this._updateYawPitchIfNeeded();\n\n this.trigger(new ComponentEvent(EVENTS.READY));\n this._photoSphereRenderer!.startRender();\n }\n\n /**\n * Destroy webgl context and block user interaction and stop rendering\n */\n private _deactivate() {\n // Turn off the video if it has one\n const video = this.getVideo();\n if (video) {\n video.pause();\n }\n\n if (this._isReady) {\n this._photoSphereRenderer!.stopRender();\n this._yawPitchControl!.disable();\n this._isReady = false;\n }\n\n if (this._photoSphereRenderer) {\n this._photoSphereRenderer.destroy();\n this._photoSphereRenderer = null;\n }\n }\n}\n\nexport default PanoViewer;\n\n","import { SpinViewerOptions, SpinViewerEvent } from \"./SpinViewer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const SPINVIEWER_OPTIONS: { [key in keyof SpinViewerOptions]: true } = {\n imageUrl: true,\n rowCount: true,\n colCount: true,\n width: true,\n height: true,\n autoHeight: true,\n colRow: true,\n scale: true,\n frameIndex: true,\n wrapperClass: true,\n imageClass: true\n};\n\nexport const SPINVIEWER_EVENTS: {\n [key: string]: keyof SpinViewerEvent;\n} = {\n LOAD: \"load\",\n IMAGE_ERROR: \"imageError\",\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n};\n\nexport const DEFAULT_WRAPPER_CLASS = \"view360-wrapper\";\nexport const DEFAULT_IMAGE_CLASS = \"view360-image\";\n","import Component, { ComponentEvent } from \"@egjs/component\";\n\nimport { TRANSFORM, SUPPORT_WILLCHANGE } from \"../utils/browserFeature\";\nimport { VERSION } from \"../version\";\n\nimport { SpinViewerOptions } from \"./SpinViewer\";\nimport { DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS } from \"./consts\";\n\nexport interface SpriteImageEvent {\n /**\n * Events that occur when component loading is complete\n * @ko 컴포넌트 로딩이 완료되면 발생하는 이벤트\n * @name eg.view360.SpriteImage#load\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {HTMLElement} param.target The target element for which to display the image 이미지를 보여줄 대상 엘리먼트\n * @param {HTMLElement} param.bgElement Generated background image element 생성된 background 이미지 엘리먼트\n *\n * @example\n *\n * sprites.on({\n * \"load\" : function(evt) {\n * console.log(\"load event fired - e.target\", e.target, \"e.bgElement\", e.bgElement);\n * }\n * });\n */\n load: {\n target: HTMLElement;\n bgElement: HTMLDivElement;\n };\n /**\n * An event that occurs when the image index is changed by the user's left / right panning\n * @ko 사용자의 좌우 Panning 에 의해 이미지 인덱스가 변경되었을때 발생하는 이벤트\n * @name eg.view360.SpriteImage#imageError\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {String} param.imageUrl User-specified image URL 사용자가 지정한 이미지 URL\n *\n * @example\n *\n * sprites.on({\n * \"imageError\" : function(evt) {\n * // Error handling\n * console.log(e.imageUrl);\n * }\n * });\n */\n imageError: {\n imageUrl?: string;\n };\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpriteImage\n */\nclass SpriteImage extends Component {\n private static _createBgDiv(wrapperInContainer: HTMLDivElement | null, img: HTMLImageElement, rowCount: number, colCount: number, autoHeight: boolean) {\n const el = wrapperInContainer || document.createElement(\"div\");\n\n el.style.position = \"relative\";\n el.style.overflow = \"hidden\";\n\n img.style.position = \"absolute\";\n img.style.width = `${colCount * 100}%`;\n img.style.height = `${rowCount * 100}%`;\n\n /** Prevent image from being dragged on IE10, IE11, Safari especially */\n img.ondragstart = () => (false); // img.style.pointerEvents = \"none\";\n // Use hardware accelerator if available\n if (SUPPORT_WILLCHANGE) {\n (img.style.willChange = \"transform\");\n }\n\n el.appendChild(img);\n\n const unitWidth = img.naturalWidth / colCount;\n const unitHeight = img.naturalHeight / rowCount;\n\n if (autoHeight) {\n const r = unitHeight / unitWidth;\n\n el.style.paddingBottom = `${r * 100}%`;\n } else {\n el.style.height = \"100%\";\n }\n\n return el;\n }\n\n private static _getSizeString(size) {\n if (typeof size === \"number\") {\n return `${size}px`;\n }\n\n return size;\n }\n\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _rowCount: number;\n private _colCount: number;\n private _totalCount: number;\n private _width: number | string;\n private _height: number | string;\n private _autoHeight: boolean;\n private _colRow: number[];\n private _image: HTMLImageElement;\n private _bg: HTMLDivElement;\n private _autoPlayReservedInfo: { interval: number; playCount: number } | null;\n private _autoPlayTimer: number;\n\n /**\n * @class eg.view360.SpriteImage\n * @classdesc A module that displays a single or continuous image of any one of the \"sprite images\". SpinViewer internally uses SpriteImage to show each frame of the sprite image.\n * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다.\n * @extends eg.Component\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the \"Sprite image\". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n *\n * // Initialize SpriteImage\n *\n * var el = document.getElementById(\"image-div\");\n * var sprites = new eg.view360.SpriteImage(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24\n * });\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n const opt = options || {};\n\n this._el = element;\n this._rowCount = opt.rowCount || 1;\n this._colCount = opt.colCount || 1;\n this._totalCount = this._rowCount * this._colCount; // total frames\n this._width = opt.width || \"auto\";\n this._height = opt.height || \"auto\";\n this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten.\n this._colRow = [0, 0];\n\n if (opt.colRow) {\n this._colRow = opt.colRow;\n } else if (opt.frameIndex) {\n this.setFrameIndex(opt.frameIndex);\n }\n\n this._el.style.width = SpriteImage._getSizeString(this._width);\n this._el.style.height = SpriteImage._getSizeString(this._height);\n\n const wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS;\n const imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS;\n\n if (!opt.imageUrl) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n }, 0);\n return;\n }\n\n const imageInContainer = element.querySelector(`.${imageClass}`);\n const wrapperInContainer = element.querySelector(`.${wrapperClass}`);\n\n if (wrapperInContainer && imageInContainer) {\n // Set it to invisible to prevent wrapper being resized\n imageInContainer.style.display = \"none\";\n }\n\n this._image = imageInContainer || new Image();\n /**\n * Event\n */\n\n const image = this._image;\n\n image.onload = () => {\n if (wrapperInContainer && imageInContainer) {\n imageInContainer.style.display = \"\";\n }\n\n this._bg = SpriteImage._createBgDiv(\n wrapperInContainer,\n image,\n this._rowCount,\n this._colCount,\n this._autoHeight\n );\n this._el.appendChild(this._bg);\n this.setColRow(this._colRow[0], this._colRow[1]);\n\n this.trigger(new ComponentEvent(\"load\", {\n target: this._el,\n bgElement: this._bg\n }));\n\n if (this._autoPlayReservedInfo) {\n this.play(this._autoPlayReservedInfo);\n this._autoPlayReservedInfo = null;\n }\n };\n\n image.onerror = () => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n };\n\n image.src = opt.imageUrl;\n }\n\n /**\n * Specifies the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정\n * @method eg.view360.SpriteImage#setFrameIndex\n * @param {Number} frameIndex frame index of a frame프레임의 인덱스\n *\n * @example\n *\n * sprites.setFrameIndex(0, 1);// col = 0, row = 1\n */\n public setFrameIndex(index: number) {\n const colRow = this.toColRow(index);\n\n this.setColRow(colRow[0], colRow[1]);\n }\n\n /**\n * Returns the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환\n * @method eg.view360.SpriteImage#getFrameIndex\n * @return {Number} frame index frame 인덱스\n *\n * @example\n *\n * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1\n *\n */\n public getFrameIndex() {\n return this._colRow[1] * this._colCount + this._colRow[0];\n }\n\n /**\n * Specifies the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정\n * @method eg.view360.SpriteImage#setColRow\n * @param {Number} col Column number of a frame프레임의 행값\n * @param {Number} row Row number of a frame프레임의 열값\n *\n * @example\n *\n * sprites.setlColRow(1, 2); // col = 1, row = 2\n */\n public setColRow(col: number, row: number) {\n if (row > this._rowCount - 1 || col > this._colCount - 1) {\n return;\n }\n\n if (this._image && TRANSFORM) {\n // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser?\n this._image.style[TRANSFORM] = `translate(${-(col / this._colCount * 100)}%, ${-(row / this._rowCount * 100)}%)`;\n }\n\n this._colRow = [col, row];\n }\n\n /**\n * Returns the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환\n * @method eg.view360.SpriteImage#gelColRow\n * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열\n *\n * @example\n *\n * var colRow = sprites.getlColRow();\n * // colRow = [1, 2] - index of col is 1, index of row is 2\n *\n */\n public getColRow() {\n return this._colRow;\n }\n\n /**\n * Stop playing\n * @ko play 되고 있던 프레임 재생을 중지합니다.\n * @method eg.view360.SpriteImage#stop\n *\n * @example\n *\n * viewer.stop();\n *\n */\n public stop() {\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n }\n\n /**\n * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'.\n * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다.\n * @method eg.view360.SpriteImage#play\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위\n * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복\n *\n * @example\n *\n * viewer.play({angle: 16, playCount: 1});\n *\n */\n public play({ interval, playCount } = { interval: 1000 / this._totalCount, playCount: 0 }) {\n if (!this._bg) {\n this._autoPlayReservedInfo = {interval, playCount};\n return;\n }\n\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n\n let frameIndex = this.getFrameIndex();\n let count = 0;\n let frameCount = 0; // for checking 1 cycle\n\n this._autoPlayTimer = window.setInterval(() => {\n frameIndex %= this._totalCount;\n const colRow = this.toColRow(frameIndex);\n\n this.setColRow(colRow[0], colRow[1]);\n frameIndex++;\n\n // Done 1 Cycle?\n if (++frameCount === this._totalCount) {\n frameCount = 0;\n count++;\n }\n\n if (playCount > 0 && count === playCount) {\n clearInterval(this._autoPlayTimer);\n }\n }, interval);\n }\n\n public toColRow(frameIndex: number) {\n const colCount = this._colCount;\n const rowCount = this._rowCount;\n\n if (frameIndex < 0) {\n return [0, 0];\n } else if (frameIndex >= this._totalCount) {\n return [colCount - 1, rowCount - 1];\n }\n\n const col = frameIndex % colCount;\n const row = Math.floor(frameIndex / colCount);\n\n // console.log(frameIndex, col, row);\n return [col, row];\n }\n}\n\nexport default SpriteImage;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport { VERSION } from \"../version\";\nimport { AnimationEndEvent, ChangeEvent, ImageErrorEvent, LoadEvent } from \"../types/event\";\n\nimport SpriteImage from \"./SpriteImage\";\n\nconst DEFAULT_PAN_SCALE = 0.21;\n\nexport interface SpinViewerEvent {\n load: LoadEvent;\n imageError: ImageErrorEvent;\n change: ChangeEvent;\n animationEnd: AnimationEndEvent;\n}\n\nexport interface SpinViewerOptions {\n imageUrl: string;\n rowCount: number;\n colCount: number;\n width: number | string;\n height: number | string;\n autoHeight: boolean;\n colRow: number[];\n scale: number;\n frameIndex: number;\n wrapperClass: string;\n imageClass: string;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpinViewer\n */\nclass SpinViewer extends Component {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @static\n * @example\n * eg.view360.SpinViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.SpinViewer\n */\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _sprites: SpriteImage;\n private _axes: Axes;\n private _panInput: PanInput;\n\n private _scale: number;\n private _panScale: number;\n private _frameCount: number;\n\n /**\n * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object.\n * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다.\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값\n * @param {String} [options.wrapperClass=\"view360-wrapper\"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @param {String} [options.imageClass=\"view360-image\"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n * ```\n * // Initialize SpinViewer\n * var el = document.getElementById(\"product-360\");\n * var viewer = new eg.view360.SpinViewer(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24 //required\n * });\n * ```\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n\n this._el = element;\n\n const opt = {...options};\n const colCount = opt.colCount || 1;\n const rowCount = opt.rowCount || 1;\n\n this._scale = (opt.scale || 1);\n this._panScale = this._scale * DEFAULT_PAN_SCALE;\n\n this._frameCount = colCount * rowCount;\n\n // Init SpriteImage\n this._sprites = new SpriteImage(element, opt).on({\n \"load\": evt => {\n this.trigger(new ComponentEvent(\"load\", evt));\n },\n \"imageError\": evt => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: evt.imageUrl\n }));\n }\n });\n\n // Init Axes\n this._panInput = new PanInput(this._el, {\n scale: [this._panScale, this._panScale]\n });\n this._axes = new Axes({\n angle: {\n range: [0, 359],\n circular: true\n }\n }).on({\n \"change\": evt => {\n const curr = Math.floor(evt.pos.angle / (360 / this._frameCount));\n const frameIndex = this._frameCount - curr - 1;\n\n this._sprites.setFrameIndex(frameIndex);\n\n this.trigger(new ComponentEvent(\"change\", {\n frameIndex,\n colRow: this._sprites.getColRow(),\n angle: evt.pos.angle\n }));\n },\n \"animationEnd\": evt => {\n this.trigger(new ComponentEvent(\"animationEnd\", {\n isTrusted: evt.isTrusted\n }));\n }\n });\n\n this._axes.connect(\"angle\", this._panInput);\n }\n\n /**\n * Set spin scale\n * @ko scale 을 조정할 수 있는 함수\n * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.setScale(2);// It moves twice as much.\n */\n public setScale(scale: number) {\n if (isNaN(scale) || scale < 0) {\n return this;\n }\n\n this._scale = scale;\n this._panScale = scale * DEFAULT_PAN_SCALE;\n this._panInput.options.scale = [this._panScale, this._panScale];\n\n return this;\n }\n\n /**\n * Get spin scale\n * @ko scale 값을 반환한다.\n *\n * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @example\n * viewer.getScale();// It returns number\n */\n public getScale() {\n return this._scale;\n }\n\n /**\n * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle.\n * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle상대적 회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinBy(720, {duration: 500});\n */\n public spinBy(angle = 0, param = {duration: 0}) {\n this._axes.setBy({angle}, param.duration);\n return this;\n }\n\n /**\n * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle).\n * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinTo(30, {duration:100});\n */\n public spinTo(angle = 0, param = {duration: 0}) {\n this._axes.setTo({angle}, param.duration);\n return this;\n }\n\n /**\n * Returns current angles\n * @ko 현재 각도를 반환한다.\n *\n * @return {Number} Current angle 현재 각도\n */\n public getAngle() {\n return this._axes.get().angle || 0;\n }\n}\n\nexport default SpinViewer;\n","import PanoViewer, { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\n\nexport default (panoViewer: PanoViewer, newProps: Partial, prevProps: Partial) => {\n if (isPropChanged(newProps.image, prevProps.image)) {\n panoViewer.setImage(newProps.image, {\n projectionType: newProps.projectionType,\n cubemapConfig: newProps.cubemapConfig,\n stereoFormat: newProps.stereoFormat,\n isVideo: false\n });\n } else if (isPropChanged(newProps.video, prevProps.video)) {\n panoViewer.setVideo(newProps.video, {\n projectionType: newProps.projectionType,\n cubemapConfig: newProps.cubemapConfig,\n stereoFormat: newProps.stereoFormat\n });\n }\n\n const singleUpdateOptions: Array = [\n \"fovRange\",\n \"gyroMode\",\n \"pitchRange\",\n \"showPolePoint\",\n \"touchDirection\",\n \"useKeyboard\",\n \"useZoom\",\n \"yawRange\"\n ];\n\n singleUpdateOptions.forEach(optionName => {\n updateOption(panoViewer, optionName, newProps, prevProps);\n });\n};\n\nconst isPropChanged = (val: any, prevVal: any): val is true => val != null && val !== prevVal;\nconst updateOption = (panoViewer: PanoViewer, optionName: string, newProps: Partial, prevProps: Partial) => {\n if (isPropChanged(newProps[optionName], prevProps[optionName])) {\n panoViewer[`set${optionName[0].toUpperCase()}${optionName.slice(1)}`](newProps[optionName]);\n }\n};\n","import { PanoViewer } from \"../PanoViewer\";\n\nimport withMethods from \"./withMethods\";\n\nconst withPanoViewerMethods = (prototype: any, name: string) => {\n withMethods(PanoViewer, prototype, name);\n};\n\nexport default withPanoViewerMethods;\n","import { SpinViewer } from \"../SpinViewer\";\n\nimport withMethods from \"./withMethods\";\n\nconst withSpinViewerMethods = (prototype: any, name: string) => {\n withMethods(SpinViewer, prototype, name);\n};\n\nexport default withSpinViewerMethods;\n","export const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n\nexport const generateCanvasKey = (oldKey: number) => {\n let newKey: number;\n\n do {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n newKey = array[0];\n } while (newKey === oldKey);\n\n return newKey;\n};\n","/*\n * Copyright (c) 2017 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport * as PanoViewer from \"./PanoViewer\";\nimport * as SpinViewer from \"./SpinViewer\";\nimport * as CFC from \"./cfc\";\nimport { merge } from \"./utils/utils\";\n\nconst View360: any = {};\n\nmerge(View360, PanoViewer);\nmerge(View360, SpinViewer);\nmerge(View360, CFC);\n\nexport default View360;\n"],"names":["VERSION","win","window","Math","self","Function","doc","document","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","IS_IOS","IS_SAFARI_ON_DESKTOP","Float32Array","Array","getComputedStyle","toDegree","a","PI","userAgent","SUPPORT_TOUCH","SUPPORT_DEVICEMOTION","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","target","i","len","length","SUPPORT_WILLCHANGE","CSS","supports","WEBXR_SUPPORTED","checkXRSupport","xr","isSessionSupported","then","res","catch","supportsSession","util","n","extractPitchFromQuat","quaternion","baseV","vec3","fromValues","transformQuat","atan2","sqrt","pow","hypot","x","y","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","angleBetweenVec2","v1","v2","det","vec2","dot","yawOffsetBetween","viewDir","targetDir","viewDirXZ","targetDirXZ","normalize","sign","Number","getRotationDelta","prevQ","curQ","rotateKind","prevQuaternion","quat","clone","curQuaternion","prevPoint","curPoint","rotateDirection","cross","create","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","distance","abs","projectedPrevPoint","subtract","scale","trigonometricRatio","theta","acos","crossVec","thetaDirection","version","branch","build","match","exec","parseInt","r","CHROME_VERSION","IS_CHROME_WITHOUT_DEVICE_MOTION","IS_ANDROID","test","MC_BIND_SCALE","GYRO_MODE","NONE","YAWPITCH","VR","MathUtil","degToRad","radToDeg","Vector2","prototype","constructor","set","this","copy","v","subVectors","b","Vector3","z","scalar","invScalar","multiplyScalar","applyQuaternion","q","qx","qy","qz","qw","w","ix","iy","iz","iw","crossVectors","ax","ay","az","bx","by","bz","Quaternion","undefined","setFromEulerXYZ","c1","cos","c2","c3","s1","sin","s2","s3","setFromEulerYXZ","setFromAxisAngle","axis","angle","halfAngle","s","multiply","multiplyQuaternions","qax","qay","qaz","qaw","qbx","qby","qbz","qbw","inverse","l","slerp","qb","t","cosHalfTheta","halfTheta","sinHalfTheta","ratioA","ratioB","setFromUnitVectors","vFrom","vTo","isIOS","isWebViewAndroid","isSafari","isFirefoxAndroid","isR7","piOver180","rad45","defaultOrientation","defaultPosition","Util","updateEyeMatrices","projection","view","pose","parameters","vrDisplay","out","fov","fieldOfView","near","depthNear","far","depthFar","upTan","tan","upDegrees","downTan","downDegrees","leftTan","leftDegrees","rightTan","rightDegrees","xScale","yScale","a00","a01","a03","a10","a11","a12","a13","a20","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b07","b08","b09","b10","b11","orientation","position","xx","x2","xy","y2","xz","z2","yy","yz","zz","wx","wy","wz","offset","a02","a21","b06","MIN_TIMESTEP","MAX_TIMESTEP","base64","mimeType","clamp","value","min","max","lerp","platform","indexOf","isLandscapeMode","rtn","isTimestampDeltaValid","timestampDeltaS","isNaN","getScreenWidth","screen","width","height","getScreenHeight","requestFullscreen","element","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","exitFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","getFullscreenElement","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","linkProgram","gl","vertexSource","fragmentSource","attribLocationMap","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","attribName","program","createProgram","attachShader","bindAttribLocation","deleteShader","getProgramUniforms","uniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","uniformName","getActiveUniform","replace","getUniformLocation","orthoMatrix","left","right","bottom","top","lr","bt","nf","copyArray","source","dest","isMobile","check","vendor","opera","substr","extend","src","key","hasOwnProperty","safariCssSizeWorkaround","canvas","width_1","height_1","setTimeout","isDebug","getQueryParameter","results","RegExp","location","search","decodeURIComponent","frameDataFromPose","frameData","timestamp","leftProjectionMatrix","leftViewMatrix","getEyeParameters","rightProjectionMatrix","rightViewMatrix","isInsideCrossDomainIFrame","isFramed","refDomain","getDomainFromUrl","referrer","thisDomain","href","url","domain","split","predictionTimeS","previousQ","previousTimestampS","deltaQ","outQ","currentQ","gyro","timestampS","angularSpeed","console","log","toFixed","predictAngle","_super","_this","_onDeviceMotion","bind","_onDeviceOrientation","_onChromeWithoutDeviceMotion","isWithoutDeviceMotion","isAndroid","stillGyroVec","rawGyroVec","adjustedGyroVec","_timer","lastDevicemotionTimestamp","_isEnabled","enable","__extends","addEventListener","removeEventListener","e","alpha","beta","gamma","trigger","ComponentEvent","inputEvent","deviceorientation","clearTimeout","Date","getTime","isGyroSensorAvailable","rotationRate","isGravitySensorAvailable","accelerationIncludingGravity","interval","devicemotionEvent","__assign","timeStamp","type","acceleration","adjustedRotationRate","Component","sample","sensorSample","kFilter","vector","currentGyroMeasurement","deltaT","previousGyroMeasurement","run_","currentAccelMeasurement","SensorSample","filterQ","previousFilterQ","accelQ","isOrientationInitialized","estimatedGravity","measuredGravity","gyroIntegralQ","accelToQuaternion_","gyroDeltaQ","gyroToQuaternionDelta_","invFilterQ","getQuaternionAngle","targetQ","accel","normAccel","dt","ComplementaryFilter","isFilterQuaternionInitialized","getOrientation","deviceMotion","DeviceMotion","accelerometer","gyroscope","_onDeviceMotionChange","_onScreenOrientationChange","filter","posePredictor","PosePredictor","filterToWorldQ","isChromeUsingDegrees","inverseWorldToScreenQ","worldToScreenQ","originalPoseAdjustQ","_setScreenTransform","resetQ","on","isEnabled","disable","_deviceOrientationQ","deviceOrientationFixQ","_alpha","outQuat","_convertFusionToPredicted","_prevOrientation","equals","predictedQ","getPrediction","_a","accGravity","rotRate","_triggerChange","addAccelMeasurement","addGyroMeasurement","el","options","_prevQuaternion","_quaternion","fusionPoseSensor","threshold","_onPoseChange","axes","observer","FusionPoseSensor","_attachEvent","_dettachEvent","destroy","disconnect","event","prvQ","change","yawDeltaByYaw","reduce","acc","off","screenRotationAngleInst","refCount","_onOrientationChange","_spinR","_screenOrientationAngle","glMatrix","toRadian","betaR","gammaR","_useRotation","_screenRotationAngle","setUseRotation","useRotation","_userDirection","Axes","DIRECTION_ALL","unref","ScreenRotationAngle","_direction","DIRECTION_HORIZONTAL","connect","properties","useDirection","_getOffset","newOffset","getRadian","cosTheta","sinTheta","DIRECTION_VERTICAL","PanInput","Y_AXIS_VECTOR","_fusionPoseSensor","isTrusted","yaw","yawQ","setAxisAngle","conj","conjugate","DEFAULT_YAW_RANGE","DEFAULT_PITCH_RANGE","CIRCULAR_PITCH_RANGE","opt","pitch","showPolePoint","useZoom","useKeyboard","gyroMode","touchDirection","TOUCH_DIRECTION_YAW","yawRange","pitchRange","fovRange","aspectRatio","_element","_initialFov","_enabled","_isAnimating","_deviceQuaternion","_initAxes","option","param","_axes","get","areaHeight","_axesPanInput","deceleration","newValue","_getOptions","newOptions","changedKeyList","push","Object","keys","_setOptions","_getValidatedOptions","_applyOptions","updatePanScale","persistOrientation","_resetOrientation","duration","pos","p","f","maximumDuration","Infinity","setBy","yawPitch","getCombinedQuaternion","_axesWheelInput","_axesTiltMotionInput","_axesPinchInput","_axesMoveKeyInput","yRange","_updateYawRange","pRange","_updatePitchRange","RotationPanInput","WheelInput","PinchInput","MoveKeyInput","range","circular","_isCircular","bounce","hold","evt","delta","_updateControlScale","release","animationEnd","_getValidYawRange","_getValidPitchRange","arguments","prevFov","nextFov","isVR","isYawPitch","some","setTo","_initDeviceQuaternion","TiltMotionInput","_togglePinchInputByOption","_enableTouch","_inputs","direction","yawEnabled","pitchEnabled","DeviceQuaternion","newYawRange","newFov","newAspectRatio","ratio","_adjustAspectRatio","horizontalFov","newPitchRange","changeEvt","verticalAngle","halfFov","concat","halfHorizontalFov","mathUtil","targetElement","input","inputRange","outputRange","rangeIdx","inputA","inputB","outputA","outputB","_lerp","fraction","YawPitchControl","ERROR_TYPE","INVALID_DEVICE","NO_WEBGL","FAIL_IMAGE_LOAD","FAIL_BIND_TEXTURE","INVALID_RESOURCE","RENDERING_CONTEXT_LOST","PANOVIEWER_EVENTS","READY","VIEW_CHANGE","ANIMATION_END","ERROR","PROJECTION_TYPE","EQUIRECTANGULAR","CUBEMAP","CUBESTRIP","PANORAMA","STEREOSCOPIC_EQUI","STEREO_FORMAT","TOP_BOTTOM","LEFT_RIGHT","DEFAULT_CANVAS_CLASS","merge","_i","srcs","forEach","isArray","appendSourceElement","video","videoUrl","videoSrc","videoType","sourceElement","createElement","appendChild","WEBGL_ERROR_CODE","webglAvailability","WebGLUtils","shader","getShaderParameter","COMPILE_STATUS","error","getShaderInfoLog","LINK_STATUS","deleteProgram","data","itemSize","attr","buffer","createBuffer","bindBuffer","bufferData","STATIC_DRAW","numItems","enableVertexAttribArray","vertexAttribPointer","FLOAT","userContextAttributes","context","contextAttributes","preserveDrawingBuffer","antialias","onWebglcontextcreationerror","statusMessage","webglIdentifiers_1","__values","identifier","getContext","textureTarget","texture","createTexture","bindTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","loseContextExtension","webglContext","getWebglContext","getExtension","loseContext","agentInfo","isStableWebgl","parseFloat","code","pixels","texImage2D","RGBA","UNSIGNED_BYTE","getParameter","MAX_TEXTURE_SIZE","isIE11","majorVersion","EVENTS","_forceDimension","_pixelCanvas","_pixelContext","shaderProgram","indexBuffer","mvMatrix","pMatrix","uniformMatrix4fv","pMatrixUniform","mvMatrixUniform","drawElements","TRIANGLES","UNSIGNED_SHORT","pixelSource","naturalWidth","videoWidth","naturalHeight","videoHeight","image","forceDimension","HTMLVideoElement","getDimension","contentDimension","textureDimension","drawImage","imageConfig","tileConfig","map","config","flipHorizontal","rotation","message","Renderer","CubeRenderer","order","_VERTEX_POSITION_DATA","_INDEX_DATA","indexData","vertexPositionData","getVertexPositionData","extractOrder","base","_extractTileConfig","trim","face","floor","ordermap","shift","unshift","pop","tileVertex","slice","elemSize","tileTemp","j","splice","coord","_shrinkCoord","faceCoords","val","coords","orderMap","surfaceIdx","tileIdx","TEXTURE_CUBE_MAP_POSITIVE_X","maxCubeMapTextureSize","getMaxCubeMapTextureSize","tile","extractTileFromImage","_triggerError","TEXTURE_CUBE_MAP","updateTexture","inputTextureSize","outputTextureSize","getSourceTileSize","tilePerRow","MAX_CUBE_MAP_TEXTURE_SIZE","imageWidth","isPowerOfTwo","coordData","SHRINK_MULTIPLIER","axisMultipliers","axisIndex","axisDir","notSameDir","_vertices","textureSize","rows","c","tileConfigs","_transformCoord","index","TEXTURE_2D","_getPixelSource","size","maxSize","getMaxTextureSize","_initPixelSource","activeTexture","TEXTURE0","pixelStorei","UNPACK_FLIP_Y_WEBGL","newCoord","_flipHorizontalCoord","_rotateCoord","SHRINK_Y","SHRINK_X","rotationAngle","moved","shiftCount","ANGLE_CORRECTION_FOR_CENTER_ALIGN","textureCoordData","latIdx","lngIdx","phi","sinPhi","u","format","_stereoFormat","ctx","leftEyeScaleOffset","rightEyeScaleOffset","uTexScaleOffset","uniform4fv","render","SphereRenderer","_TEXTURE_COORD_DATA","CylinderRenderer","resizeDimension","rotated","cylinderMaxRadian","_b","imageAspectRatio","halfCylinderY","CYLIDER_Y","startAngleForCenterAlign","yIdx","yLength","VR_DISPLAY_PRESENT_CHANGE","DEFAULT_LEFT_BOUNDS","DEFAULT_RIGHT_BOUNDS","EYES","_vrDisplay","removeEndCallback","isPresenting","exitPresent","_clear","_frameData","VRFrameData","Boolean","bindFramebuffer","FRAMEBUFFER","submitFrame","display","halfWidth","drawingBufferWidth","drawingBufferHeight","getFrameData","leftMVMatrix","rightMVMatrix","mat4","rotateY","_yawOffset","viewport","callback","getVRDisplays","displays","capabilities","canPresent","requestPresent","leftEye","rightEye","renderWidth","renderHeight","_setDisplay","Promise","reject","Error","layers","getLayers","layer","_leftBounds","leftBounds","_rightBounds","rightBounds","addEndCallback","xrSession","_xrSession","end","_options","frame","getViewerPose","_xrRefSpace","baseLayer","session","renderState","framebuffer","glLayer","views","getViewport","transform","matrix","rotateX","projectionMatrix","_presenting","requiredFeatures","attributes","getContextAttributes","xrCompatible","makeXRCompatible","requestSession","xrLayer","XRWebGLLayer","updateRenderState","requestReferenceSpace","refSpace","_setSession","_xrLayer","args","_callback","_rafId","_context","requestAnimationFrame","_onLoop","before","performance","now","diff","_rafTimer","_onLoopNextTick","cancelAnimationFrame","ImageType","DEVICE_PIXEL_RATIO","withMethods","component","vanillaInstance","proto","getOwnPropertyNames","startsWith","getterDescriptor","descriptor","getOwnPropertyDescriptor","defineProperty","call","BIND_TEXTURE","IMAGE_LOADED","RENDERING_CONTEXT_RESTORE","RENDERER_ERROR","isVideo","container","canvasClass","sphericalConfig","renderingContextAttributes","vr","_vr","animator","_animator","exitVR","_restoreStyle","updateViewportDimensions","_updateViewport","_bindBuffers","_shouldForceDraw","stop","setContext","setCallback","_render","start","time","eyeParams","getEyeParams","beforeRender","eyeIndex","eyeParam","uniform1f","uEye","_draw","afterRender","minusZDir","canRender","mat3","fromMat4","mvInv","invert","pInv","transformMat3","yawOffset","setYawOffset","_renderStereo","_lastQuaternion","_lastYaw","_lastPitch","_lastFieldOfView","perspective","textureCoordBuffer","vertexBuffer","_initCanvas","_setDefaultCanvasStyle","_wrapper","_wrapperOrigStyle","_renderingContextAttributes","_image","_imageConfig","_imageIsReady","_keepUpdate","_onContentLoad","_onContentError","WebGLAnimator","setImage","imageType","cubemapConfig","yawPitchControl","_yawPitchControl","_isVideo","_setImageType","_contentLoader","ImReady","videoCandidate","video_1","setAttribute","querySelectorAll","readyState","load","toVideoElement","parsedImages","img","imgEl","Image","crossOrigin","toImageElement","rej","contentLoader","isReady","_bindTexture","once","errorCount","parentElement","_hasExternalCanvas","detach","hasRenderingContext","removeChild","forceContextLoss","_onWebglcontextlost","_onWebglcontextrestored","isContextLost","viewPortChanged","h","doUpdate","isImageLoaded","exactEquals","updateFieldOfView","fromQuat","identity","_renderer","resolve","_requestPresent","_imageType","_isCubeMap","CubeStripRenderer","stereoFormat","_initWebGL","canvasInContainer","querySelector","_createCanvas","className","margin","maxHeight","maxWidth","outline","content","projectionType","_triggerContentLoad","renderer","vsSource","getVertexShaderSource","fsSource","getFragmentShaderSource","getErrorNameFromWebGLErrorCode","getError","useProgram","vertexPositionAttribute","getAttribLocation","samplerUniform","textureCoordAttribute","clear","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","STENCIL_BUFFER_BIT","uniform1i","preventDefault","_initRenderingContext","_initShaderProgram","clearColor","deleteTexture","CULL_FACE","WebGLRenderingContext","getIndexData","getTextureCoordData","initBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","Uint16Array","isEAC","updateShaderData","_initBuffers","getFov","shouldRenderWithQuaternion","getQuaternion","renderWithQuaternion","getYawPitch","renderWithYawPitch","_updateTexture","XRManager","VRManager","_onFirstVRFrame","_setWrapperFullscreen","wrapper","getAttribute","wrapperStyle","zIndex","removeAttribute","PanoImageRenderer","isWebGLAvailable","isStableWebGL","_container","_projectionType","_cubemapConfig","_width","_height","_yaw","_pitch","_fov","_gyroMode","_aspectRatio","_canvasClass","PanoViewer","_isValidTouchDirection","TOUCH_DIRECTION_ALL","yawPitchConfig","_isReady","_initYawPitchControl","_initRenderer","onDeviceMotionChange","race","fb","TOUCH_DIRECTION","YAW","PITCH","ALL","_photoSphereRenderer","getContent","warn","_deactivate","keepUpdate","requestPermission","permissionState","enableSensor","enterVR","containerSize","lookAt","verticalAngleOfImage","initialYaw","initialPitch","setYawPitchControl","_bindRendererHandler","_activate","yawSize","maxFov","minFov","ProjectionType","atan","attachTo","_updateYawPitchIfNeeded","startRender","getVideo","pause","stopRender","TOUCH_DIRECTION_NONE","TOUCH_DIRECTION_PITCH","DEFAULT_WRAPPER_CLASS","DEFAULT_IMAGE_CLASS","_el","_rowCount","rowCount","_colCount","colCount","_totalCount","_autoHeight","autoHeight","_colRow","colRow","frameIndex","setFrameIndex","SpriteImage","_getSizeString","wrapperClass","imageClass","imageUrl","imageInContainer","wrapperInContainer","onload","_bg","_createBgDiv","setColRow","bgElement","_autoPlayReservedInfo","play","onerror","overflow","ondragstart","willChange","unitWidth","unitHeight","paddingBottom","toColRow","col","row","_autoPlayTimer","clearInterval","count","frameCount","playCount","getFrameIndex","setInterval","_scale","_panScale","_frameCount","_sprites","_panInput","curr","getColRow","SpinViewer","LOAD","IMAGE_ERROR","CHANGE","isPropChanged","prevVal","updateOption","panoViewer","optionName","newProps","prevProps","toUpperCase","setVideo","propsObj","props","propName","oldKey","newKey","array","Uint32Array","crypto","getRandomValues","View360","CFC"],"mappings":"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"} \ No newline at end of file diff --git a/dist/view360.pkgd.js b/dist/view360.pkgd.js new file mode 100644 index 000000000..f9917c54d --- /dev/null +++ b/dist/view360.pkgd.js @@ -0,0 +1,14855 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.eg = global.eg || {}, global.eg.view360 = factory())); +}(this, (function () { 'use strict'; + + var VERSION = "3.6.3"; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); + }; + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + function __generator(thisArg, body) { + var _ = { + label: 0, + sent: function () { + if (t[0] & 1) throw t[1]; + return t[1]; + }, + trys: [], + ops: [] + }, + f, + y, + t, + g; + return g = { + next: verb(0), + "throw": verb(1), + "return": verb(2) + }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; + + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + + switch (op[0]) { + case 0: + case 1: + t = op; + break; + + case 4: + _.label++; + return { + value: op[1], + done: false + }; + + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + + case 7: + op = _.ops.pop(); + + _.trys.pop(); + + continue; + + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + + if (t && _.label < t[2]) { + _.label = t[2]; + + _.ops.push(op); + + break; + } + + if (t[2]) _.ops.pop(); + + _.trys.pop(); + + continue; + } + + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + + if (op[0] & 5) throw op[1]; + return { + value: op[0] ? op[1] : void 0, + done: true + }; + } + } + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + + return ar; + } + + /* + Copyright (c) NAVER Corp. + name: @egjs/component + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-component + version: 3.0.1 + */ + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __values$1(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read$1(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + + return ar; + } + function __spread$1() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read$1(arguments[i])); + + return ar; + } + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + var isUndefined = function (value) { + return typeof value === "undefined"; + }; + + /** + * Event class to provide additional properties + * @ko Component에서 추가적인 프로퍼티를 제공하는 이벤트 클래스 + */ + + var ComponentEvent = + /*#__PURE__*/ + function () { + /** + * Create a new instance of ComponentEvent. + * @ko ComponentEvent의 새로운 인스턴스를 생성한다. + * @param eventType The name of the event.이벤트 이름. + * @param props An object that contains additional event properties.추가적인 이벤트 프로퍼티 오브젝트. + */ + function ComponentEvent(eventType, props) { + var e_1, _a; + + this.eventType = eventType; + this._canceled = false; + if (!props) return; + + try { + for (var _b = __values$1(Object.keys(props)), _c = _b.next(); !_c.done; _c = _b.next()) { + var key = _c.value; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + + this[key] = props[key]; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + } + /** + * Stop the event. {@link ComponentEvent#isCanceled} will return `true` after. + * @ko 이벤트를 중단한다. 이후 {@link ComponentEvent#isCanceled}가 `true`를 반환한다. + */ + + + var __proto = ComponentEvent.prototype; + + __proto.stop = function () { + this._canceled = true; + }; + /** + * Returns a boolean value that indicates whether {@link ComponentEvent#stop} is called before. + * @ko {@link ComponentEvent#stop}이 호출되었는지 여부를 반환한다. + * @return {boolean} A boolean value that indicates whether {@link ComponentEvent#stop} is called before.이전에 {@link ComponentEvent#stop}이 불려졌는지 여부를 반환한다. + */ + + + __proto.isCanceled = function () { + return this._canceled; + }; + + return ComponentEvent; + }(); + + /** + * A class used to manage events in a component + * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스 + */ + + var Component = + /*#__PURE__*/ + function () { + /** + * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"} + */ + function Component() { + this._eventHandler = {}; + } + /** + * Trigger a custom event. + * @ko 커스텀 이벤트를 발생시킨다 + * @param {string | ComponentEvent} event The name of the custom event to be triggered or an instance of the ComponentEvent발생할 커스텀 이벤트의 이름 또는 ComponentEvent의 인스턴스 + * @param {any[]} params Event data to be sent when triggering a custom event 커스텀 이벤트가 발생할 때 전달할 데이터 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * beforeHi: ComponentEvent<{ foo: number; bar: string }>; + * hi: { foo: { a: number; b: boolean } }; + * someEvent: (foo: number, bar: string) => void; + * someOtherEvent: void; // When there's no event argument + * }> { + * some(){ + * if(this.trigger("beforeHi")){ // When event call to stop return false. + * this.trigger("hi");// fire hi event. + * } + * } + * } + * + * const some = new Some(); + * some.on("beforeHi", e => { + * if(condition){ + * e.stop(); // When event call to stop, `hi` event not call. + * } + * // `currentTarget` is component instance. + * console.log(some === e.currentTarget); // true + * + * typeof e.foo; // number + * typeof e.bar; // string + * }); + * some.on("hi", e => { + * typeof e.foo.b; // boolean + * }); + * // If you want to more know event design. You can see article. + * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F + * ``` + */ + + + var __proto = Component.prototype; + + __proto.trigger = function (event) { + var params = []; + + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + + var eventName = event instanceof ComponentEvent ? event.eventType : event; + + var handlers = __spread$1(this._eventHandler[eventName] || []); + + if (handlers.length <= 0) { + return this; + } + + if (event instanceof ComponentEvent) { + event.currentTarget = this; + handlers.forEach(function (handler) { + handler(event); + }); + } else { + handlers.forEach(function (handler) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + handler.apply(void 0, __spread$1(params)); + }); + } + + return this; + }; + /** + * Executed event just one time. + * @ko 이벤트가 한번만 실행된다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: ComponentEvent; + * }> { + * hi() { + * alert("hi"); + * } + * thing() { + * this.once("hi", this.hi); + * } + * } + * + * var some = new Some(); + * some.thing(); + * some.trigger(new ComponentEvent("hi")); + * // fire alert("hi"); + * some.trigger(new ComponentEvent("hi")); + * // Nothing happens + * ``` + */ + + + __proto.once = function (eventName, handlerToAttach) { + var _this = this; + + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + + for (var key in eventHash) { + this.once(key, eventHash[key]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var listener_1 = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } // eslint-disable-next-line @typescript-eslint/no-unsafe-call + + + handlerToAttach.apply(void 0, __spread$1(args)); + + _this.off(eventName, listener_1); + }; + + this.on(eventName, listener_1); + } + + return this; + }; + /** + * Checks whether an event has been attached to a component. + * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다. + * @param {string} eventName The name of the event to be attached 등록 여부를 확인할 이벤트의 이름 + * @return {boolean} Indicates whether the event is attached. 이벤트 등록 여부 + * @example + * ```ts + * import Component from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * some() { + * this.hasOn("hi");// check hi event. + * } + * } + * ``` + */ + + + __proto.hasOn = function (eventName) { + return !!this._eventHandler[eventName]; + }; + /** + * Attaches an event to a component. + * @ko 컴포넌트에 이벤트를 등록한다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.on("hi",this.hi); //attach event + * } + * } + * ``` + */ + + + __proto.on = function (eventName, handlerToAttach) { + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + + for (var name in eventHash) { + this.on(name, eventHash[name]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var handlerList = this._eventHandler[eventName]; + + if (isUndefined(handlerList)) { + this._eventHandler[eventName] = []; + handlerList = this._eventHandler[eventName]; + } + + handlerList.push(handlerToAttach); + } + + return this; + }; + /** + * Detaches an event from the component.
If the `eventName` is not given this will detach all event handlers attached.
If the `handlerToDetach` is not given, this will detach all event handlers for `eventName`. + * @ko 컴포넌트에 등록된 이벤트를 해제한다.
`eventName`이 주어지지 않았을 경우 모든 이벤트 핸들러를 제거한다.
`handlerToAttach`가 주어지지 않았을 경우 `eventName`에 해당하는 모든 이벤트 핸들러를 제거한다. + * @param {string?} eventName The name of the event to be detached 해제할 이벤트의 이름 + * @param {function?} handlerToDetach The handler function of the event to be detached 해제할 이벤트의 핸들러 함수 + * @return An instance of a component itself 컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.off("hi",this.hi); //detach event + * } + * } + * ``` + */ + + + __proto.off = function (eventName, handlerToDetach) { + var e_1, _a; // Detach all event handlers. + + + if (isUndefined(eventName)) { + this._eventHandler = {}; + return this; + } // Detach all handlers for eventname or detach event handlers by object. + + + if (isUndefined(handlerToDetach)) { + if (typeof eventName === "string") { + delete this._eventHandler[eventName]; + return this; + } else { + var eventHash = eventName; + + for (var name in eventHash) { + this.off(name, eventHash[name]); + } + + return this; + } + } // Detach single event handler + + + var handlerList = this._eventHandler[eventName]; + + if (handlerList) { + var idx = 0; + + try { + for (var handlerList_1 = __values$1(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) { + var handlerFunction = handlerList_1_1.value; + + if (handlerFunction === handlerToDetach) { + handlerList.splice(idx, 1); + + if (handlerList.length <= 0) { + delete this._eventHandler[eventName]; + } + + break; + } + + idx++; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1); + } finally { + if (e_1) throw e_1.error; + } + } + } + + return this; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @example + * Component.VERSION; // ex) 3.0.0 + * @memberof Component + */ + + + Component.VERSION = "3.0.1"; + return Component; + }(); + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + var ComponentEvent$1 = ComponentEvent; + + /** + * @this {Promise} + */ + function finallyConstructor(callback) { + var constructor = this.constructor; + return this.then( + function(value) { + // @ts-ignore + return constructor.resolve(callback()).then(function() { + return value; + }); + }, + function(reason) { + // @ts-ignore + return constructor.resolve(callback()).then(function() { + // @ts-ignore + return constructor.reject(reason); + }); + } + ); + } + + function allSettled(arr) { + var P = this; + return new P(function(resolve, reject) { + if (!(arr && typeof arr.length !== 'undefined')) { + return reject( + new TypeError( + typeof arr + + ' ' + + arr + + ' is not iterable(cannot read property Symbol(Symbol.iterator))' + ) + ); + } + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return resolve([]); + var remaining = args.length; + + function res(i, val) { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then; + if (typeof then === 'function') { + then.call( + val, + function(val) { + res(i, val); + }, + function(e) { + args[i] = { status: 'rejected', reason: e }; + if (--remaining === 0) { + resolve(args); + } + } + ); + return; + } + } + args[i] = { status: 'fulfilled', value: val }; + if (--remaining === 0) { + resolve(args); + } + } + + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + } + + // Store setTimeout reference so promise-polyfill will be unaffected by + // other code modifying setTimeout (like sinon.useFakeTimers()) + var setTimeoutFunc = setTimeout; + + function isArray(x) { + return Boolean(x && typeof x.length !== 'undefined'); + } + + function noop() {} + + // Polyfill for Function.prototype.bind + function bind(fn, thisArg) { + return function() { + fn.apply(thisArg, arguments); + }; + } + + /** + * @constructor + * @param {Function} fn + */ + function Promise$1(fn) { + if (!(this instanceof Promise$1)) + throw new TypeError('Promises must be constructed via new'); + if (typeof fn !== 'function') throw new TypeError('not a function'); + /** @type {!number} */ + this._state = 0; + /** @type {!boolean} */ + this._handled = false; + /** @type {Promise|undefined} */ + this._value = undefined; + /** @type {!Array} */ + this._deferreds = []; + + doResolve(fn, this); + } + + function handle(self, deferred) { + while (self._state === 3) { + self = self._value; + } + if (self._state === 0) { + self._deferreds.push(deferred); + return; + } + self._handled = true; + Promise$1._immediateFn(function() { + var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + (self._state === 1 ? resolve : reject)(deferred.promise, self._value); + return; + } + var ret; + try { + ret = cb(self._value); + } catch (e) { + reject(deferred.promise, e); + return; + } + resolve(deferred.promise, ret); + }); + } + + function resolve(self, newValue) { + try { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) + throw new TypeError('A promise cannot be resolved with itself.'); + if ( + newValue && + (typeof newValue === 'object' || typeof newValue === 'function') + ) { + var then = newValue.then; + if (newValue instanceof Promise$1) { + self._state = 3; + self._value = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(bind(then, newValue), self); + return; + } + } + self._state = 1; + self._value = newValue; + finale(self); + } catch (e) { + reject(self, e); + } + } + + function reject(self, newValue) { + self._state = 2; + self._value = newValue; + finale(self); + } + + function finale(self) { + if (self._state === 2 && self._deferreds.length === 0) { + Promise$1._immediateFn(function() { + if (!self._handled) { + Promise$1._unhandledRejectionFn(self._value); + } + }); + } + + for (var i = 0, len = self._deferreds.length; i < len; i++) { + handle(self, self._deferreds[i]); + } + self._deferreds = null; + } + + /** + * @constructor + */ + function Handler(onFulfilled, onRejected, promise) { + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; + } + + /** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ + function doResolve(fn, self) { + var done = false; + try { + fn( + function(value) { + if (done) return; + done = true; + resolve(self, value); + }, + function(reason) { + if (done) return; + done = true; + reject(self, reason); + } + ); + } catch (ex) { + if (done) return; + done = true; + reject(self, ex); + } + } + + Promise$1.prototype['catch'] = function(onRejected) { + return this.then(null, onRejected); + }; + + Promise$1.prototype.then = function(onFulfilled, onRejected) { + // @ts-ignore + var prom = new this.constructor(noop); + + handle(this, new Handler(onFulfilled, onRejected, prom)); + return prom; + }; + + Promise$1.prototype['finally'] = finallyConstructor; + + Promise$1.all = function(arr) { + return new Promise$1(function(resolve, reject) { + if (!isArray(arr)) { + return reject(new TypeError('Promise.all accepts an array')); + } + + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return resolve([]); + var remaining = args.length; + + function res(i, val) { + try { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then; + if (typeof then === 'function') { + then.call( + val, + function(val) { + res(i, val); + }, + reject + ); + return; + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex); + } + } + + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); + }; + + Promise$1.allSettled = allSettled; + + Promise$1.resolve = function(value) { + if (value && typeof value === 'object' && value.constructor === Promise$1) { + return value; + } + + return new Promise$1(function(resolve) { + resolve(value); + }); + }; + + Promise$1.reject = function(value) { + return new Promise$1(function(resolve, reject) { + reject(value); + }); + }; + + Promise$1.race = function(arr) { + return new Promise$1(function(resolve, reject) { + if (!isArray(arr)) { + return reject(new TypeError('Promise.race accepts an array')); + } + + for (var i = 0, len = arr.length; i < len; i++) { + Promise$1.resolve(arr[i]).then(resolve, reject); + } + }); + }; + + // Use polyfill for setImmediate for performance gains + Promise$1._immediateFn = + // @ts-ignore + (typeof setImmediate === 'function' && + function(fn) { + // @ts-ignore + setImmediate(fn); + }) || + function(fn) { + setTimeoutFunc(fn, 0); + }; + + Promise$1._unhandledRejectionFn = function _unhandledRejectionFn(err) { + if (typeof console !== 'undefined' && console) { + console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console + } + }; + + /* + Copyright (c) 2015 NAVER Corp. + name: @egjs/agent + license: MIT + author: NAVER Corp. + repository: git+https://github.com/naver/agent.git + version: 2.2.1 + */ + function some(arr, callback) { + var length = arr.length; + + for (var i = 0; i < length; ++i) { + if (callback(arr[i], i)) { + return true; + } + } + + return false; + } + function find(arr, callback) { + var length = arr.length; + + for (var i = 0; i < length; ++i) { + if (callback(arr[i], i)) { + return arr[i]; + } + } + + return null; + } + function getUserAgent(agent) { + var userAgent = agent; + + if (typeof userAgent === "undefined") { + if (typeof navigator === "undefined" || !navigator) { + return ""; + } + + userAgent = navigator.userAgent || ""; + } + + return userAgent.toLowerCase(); + } + function execRegExp(pattern, text) { + try { + return new RegExp(pattern, "g").exec(text); + } catch (e) { + return null; + } + } + function hasUserAgentData() { + if (typeof navigator === "undefined" || !navigator || !navigator.userAgentData) { + return false; + } + + var userAgentData = navigator.userAgentData; + var brands = userAgentData.brands || userAgentData.uaList; + return !!(brands && brands.length); + } + function findVersion(versionTest, userAgent) { + var result = execRegExp("(" + versionTest + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent); + return result ? result[3] : ""; + } + function convertVersion(text) { + return text.replace(/_/g, "."); + } + function findPreset(presets, userAgent) { + var userPreset = null; + var version = "-1"; + some(presets, function (preset) { + var result = execRegExp("(" + preset.test + ")((?:\\/|\\s|:)([0-9|\\.|_]+))?", userAgent); + + if (!result || preset.brand) { + return false; + } + + userPreset = preset; + version = result[3] || "-1"; + + if (preset.versionAlias) { + version = preset.versionAlias; + } else if (preset.versionTest) { + version = findVersion(preset.versionTest.toLowerCase(), userAgent) || version; + } + + version = convertVersion(version); + return true; + }); + return { + preset: userPreset, + version: version + }; + } + function findBrand(brands, preset) { + return find(brands, function (_a) { + var brand = _a.brand; + return execRegExp("" + preset.test, brand.toLowerCase()); + }); + } + + var BROWSER_PRESETS = [{ + test: "phantomjs", + id: "phantomjs" + }, { + test: "whale", + id: "whale" + }, { + test: "edgios|edge|edg", + id: "edge" + }, { + test: "msie|trident|windows phone", + id: "ie", + versionTest: "iemobile|msie|rv" + }, { + test: "miuibrowser", + id: "miui browser" + }, { + test: "samsungbrowser", + id: "samsung internet" + }, { + test: "samsung", + id: "samsung internet", + versionTest: "version" + }, { + test: "chrome|crios", + id: "chrome" + }, { + test: "firefox|fxios", + id: "firefox" + }, { + test: "android", + id: "android browser", + versionTest: "version" + }, { + test: "safari|iphone|ipad|ipod", + id: "safari", + versionTest: "version" + }]; // chromium's engine(blink) is based on applewebkit 537.36. + + var CHROMIUM_PRESETS = [{ + test: "(?=.*applewebkit/(53[0-7]|5[0-2]|[0-4]))(?=.*\\schrome)", + id: "chrome" + }, { + test: "chromium", + id: "chrome" + }, { + test: "whale", + id: "chrome", + brand: true + }]; + var WEBKIT_PRESETS = [{ + test: "applewebkit", + id: "webkit" + }]; + var WEBVIEW_PRESETS = [{ + test: "(?=(iphone|ipad))(?!(.*version))", + id: "webview" + }, { + test: "(?=(android|iphone|ipad))(?=.*(naver|daum|; wv))", + id: "webview" + }, { + // test webview + test: "webview", + id: "webview" + }]; + var OS_PRESETS = [{ + test: "windows phone", + id: "windows phone" + }, { + test: "windows 2000", + id: "window", + versionAlias: "5.0" + }, { + test: "windows nt", + id: "window" + }, { + test: "iphone|ipad|ipod", + id: "ios", + versionTest: "iphone os|cpu os" + }, { + test: "mac os x", + id: "mac" + }, { + test: "android", + id: "android" + }, { + test: "tizen", + id: "tizen" + }, { + test: "webos|web0s", + id: "webos" + }]; + + function parseUserAgentData(osData) { + var userAgentData = navigator.userAgentData; + var brands = (userAgentData.uaList || userAgentData.brands).slice(); + var isMobile = userAgentData.mobile || false; + var firstBrand = brands[0]; + var browser = { + name: firstBrand.brand, + version: firstBrand.version, + majorVersion: -1, + webkit: false, + webview: some(WEBVIEW_PRESETS, function (preset) { + return findBrand(brands, preset); + }), + chromium: some(CHROMIUM_PRESETS, function (preset) { + return findBrand(brands, preset); + }) + }; + var os = { + name: "unknown", + version: "-1", + majorVersion: -1 + }; + browser.webkit = !browser.chromium && some(WEBKIT_PRESETS, function (preset) { + return findBrand(brands, preset); + }); + + if (osData) { + var platform_1 = osData.platform.toLowerCase(); + var result = find(OS_PRESETS, function (preset) { + return new RegExp("" + preset.test, "g").exec(platform_1); + }); + os.name = result ? result.id : platform_1; + os.version = osData.platformVersion; + } + + some(BROWSER_PRESETS, function (preset) { + var result = findBrand(brands, preset); + + if (!result) { + return false; + } + + browser.name = preset.id; + browser.version = osData ? osData.uaFullVersion : result.version; + return true; + }); + + if (navigator.platform === "Linux armv8l") { + os.name = "android"; + } else if (browser.webkit) { + os.name = isMobile ? "ios" : "mac"; + } + + if (os.name === "ios" && browser.webview) { + browser.version = "-1"; + } + + os.version = convertVersion(os.version); + browser.version = convertVersion(browser.version); + os.majorVersion = parseInt(os.version, 10); + browser.majorVersion = parseInt(browser.version, 10); + return { + browser: browser, + os: os, + isMobile: isMobile, + isHints: true + }; + } + + function parseUserAgent(userAgent) { + var nextAgent = getUserAgent(userAgent); + var isMobile = !!/mobi/g.exec(nextAgent); + var browser = { + name: "unknown", + version: "-1", + majorVersion: -1, + webview: !!findPreset(WEBVIEW_PRESETS, nextAgent).preset, + chromium: !!findPreset(CHROMIUM_PRESETS, nextAgent).preset, + webkit: false + }; + var os = { + name: "unknown", + version: "-1", + majorVersion: -1 + }; + + var _a = findPreset(BROWSER_PRESETS, nextAgent), + browserPreset = _a.preset, + browserVersion = _a.version; + + var _b = findPreset(OS_PRESETS, nextAgent), + osPreset = _b.preset, + osVersion = _b.version; + + browser.webkit = !browser.chromium && !!findPreset(WEBKIT_PRESETS, nextAgent).preset; + + if (osPreset) { + os.name = osPreset.id; + os.version = osVersion; + os.majorVersion = parseInt(osVersion, 10); + } + + if (browserPreset) { + browser.name = browserPreset.id; + browser.version = browserVersion; + + if (browser.webview && os.name === "ios" && browser.name !== "safari") { + browser.webview = false; + } + } + + browser.majorVersion = parseInt(browser.version, 10); + return { + browser: browser, + os: os, + isMobile: isMobile, + isHints: false + }; + } + /** + * Extracts browser and operating system information from the user agent string. + * @ko 유저 에이전트 문자열에서 브라우저와 운영체제 정보를 추출한다. + * @function eg.agent#agent + * @param - user agent string to parse 파싱할 유저에이전트 문자열 + * @return - agent Info 에이전트 정보 + * @example + import agent from "@egjs/agent"; + // eg.agent(); + const { os, browser, isMobile } = agent(); + */ + + function agent(userAgent) { + if (typeof userAgent === "undefined" && hasUserAgentData()) { + return parseUserAgentData(); + } else { + return parseUserAgent(userAgent); + } + } + + /* eslint-disable @typescript-eslint/no-implied-eval */ + /* eslint-disable no-new-func, no-nested-ternary */ + + var win = typeof window !== "undefined" && window.Math === Math ? window : typeof self !== "undefined" && self.Math === Math ? self : Function("return this")(); + /* eslint-enable no-new-func, no-nested-ternary */ + + var doc = win.document; + var nav = win.navigator; + var agent$1 = agent(); + var osName = agent$1.os.name; + var browserName = agent$1.browser.name; + var IS_IOS = osName === "ios"; + var IS_SAFARI_ON_DESKTOP = osName === "mac" && browserName === "safari"; + + /* eslint-disable @typescript-eslint/naming-convention */ + win.Float32Array = typeof win.Float32Array !== "undefined" ? win.Float32Array : win.Array; + var Float32Array$1 = win.Float32Array; + var getComputedStyle = win.getComputedStyle; + var userAgent = win.navigator && win.navigator.userAgent; + var SUPPORT_TOUCH = ("ontouchstart" in win); + var SUPPORT_DEVICEMOTION = ("ondevicemotion" in win); + var DeviceMotionEvent = win.DeviceMotionEvent; + var devicePixelRatio = win.devicePixelRatio; + + var TRANSFORM = function () { + var _a; + + var docStyle = (_a = doc === null || doc === void 0 ? void 0 : doc.documentElement.style) !== null && _a !== void 0 ? _a : {}; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in docStyle) { + return target[i]; + } + } + + return ""; + }(); // check for will-change support + + + var SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports && win.CSS.supports("will-change", "transform"); + var WEBXR_SUPPORTED = false; + + var checkXRSupport = function () { + var navigator = window.navigator; + + if (!navigator.xr) { + return; + } + + if (navigator.xr.isSessionSupported) { + navigator.xr.isSessionSupported("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } else if (navigator.xr.supportsSession) { + navigator.xr.supportsSession("immersive-vr").then(function (res) { + WEBXR_SUPPORTED = res; + }).catch(function () { + return void 0; + }); + } + }; + + /* + Copyright (c) 2015 NAVER Corp. + name: @egjs/axes + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-axes + version: 3.3.0 + */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics$1 = function (d, b) { + extendStatics$1 = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + }; + + return extendStatics$1(d, b); + }; + + function __extends$1(d, b) { + extendStatics$1(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign$1 = function () { + __assign$1 = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign$1.apply(this, arguments); + }; + + /* eslint-disable no-new-func, no-nested-ternary */ + var win$1; + + if (typeof window === "undefined") { + // window is undefined in node.js + win$1 = { + navigator: { + userAgent: "" + } + }; + } else { + win$1 = window; + } + + var DIRECTION_NONE = 1; + var DIRECTION_LEFT = 2; + var DIRECTION_RIGHT = 4; + var DIRECTION_HORIZONTAL = 2 | 4; + var DIRECTION_UP = 8; + var DIRECTION_DOWN = 16; + var DIRECTION_VERTICAL = 8 | 16; + var DIRECTION_ALL = 2 | 4 | 8 | 16; + var MOUSE_LEFT = "left"; + var MOUSE_RIGHT = "right"; + var MOUSE_MIDDLE = "middle"; + var VELOCITY_INTERVAL = 16; + var IOS_EDGE_THRESHOLD = 30; + var IS_IOS_SAFARI = "ontouchstart" in win$1 && agent().browser.name === "safari"; + var TRANSFORM$1 = function () { + if (typeof document === "undefined") { + return ""; + } + + var bodyStyle = (document.head || document.getElementsByTagName("head")[0]).style; + var target = ["transform", "webkitTransform", "msTransform", "mozTransform"]; + + for (var i = 0, len = target.length; i < len; i++) { + if (target[i] in bodyStyle) { + return target[i]; + } + } + + return ""; + }(); + var PREVENT_DRAG_CSSPROPS = { + "user-select": "none", + "-webkit-user-drag": "none" + }; + + var toArray = function (nodes) { + // const el = Array.prototype.slice.call(nodes); + // for IE8 + var el = []; + + for (var i = 0, len = nodes.length; i < len; i++) { + el.push(nodes[i]); + } + + return el; + }; + var $ = function (param, multi) { + if (multi === void 0) { + multi = false; + } + + var el; + + if (typeof param === "string") { + // String (HTML, Selector) + // check if string is HTML tag format + var match = param.match(/^<([a-z]+)\s*([^>]*)>/); // creating element + + if (match) { + // HTML + var dummy = document.createElement("div"); + dummy.innerHTML = param; + el = toArray(dummy.childNodes); + } else { + // Selector + el = toArray(document.querySelectorAll(param)); + } + + if (!multi) { + el = el.length >= 1 ? el[0] : undefined; + } + } else if (param === win$1) { + // window + el = param; + } else if (param.nodeName && (param.nodeType === 1 || param.nodeType === 9)) { + // HTMLElement, Document + el = param; + } else if ("jQuery" in win$1 && param instanceof jQuery || param.constructor.prototype.jquery) { + // jQuery + el = multi ? param.toArray() : param.get(0); + } else if (Array.isArray(param)) { + el = param.map(function (v) { + return $(v); + }); + + if (!multi) { + el = el.length >= 1 ? el[0] : undefined; + } + } + + return el; + }; + var raf = win$1.requestAnimationFrame || win$1.webkitRequestAnimationFrame; + var caf = win$1.cancelAnimationFrame || win$1.webkitCancelAnimationFrame; + + if (raf && !caf) { + var keyInfo_1 = {}; + var oldraf_1 = raf; + + raf = function (callback) { + var wrapCallback = function (timestamp) { + if (keyInfo_1[key]) { + callback(timestamp); + } + }; + + var key = oldraf_1(wrapCallback); + keyInfo_1[key] = true; + return key; + }; + + caf = function (key) { + delete keyInfo_1[key]; + }; + } else if (!(raf && caf)) { + raf = function (callback) { + return win$1.setTimeout(function () { + callback(win$1.performance && win$1.performance.now && win$1.performance.now() || new Date().getTime()); + }, 16); + }; + + caf = win$1.clearTimeout; + } + /** + * A polyfill for the window.requestAnimationFrame() method. + * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame + * @private + */ + + + var requestAnimationFrame = function (fp) { + return raf(fp); + }; + /** + * A polyfill for the window.cancelAnimationFrame() method. It cancels an animation executed through a call to the requestAnimationFrame() method. + * @param {Number} key − The ID value returned through a call to the requestAnimationFrame() method. requestAnimationFrame() 메서드가 반환한 아이디 값 + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/cancelAnimationFrame + * @private + */ + + var cancelAnimationFrame = function (key) { + caf(key); + }; + var map = function (obj, callback) { + var tranformed = {}; + + for (var k in obj) { + if (k) { + tranformed[k] = callback(obj[k], k); + } + } + + return tranformed; + }; + var filter = function (obj, callback) { + var filtered = {}; + + for (var k in obj) { + if (k && callback(obj[k], k)) { + filtered[k] = obj[k]; + } + } + + return filtered; + }; + var every = function (obj, callback) { + for (var k in obj) { + if (k && !callback(obj[k], k)) { + return false; + } + } + + return true; + }; + var equal = function (target, base) { + return every(target, function (v, k) { + return v === base[k]; + }); + }; + var roundNumFunc = {}; + var roundNumber = function (num, roundUnit) { + // Cache for performance + if (!roundNumFunc[roundUnit]) { + roundNumFunc[roundUnit] = getRoundFunc(roundUnit); + } + + return roundNumFunc[roundUnit](num); + }; + var roundNumbers = function (num, roundUnit) { + if (!num || !roundUnit) { + return num; + } + + return map(num, function (value, key) { + return roundNumber(value, typeof roundUnit === "number" ? roundUnit : roundUnit[key]); + }); + }; + var getDecimalPlace = function (val) { + if (!isFinite(val)) { + return 0; + } + + var v = "" + val; + + if (v.indexOf("e") >= 0) { + // Exponential Format + // 1e-10, 1e-12 + var p = 0; + var e = 1; + + while (Math.round(val * e) / e !== val) { + e *= 10; + p++; + } + + return p; + } // In general, following has performance benefit. + // https://jsperf.com/precision-calculation + + + return v.indexOf(".") >= 0 ? v.length - v.indexOf(".") - 1 : 0; + }; + var inversePow = function (n) { + // replace Math.pow(10, -n) to solve floating point issue. + // eg. Math.pow(10, -4) => 0.00009999999999999999 + return 1 / Math.pow(10, n); + }; + var getRoundFunc = function (v) { + var p = v < 1 ? Math.pow(10, getDecimalPlace(v)) : 1; + return function (n) { + if (v === 0) { + return 0; + } + + return Math.round(Math.round(n / v) * v * p) / p; + }; + }; + var getAngle = function (posX, posY) { + return Math.atan2(posY, posX) * 180 / Math.PI; + }; + var isCssPropsFromAxes = function (originalCssProps) { + var same = true; + Object.keys(PREVENT_DRAG_CSSPROPS).forEach(function (prop) { + if (!originalCssProps || originalCssProps[prop] !== PREVENT_DRAG_CSSPROPS[prop]) { + same = false; + } + }); + return same; + }; + var setCssProps = function (element, option, direction) { + var _a; + + var touchActionMap = (_a = {}, _a[DIRECTION_NONE] = "auto", _a[DIRECTION_ALL] = "none", _a[DIRECTION_VERTICAL] = "pan-x", _a[DIRECTION_HORIZONTAL] = "pan-y", _a); + var oldCssProps = {}; + + if (element && element.style) { + var touchAction = option.touchAction ? option.touchAction : touchActionMap[direction]; + + var newCssProps_1 = __assign$1(__assign$1({}, PREVENT_DRAG_CSSPROPS), { + "touch-action": element.style["touch-action"] === "none" ? "none" : touchAction + }); + + Object.keys(newCssProps_1).forEach(function (prop) { + oldCssProps[prop] = element.style[prop]; + element.style[prop] = newCssProps_1[prop]; + }); + } + + return oldCssProps; + }; + var revertCssProps = function (element, originalCssProps) { + if (element && element.style && originalCssProps) { + Object.keys(originalCssProps).forEach(function (prop) { + element.style[prop] = originalCssProps[prop]; + }); + } + + return; + }; + + var EventManager = + /*#__PURE__*/ + function () { + function EventManager(_axes) { + this._axes = _axes; + } + /** + * This event is fired when a user holds an element on the screen of the device. + * @ko 사용자가 기기의 화면에 손을 대고 있을 때 발생하는 이벤트 + * @event Axes#hold + * @type {object} + * @property {Object.} pos coordinate 좌표 정보 + * @property {Object} input The instance of inputType where the event occurred이벤트가 발생한 inputType 인스턴스 + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("hold", function(event) { + * // event.pos + * // event.input + * // event.inputEvent + * // isTrusted + * }); + * ``` + */ + + + var __proto = EventManager.prototype; + + __proto.hold = function (pos, option) { + var roundPos = this._getRoundPos(pos).roundPos; + + this._axes.trigger(new ComponentEvent$1("hold", { + pos: roundPos, + input: option.input || null, + inputEvent: option.event || null, + isTrusted: true + })); + }; + /** + * Specifies the coordinates to move after the 'change' event. It works when the holding value of the change event is true. + * @ko 'change' 이벤트 이후 이동할 좌표를 지정한다. change이벤트의 holding 값이 true일 경우에 동작한다 + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("change", function(event) { + * event.holding && event.set({x: 10}); + * }); + * ``` + */ + + /** Specifies the animation coordinates to move after the 'release' or 'animationStart' events. + * @ko 'release' 또는 'animationStart' 이벤트 이후 이동할 좌표를 지정한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("animationStart", function(event) { + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + /** + * This event is fired when a user release an element on the screen of the device. + * @ko 사용자가 기기의 화면에서 손을 뗐을 때 발생하는 이벤트 + * @event Axes#release + * @type {object} + * @property {Object.} depaPos The coordinates when releasing an element손을 뗐을 때의 좌표 + * @property {Object.} destPos The coordinates to move to after releasing an element손을 뗀 뒤에 이동할 좌표 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Object.} bounceRatio If the coordinates at the time of release are in the bounce area, the current bounce value divided by the maximum bounce value 손을 뗐을 때의 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치. + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {Object} input The instance of inputType where the event occurred이벤트가 발생한 inputType 인스턴스 + * @property {setTo} setTo Specifies the animation coordinates to move after the event 이벤트 이후 이동할 애니메이션 좌표를 지정한다 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("release", function(event) { + * // event.depaPos + * // event.destPos + * // event.delta + * // event.input + * // event.inputEvent + * // event.setTo + * // event.isTrusted + * + * // if you want to change the animation coordinates to move after the 'release' event. + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + + __proto.triggerRelease = function (param) { + var _a = this._getRoundPos(param.destPos, param.depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + param.destPos = roundPos; + param.depaPos = roundDepa; + param.setTo = this._createUserControll(param.destPos, param.duration); + + this._axes.trigger(new ComponentEvent$1("release", __assign$1(__assign$1({}, param), { + bounceRatio: this._getBounceRatio(roundPos) + }))); + }; + /** + * This event is fired when coordinate changes. + * @ko 좌표가 변경됐을 때 발생하는 이벤트 + * @event Axes#change + * @type {object} + * @property {Object.} pos The coordinate 좌표 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Object.} bounceRatio If the current coordinates are in the bounce area, the current bounce value divided by the maximum bounce value 현재 좌표가 bounce 영역에 있는 경우 현재 bounce된 값을 최대 bounce 값으로 나눈 수치. + * @property {Boolean} holding Indicates whether a user holds an element on the screen of the device.사용자가 기기의 화면을 누르고 있는지 여부 + * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {Object} inputEvent The event object received from inputType. If the value is changed by animation, it returns 'null'.inputType으로 부터 받은 이벤트 객체. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {set} set Specifies the coordinates to move after the event. It works when the holding value is true 이벤트 이후 이동할 좌표를 지정한다. holding 값이 true일 경우에 동작한다. + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("change", function(event) { + * // event.pos + * // event.delta + * // event.input + * // event.inputEvent + * // event.holding + * // event.set + * // event.isTrusted + * + * // if you want to change the coordinates to move after the 'change' event. + * // it works when the holding value of the change event is true. + * event.holding && event.set({x: 10}); + * }); + * ``` + */ + + + __proto.triggerChange = function (pos, depaPos, option, holding) { + if (holding === void 0) { + holding = false; + } + + var animationManager = this.animationManager; + var axisManager = animationManager.axisManager; + var eventInfo = animationManager.getEventInfo(); + + var _a = this._getRoundPos(pos, depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + var moveTo = axisManager.moveTo(roundPos, roundDepa); + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.event) || null; + var param = { + pos: moveTo.pos, + delta: moveTo.delta, + bounceRatio: this._getBounceRatio(moveTo.pos), + holding: holding, + inputEvent: inputEvent, + isTrusted: !!inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || (eventInfo === null || eventInfo === void 0 ? void 0 : eventInfo.input) || null, + set: inputEvent ? this._createUserControll(moveTo.pos) : function () {} + }; + var event = new ComponentEvent$1("change", param); + + this._axes.trigger(event); + + if (inputEvent) { + axisManager.set(param.set().destPos); + } + + return !event.isCanceled(); + }; + /** + * This event is fired when animation starts. + * @ko 에니메이션이 시작할 때 발생한다. + * @event Axes#animationStart + * @type {object} + * @property {Object.} depaPos The coordinates when animation starts애니메이션이 시작 되었을 때의 좌표 + * @property {Object.} destPos The coordinates to move to. If you change this value, you can run the animation이동할 좌표. 이값을 변경하여 애니메이션을 동작시킬수 있다 + * @property {Object.} delta The movement variation of coordinate 좌표의 변화량 + * @property {Number} duration Duration of the animation (unit: ms). If you change this value, you can control the animation duration time.애니메이션 진행 시간(단위: ms). 이값을 변경하여 애니메이션의 이동시간을 조절할 수 있다. + * @property {Object} input The instance of inputType where the event occurred. If the value is changed by animation, it returns 'null'.이벤트가 발생한 inputType 인스턴스. 애니메이션에 의해 값이 변경될 경우에는 'null'을 반환한다. + * @property {Object} inputEvent The event object received from inputType inputType으로 부터 받은 이벤트 객체 + * @property {setTo} setTo Specifies the animation coordinates to move after the event 이벤트 이후 이동할 애니메이션 좌표를 지정한다 + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("release", function(event) { + * // event.depaPos + * // event.destPos + * // event.delta + * // event.input + * // event.inputEvent + * // event.setTo + * // event.isTrusted + * + * // if you want to change the animation coordinates to move after the 'animationStart' event. + * event.setTo({x: 10}, 2000); + * }); + * ``` + */ + + + __proto.triggerAnimationStart = function (param) { + var _a = this._getRoundPos(param.destPos, param.depaPos), + roundPos = _a.roundPos, + roundDepa = _a.roundDepa; + + param.destPos = roundPos; + param.depaPos = roundDepa; + param.setTo = this._createUserControll(param.destPos, param.duration); + var event = new ComponentEvent$1("animationStart", param); + + this._axes.trigger(event); + + return !event.isCanceled(); + }; + /** + * This event is fired when animation ends. + * @ko 에니메이션이 끝났을 때 발생한다. + * @event Axes#animationEnd + * @type {object} + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("animationEnd", function(event) { + * // event.isTrusted + * }); + * ``` + */ + + + __proto.triggerAnimationEnd = function (isTrusted) { + if (isTrusted === void 0) { + isTrusted = false; + } + + this._axes.trigger(new ComponentEvent$1("animationEnd", { + isTrusted: isTrusted + })); + }; + /** + * This event is fired when all actions have been completed. + * @ko 에니메이션이 끝났을 때 발생한다. + * @event Axes#finish + * @type {object} + * @property {Boolean} isTrusted Returns true if an event was generated by the user action, or false if it was caused by a script or API call 사용자의 액션에 의해 이벤트가 발생하였으면 true, 스크립트나 API호출에 의해 발생하였을 경우에는 false를 반환한다. + * + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }).on("finish", function(event) { + * // event.isTrusted + * }); + * ``` + */ + + + __proto.triggerFinish = function (isTrusted) { + if (isTrusted === void 0) { + isTrusted = false; + } + + this._axes.trigger(new ComponentEvent$1("finish", { + isTrusted: isTrusted + })); + }; + + __proto.setAnimationManager = function (animationManager) { + this.animationManager = animationManager; + }; + + __proto.destroy = function () { + this._axes.off(); + }; + + __proto._createUserControll = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } // to controll + + + var userControl = { + destPos: __assign$1({}, pos), + duration: duration + }; + return function (toPos, userDuration) { + if (toPos) { + userControl.destPos = __assign$1({}, toPos); + } + + if (userDuration !== undefined) { + userControl.duration = userDuration; + } + + return userControl; + }; + }; + + __proto._getRoundPos = function (pos, depaPos) { + // round value if round exist + var roundUnit = this._axes.options.round; // if (round == null) { + // return {pos, depaPos}; // undefined, undefined + // } + + return { + roundPos: roundNumbers(pos, roundUnit), + roundDepa: roundNumbers(depaPos, roundUnit) + }; + }; + + __proto._getBounceRatio = function (pos) { + return this._axes.axisManager.map(pos, function (v, opt) { + if (v < opt.range[0] && opt.bounce[0] !== 0) { + return (opt.range[0] - v) / opt.bounce[0]; + } else if (v > opt.range[1] && opt.bounce[1] !== 0) { + return (v - opt.range[1]) / opt.bounce[1]; + } else { + return 0; + } + }); + }; + + return EventManager; + }(); + + var InterruptManager = + /*#__PURE__*/ + function () { + function InterruptManager(_options) { + this._options = _options; + this._prevented = false; // check whether the animation event was prevented + } + + var __proto = InterruptManager.prototype; + + __proto.isInterrupting = function () { + // when interruptable is 'true', return value is always 'true'. + return this._options.interruptable || this._prevented; + }; + + __proto.isInterrupted = function () { + return !this._options.interruptable && this._prevented; + }; + + __proto.setInterrupt = function (prevented) { + if (!this._options.interruptable) { + this._prevented = prevented; + } + }; + + return InterruptManager; + }(); + + var getInsidePosition = function (destPos, range, circular, bounce) { + var toDestPos = destPos; + var targetRange = [circular[0] ? range[0] : bounce ? range[0] - bounce[0] : range[0], circular[1] ? range[1] : bounce ? range[1] + bounce[1] : range[1]]; + toDestPos = Math.max(targetRange[0], toDestPos); + toDestPos = Math.min(targetRange[1], toDestPos); + return toDestPos; + }; // determine outside + + var isOutside = function (pos, range) { + return pos < range[0] || pos > range[1]; + }; // determine whether position has reached the maximum moveable area + + var isEndofBounce = function (pos, range, bounce, circular) { + return !circular[0] && pos === range[0] - bounce[0] || !circular[1] && pos === range[1] + bounce[1]; + }; + var getDuration = function (distance, deceleration) { + var duration = Math.sqrt(distance / deceleration * 2); // when duration is under 100, then value is zero + + return duration < 100 ? 0 : duration; + }; + var isCircularable = function (destPos, range, circular) { + return circular[1] && destPos > range[1] || circular[0] && destPos < range[0]; + }; + var getCirculatedPos = function (pos, range, circular) { + var toPos = pos; + var min = range[0]; + var max = range[1]; + var length = max - min; + + if (circular[1] && pos > max) { + // right + toPos = (toPos - max) % length + min; + } + + if (circular[0] && pos < min) { + // left + toPos = (toPos - min) % length + max; + } + + return toPos; + }; + + var AxisManager = + /*#__PURE__*/ + function () { + function AxisManager(_axis) { + var _this = this; + + this._axis = _axis; + + this._complementOptions(); + + this._pos = Object.keys(this._axis).reduce(function (acc, v) { + acc[v] = _this._axis[v].range[0]; + return acc; + }, {}); + } + + var __proto = AxisManager.prototype; + + __proto.getDelta = function (depaPos, destPos) { + var fullDepaPos = this.get(depaPos); + return map(this.get(destPos), function (v, k) { + return v - fullDepaPos[k]; + }); + }; + + __proto.get = function (axes) { + var _this = this; + + if (axes && Array.isArray(axes)) { + return axes.reduce(function (acc, v) { + if (v && v in _this._pos) { + acc[v] = _this._pos[v]; + } + + return acc; + }, {}); + } else { + return __assign$1(__assign$1({}, this._pos), axes || {}); + } + }; + + __proto.moveTo = function (pos, depaPos) { + if (depaPos === void 0) { + depaPos = this._pos; + } + + var delta = map(this._pos, function (v, key) { + return key in pos && key in depaPos ? pos[key] - depaPos[key] : 0; + }); + this.set(this.map(pos, function (v, opt) { + return opt ? getCirculatedPos(v, opt.range, opt.circular) : 0; + })); + return { + pos: __assign$1({}, this._pos), + delta: delta + }; + }; + + __proto.set = function (pos) { + for (var k in pos) { + if (k && k in this._pos) { + this._pos[k] = pos[k]; + } + } + }; + + __proto.every = function (pos, callback) { + var axisOptions = this._axis; + return every(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.filter = function (pos, callback) { + var axisOptions = this._axis; + return filter(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.map = function (pos, callback) { + var axisOptions = this._axis; + return map(pos, function (value, key) { + return callback(value, axisOptions[key], key); + }); + }; + + __proto.isOutside = function (axes) { + return !this.every(axes ? this.get(axes) : this._pos, function (v, opt) { + return !isOutside(v, opt.range); + }); + }; + + __proto.getAxisOptions = function (key) { + return this._axis[key]; + }; + /** + * set up 'css' expression + * @private + */ + + + __proto._complementOptions = function () { + var _this = this; + + Object.keys(this._axis).forEach(function (axis) { + _this._axis[axis] = __assign$1({ + range: [0, 100], + bounce: [0, 0], + circular: [false, false] + }, _this._axis[axis]); + ["bounce", "circular"].forEach(function (v) { + var axisOption = _this._axis; + var key = axisOption[axis][v]; + + if (/string|number|boolean/.test(typeof key)) { + axisOption[axis][v] = [key, key]; + } + }); + }); + }; + + return AxisManager; + }(); + + var SUPPORT_TOUCH$1 = ("ontouchstart" in win$1); + var SUPPORT_POINTER = ("PointerEvent" in win$1); + var SUPPORT_MSPOINTER = ("MSPointerEvent" in win$1); + var SUPPORT_POINTER_EVENTS = SUPPORT_POINTER || SUPPORT_MSPOINTER; + + var EventInput = + /*#__PURE__*/ + function () { + function EventInput() { + var _this = this; + + this._stopContextMenu = function (event) { + event.preventDefault(); + win$1.removeEventListener("contextmenu", _this._stopContextMenu); + }; + } + + var __proto = EventInput.prototype; + + __proto.extendEvent = function (event) { + var _a; + + var prevEvent = this.prevEvent; + + var center = this._getCenter(event); + + var movement = prevEvent ? this._getMovement(event) : { + x: 0, + y: 0 + }; + var scale = prevEvent ? this._getScale(event) : 1; + var angle = prevEvent ? getAngle(center.x - prevEvent.center.x, center.y - prevEvent.center.y) : 0; + var deltaX = prevEvent ? prevEvent.deltaX + movement.x : movement.x; + var deltaY = prevEvent ? prevEvent.deltaY + movement.y : movement.y; + var offsetX = movement.x; + var offsetY = movement.y; + var latestInterval = this._latestInterval; + var timeStamp = Date.now(); + var deltaTime = latestInterval ? timeStamp - latestInterval.timestamp : 0; + var velocityX = prevEvent ? prevEvent.velocityX : 0; + var velocityY = prevEvent ? prevEvent.velocityY : 0; + + if (!latestInterval || deltaTime >= VELOCITY_INTERVAL) { + if (latestInterval) { + _a = [(deltaX - latestInterval.deltaX) / deltaTime, (deltaY - latestInterval.deltaY) / deltaTime], velocityX = _a[0], velocityY = _a[1]; + } + + this._latestInterval = { + timestamp: timeStamp, + deltaX: deltaX, + deltaY: deltaY + }; + } + + return { + srcEvent: event, + scale: scale, + angle: angle, + center: center, + deltaX: deltaX, + deltaY: deltaY, + offsetX: offsetX, + offsetY: offsetY, + velocityX: velocityX, + velocityY: velocityY, + preventSystemEvent: true + }; + }; + + __proto._getDistance = function (start, end) { + var x = end.clientX - start.clientX; + var y = end.clientY - start.clientY; + return Math.sqrt(x * x + y * y); + }; + + __proto._getButton = function (event) { + var buttonCodeMap = { + 1: MOUSE_LEFT, + 2: MOUSE_RIGHT, + 4: MOUSE_MIDDLE + }; + var button = this._isTouchEvent(event) ? MOUSE_LEFT : buttonCodeMap[event.buttons]; + return button ? button : null; + }; + + __proto._isTouchEvent = function (event) { + return event.type.indexOf("touch") > -1; + }; + + __proto._isValidButton = function (button, inputButton) { + return inputButton.indexOf(button) > -1; + }; + + __proto._preventMouseButton = function (event, button) { + if (button === MOUSE_RIGHT) { + win$1.addEventListener("contextmenu", this._stopContextMenu); + } else if (button === MOUSE_MIDDLE) { + event.preventDefault(); + } + }; + + return EventInput; + }(); + + var MouseEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(MouseEventInput, _super); + + function MouseEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["mousedown"]; + _this.move = ["mousemove"]; + _this.end = ["mouseup"]; + return _this; + } + + var __proto = MouseEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function () { + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + return; + }; + + __proto.getTouches = function () { + return 0; + }; + + __proto._getScale = function () { + return 1; + }; + + __proto._getCenter = function (event) { + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + return { + x: event.clientX - prev.clientX, + y: event.clientY - prev.clientY + }; + }; + + return MouseEventInput; + }(EventInput); + + var TouchEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(TouchEventInput, _super); + + function TouchEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["touchstart"]; + _this.move = ["touchmove"]; + _this.end = ["touchend", "touchcancel"]; + return _this; + } + + var __proto = TouchEventInput.prototype; + + __proto.onEventStart = function (event) { + this._baseTouches = event.touches; + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event) { + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + this._baseTouches = event.touches; + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._baseTouches = null; + return; + }; + + __proto.getTouches = function (event) { + return event.touches.length; + }; + + __proto._getScale = function (event) { + if (event.touches.length !== 2 || this._baseTouches.length < 2) { + return null; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(event.touches[0], event.touches[1]) / this._getDistance(this._baseTouches[0], this._baseTouches[1]); + }; + + __proto._getCenter = function (event) { + return { + x: event.touches[0].clientX, + y: event.touches[0].clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + + if (event.touches[0].identifier !== prev.touches[0].identifier) { + return { + x: 0, + y: 0 + }; + } + + return { + x: event.touches[0].clientX - prev.touches[0].clientX, + y: event.touches[0].clientY - prev.touches[0].clientY + }; + }; + + return TouchEventInput; + }(EventInput); + + var PointerEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(PointerEventInput, _super); + + function PointerEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = SUPPORT_POINTER ? ["pointerdown"] : ["MSPointerDown"]; + _this.move = SUPPORT_POINTER ? ["pointermove"] : ["MSPointerMove"]; + _this.end = SUPPORT_POINTER ? ["pointerup", "pointercancel"] : ["MSPointerUp", "MSPointerCancel"]; // store first, recent inputs for each event id + + _this._firstInputs = []; + _this._recentInputs = []; + return _this; + } + + var __proto = PointerEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + this._updatePointerEvent(event); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + this._updatePointerEvent(event); + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + this._removePointerEvent(event); + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._firstInputs = []; + this._recentInputs = []; + return; + }; + + __proto.getTouches = function () { + return this._recentInputs.length; + }; + + __proto._getScale = function () { + if (this._recentInputs.length !== 2) { + return null; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(this._recentInputs[0], this._recentInputs[1]) / this._getDistance(this._firstInputs[0], this._firstInputs[1]); + }; + + __proto._getCenter = function (event) { + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var prev = this.prevEvent.srcEvent; + + if (event.pointerId !== prev.pointerId) { + return { + x: 0, + y: 0 + }; + } + + return { + x: event.clientX - prev.clientX, + y: event.clientY - prev.clientY + }; + }; + + __proto._updatePointerEvent = function (event) { + var _this = this; + + var addFlag = false; + + this._recentInputs.forEach(function (e, i) { + if (e.pointerId === event.pointerId) { + addFlag = true; + _this._recentInputs[i] = event; + } + }); + + if (!addFlag) { + this._firstInputs.push(event); + + this._recentInputs.push(event); + } + }; + + __proto._removePointerEvent = function (event) { + this._firstInputs = this._firstInputs.filter(function (x) { + return x.pointerId !== event.pointerId; + }); + this._recentInputs = this._recentInputs.filter(function (x) { + return x.pointerId !== event.pointerId; + }); + }; + + return PointerEventInput; + }(EventInput); + + var TouchMouseEventInput = + /*#__PURE__*/ + function (_super) { + __extends$1(TouchMouseEventInput, _super); + + function TouchMouseEventInput() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this.start = ["mousedown", "touchstart"]; + _this.move = ["mousemove", "touchmove"]; + _this.end = ["mouseup", "touchend", "touchcancel"]; + return _this; + } + + var __proto = TouchMouseEventInput.prototype; + + __proto.onEventStart = function (event, inputButton) { + var button = this._getButton(event); + + if (this._isTouchEvent(event)) { + this._baseTouches = event.touches; + } + + if (inputButton && !this._isValidButton(button, inputButton)) { + return null; + } + + this._preventMouseButton(event, button); + + return this.extendEvent(event); + }; + + __proto.onEventMove = function (event, inputButton) { + if (inputButton && !this._isValidButton(this._getButton(event), inputButton)) { + return null; + } + + return this.extendEvent(event); + }; + + __proto.onEventEnd = function (event) { + if (this._isTouchEvent(event)) { + this._baseTouches = event.touches; + } + + return; + }; + + __proto.onRelease = function () { + this.prevEvent = null; + this._baseTouches = null; + return; + }; + + __proto.getTouches = function (event) { + return this._isTouchEvent(event) ? event.touches.length : 0; + }; + + __proto._getScale = function (event) { + if (this._isTouchEvent(event)) { + if (event.touches.length !== 2 || this._baseTouches.length < 2) { + return 1; // TODO: consider calculating non-pinch gesture scale + } + + return this._getDistance(event.touches[0], event.touches[1]) / this._getDistance(this._baseTouches[0], this._baseTouches[1]); + } + + return this.prevEvent.scale; + }; + + __proto._getCenter = function (event) { + if (this._isTouchEvent(event)) { + return { + x: event.touches[0].clientX, + y: event.touches[0].clientY + }; + } + + return { + x: event.clientX, + y: event.clientY + }; + }; + + __proto._getMovement = function (event) { + var _this = this; + + var prev = this.prevEvent.srcEvent; + + var _a = [event, prev].map(function (e) { + if (_this._isTouchEvent(e)) { + return { + id: e.touches[0].identifier, + x: e.touches[0].clientX, + y: e.touches[0].clientY + }; + } + + return { + id: null, + x: e.clientX, + y: e.clientY + }; + }), + nextSpot = _a[0], + prevSpot = _a[1]; + + return nextSpot.id === prevSpot.id ? { + x: nextSpot.x - prevSpot.x, + y: nextSpot.y - prevSpot.y + } : { + x: 0, + y: 0 + }; + }; + + return TouchMouseEventInput; + }(EventInput); + + var toAxis = function (source, offset) { + return offset.reduce(function (acc, v, i) { + if (source[i]) { + acc[source[i]] = v; + } + + return acc; + }, {}); + }; + var convertInputType = function (inputType) { + if (inputType === void 0) { + inputType = []; + } + + var hasTouch = false; + var hasMouse = false; + var hasPointer = false; + inputType.forEach(function (v) { + switch (v) { + case "mouse": + hasMouse = true; + break; + + case "touch": + hasTouch = SUPPORT_TOUCH$1; + break; + + case "pointer": + hasPointer = SUPPORT_POINTER_EVENTS; + // no default + } + }); + + if (hasPointer) { + return new PointerEventInput(); + } else if (hasTouch && hasMouse) { + return new TouchMouseEventInput(); + } else if (hasTouch) { + return new TouchEventInput(); + } else if (hasMouse) { + return new MouseEventInput(); + } + + return null; + }; + + var InputObserver = + /*#__PURE__*/ + function () { + function InputObserver(_a) { + var options = _a.options, + interruptManager = _a.interruptManager, + eventManager = _a.eventManager, + axisManager = _a.axisManager, + animationManager = _a.animationManager; + this._isOutside = false; + this._moveDistance = null; + this._isStopped = false; + this.options = options; + this._interruptManager = interruptManager; + this._eventManager = eventManager; + this._axisManager = axisManager; + this._animationManager = animationManager; + } + + var __proto = InputObserver.prototype; + + __proto.get = function (input) { + return this._axisManager.get(input.axes); + }; + + __proto.hold = function (input, event) { + if (this._interruptManager.isInterrupted() || !input.axes.length) { + return; + } + + var changeOption = { + input: input, + event: event + }; + this._isStopped = false; + + this._interruptManager.setInterrupt(true); + + this._animationManager.stopAnimation(changeOption); + + if (!this._moveDistance) { + this._eventManager.hold(this._axisManager.get(), changeOption); + } + + this._isOutside = this._axisManager.isOutside(input.axes); + this._moveDistance = this._axisManager.get(input.axes); + }; + + __proto.change = function (input, event, offset, useAnimation) { + if (this._isStopped || !this._interruptManager.isInterrupting() || this._axisManager.every(offset, function (v) { + return v === 0; + })) { + return; + } + + var nativeEvent = event.srcEvent ? event.srcEvent : event; + + if (nativeEvent.__childrenAxesAlreadyChanged) { + return; + } + + var depaPos = this._moveDistance || this._axisManager.get(input.axes); + + var destPos; // for outside logic + + destPos = map(depaPos, function (v, k) { + return v + (offset[k] || 0); + }); + + if (this._moveDistance) { + this._moveDistance = this._axisManager.map(destPos, function (v, _a) { + var circular = _a.circular, + range = _a.range; + return circular && (circular[0] || circular[1]) ? getCirculatedPos(v, range, circular) : v; + }); + } // from outside to inside + + + if (this._isOutside && this._axisManager.every(depaPos, function (v, opt) { + return !isOutside(v, opt.range); + })) { + this._isOutside = false; + } + + depaPos = this._atOutside(depaPos); + destPos = this._atOutside(destPos); + + if (!this.options.nested || !this._isEndofAxis(offset, depaPos, destPos)) { + nativeEvent.__childrenAxesAlreadyChanged = true; + } + + var changeOption = { + input: input, + event: event + }; + + if (useAnimation) { + var duration = this._animationManager.getDuration(destPos, depaPos); + + this._animationManager.animateTo(destPos, duration, changeOption); + } else { + var isCanceled = !this._eventManager.triggerChange(destPos, depaPos, changeOption, true); + + if (isCanceled) { + this._isStopped = true; + this._moveDistance = null; + + this._animationManager.finish(false); + } + } + }; + + __proto.release = function (input, event, velocity, inputDuration) { + if (this._isStopped || !this._interruptManager.isInterrupting() || !this._moveDistance) { + return; + } + + var nativeEvent = event.srcEvent ? event.srcEvent : event; + + if (nativeEvent.__childrenAxesAlreadyReleased) { + velocity = velocity.map(function () { + return 0; + }); + } + + var pos = this._axisManager.get(input.axes); + + var depaPos = this._axisManager.get(); + + var displacement = this._animationManager.getDisplacement(velocity); + + var offset = toAxis(input.axes, displacement); + + var destPos = this._axisManager.get(this._axisManager.map(offset, function (v, opt, k) { + if (opt.circular && (opt.circular[0] || opt.circular[1])) { + return pos[k] + v; + } else { + return getInsidePosition(pos[k] + v, opt.range, opt.circular, opt.bounce); + } + })); + + nativeEvent.__childrenAxesAlreadyReleased = true; + + var duration = this._animationManager.getDuration(destPos, pos, inputDuration); + + if (duration === 0) { + destPos = __assign$1({}, depaPos); + } // prepare params + + + var param = { + depaPos: depaPos, + destPos: destPos, + duration: duration, + delta: this._axisManager.getDelta(depaPos, destPos), + inputEvent: event, + input: input, + isTrusted: true + }; + + this._eventManager.triggerRelease(param); + + this._moveDistance = null; // to contol + + var userWish = this._animationManager.getUserControl(param); + + var isEqual = equal(userWish.destPos, depaPos); + var changeOption = { + input: input, + event: event + }; + + if (isEqual || userWish.duration === 0) { + if (!isEqual) { + this._eventManager.triggerChange(userWish.destPos, depaPos, changeOption, true); + } + + this._interruptManager.setInterrupt(false); + + if (this._axisManager.isOutside()) { + this._animationManager.restore(changeOption); + } else { + this._eventManager.triggerFinish(true); + } + } else { + this._animationManager.animateTo(userWish.destPos, userWish.duration, changeOption); + } + }; // when move pointer is held in outside + + + __proto._atOutside = function (pos) { + var _this = this; + + if (this._isOutside) { + return this._axisManager.map(pos, function (v, opt) { + var tn = opt.range[0] - opt.bounce[0]; + var tx = opt.range[1] + opt.bounce[1]; + return v > tx ? tx : v < tn ? tn : v; + }); + } else { + return this._axisManager.map(pos, function (v, opt) { + var min = opt.range[0]; + var max = opt.range[1]; + var out = opt.bounce; + var circular = opt.circular; + + if (circular && (circular[0] || circular[1])) { + return v; + } else if (v < min) { + // left + return min - _this._animationManager.interpolate(min - v, out[0]); + } else if (v > max) { + // right + return max + _this._animationManager.interpolate(v - max, out[1]); + } + + return v; + }); + } + }; + + __proto._isEndofAxis = function (offset, depaPos, destPos) { + return this._axisManager.every(depaPos, function (value, option, key) { + return offset[key] === 0 || depaPos[key] === destPos[key] && isEndofBounce(value, option.range, option.bounce, option.circular); + }); + }; + + return InputObserver; + }(); + + var clamp = function (value, min, max) { + return Math.max(Math.min(value, max), min); + }; + + var AnimationManager = + /*#__PURE__*/ + function () { + function AnimationManager(_a) { + var options = _a.options, + interruptManager = _a.interruptManager, + eventManager = _a.eventManager, + axisManager = _a.axisManager; + this._options = options; + this.interruptManager = interruptManager; + this.eventManager = eventManager; + this.axisManager = axisManager; + this.animationEnd = this.animationEnd.bind(this); + } + + var __proto = AnimationManager.prototype; + + __proto.getDuration = function (depaPos, destPos, wishDuration) { + var _this = this; + + var duration; + + if (typeof wishDuration !== "undefined") { + duration = wishDuration; + } else { + var durations_1 = map(destPos, function (v, k) { + return getDuration(Math.abs(v - depaPos[k]), _this._options.deceleration); + }); + duration = Object.keys(durations_1).reduce(function (max, v) { + return Math.max(max, durations_1[v]); + }, -Infinity); + } + + return clamp(duration, this._options.minimumDuration, this._options.maximumDuration); + }; + + __proto.getDisplacement = function (velocity) { + var totalVelocity = Math.pow(velocity.reduce(function (total, v) { + return total + v * v; + }, 0), 1 / velocity.length); + var duration = Math.abs(totalVelocity / -this._options.deceleration); + return velocity.map(function (v) { + return v / 2 * duration; + }); + }; + + __proto.stopAnimation = function (option) { + if (this._animateParam) { + var orgPos_1 = this.axisManager.get(); + var pos = this.axisManager.map(orgPos_1, function (v, opt) { + return getCirculatedPos(v, opt.range, opt.circular); + }); + + if (!every(pos, function (v, k) { + return orgPos_1[k] === v; + })) { + this.eventManager.triggerChange(pos, orgPos_1, option, !!option); + } + + this._animateParam = null; + + if (this._raf) { + cancelAnimationFrame(this._raf); + } + + this._raf = null; + this.eventManager.triggerAnimationEnd(!!(option === null || option === void 0 ? void 0 : option.event)); + } + }; + + __proto.getEventInfo = function () { + if (this._animateParam && this._animateParam.input && this._animateParam.inputEvent) { + return { + input: this._animateParam.input, + event: this._animateParam.inputEvent + }; + } else { + return null; + } + }; + + __proto.restore = function (option) { + var pos = this.axisManager.get(); + var destPos = this.axisManager.map(pos, function (v, opt) { + return Math.min(opt.range[1], Math.max(opt.range[0], v)); + }); + this.stopAnimation(); + this.animateTo(destPos, this.getDuration(pos, destPos), option); + }; + + __proto.animationEnd = function () { + var beforeParam = this.getEventInfo(); + this._animateParam = null; // for Circular + + var circularTargets = this.axisManager.filter(this.axisManager.get(), function (v, opt) { + return isCircularable(v, opt.range, opt.circular); + }); + + if (Object.keys(circularTargets).length > 0) { + this.setTo(this.axisManager.map(circularTargets, function (v, opt) { + return getCirculatedPos(v, opt.range, opt.circular); + })); + } + + this.interruptManager.setInterrupt(false); + this.eventManager.triggerAnimationEnd(!!beforeParam); + + if (this.axisManager.isOutside()) { + this.restore(beforeParam); + } else { + this.finish(!!beforeParam); + } + }; + + __proto.finish = function (isTrusted) { + this._animateParam = null; + this.interruptManager.setInterrupt(false); + this.eventManager.triggerFinish(isTrusted); + }; + + __proto.getUserControl = function (param) { + var userWish = param.setTo(); + userWish.destPos = this.axisManager.get(userWish.destPos); + userWish.duration = clamp(userWish.duration, this._options.minimumDuration, this._options.maximumDuration); + return userWish; + }; + + __proto.animateTo = function (destPos, duration, option) { + var _this = this; + + this.stopAnimation(); + + var param = this._createAnimationParam(destPos, duration, option); + + var depaPos = __assign$1({}, param.depaPos); + + var retTrigger = this.eventManager.triggerAnimationStart(param); // to control + + var userWish = this.getUserControl(param); // You can't stop the 'animationStart' event when 'circular' is true. + + if (!retTrigger && this.axisManager.every(userWish.destPos, function (v, opt) { + return isCircularable(v, opt.range, opt.circular); + })) { + console.warn("You can't stop the 'animation' event when 'circular' is true."); + } + + if (retTrigger && !equal(userWish.destPos, depaPos)) { + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || null; + + this._animateLoop({ + depaPos: depaPos, + destPos: userWish.destPos, + duration: userWish.duration, + delta: this.axisManager.getDelta(depaPos, userWish.destPos), + isTrusted: !!inputEvent, + inputEvent: inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || null + }, function () { + return _this.animationEnd(); + }); + } + }; + + __proto.setTo = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + var axes = Object.keys(pos); + var orgPos = this.axisManager.get(axes); + + if (equal(pos, orgPos)) { + return this; + } + + this.interruptManager.setInterrupt(true); + var movedPos = filter(pos, function (v, k) { + return orgPos[k] !== v; + }); + + if (!Object.keys(movedPos).length) { + return this; + } + + movedPos = this.axisManager.map(movedPos, function (v, opt) { + var range = opt.range, + circular = opt.circular; + + if (circular && (circular[0] || circular[1])) { + return v; + } else { + return getInsidePosition(v, range, circular); + } + }); + + if (equal(movedPos, orgPos)) { + return this; + } + + if (duration > 0) { + this.animateTo(movedPos, duration); + } else { + this.stopAnimation(); + this.eventManager.triggerChange(movedPos); + this.finish(false); + } + + return this; + }; + + __proto.setBy = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + return this.setTo(map(this.axisManager.get(Object.keys(pos)), function (v, k) { + return v + pos[k]; + }), duration); + }; + + __proto._createAnimationParam = function (pos, duration, option) { + var depaPos = this.axisManager.get(); + var destPos = pos; + var inputEvent = (option === null || option === void 0 ? void 0 : option.event) || null; + return { + depaPos: depaPos, + destPos: destPos, + duration: clamp(duration, this._options.minimumDuration, this._options.maximumDuration), + delta: this.axisManager.getDelta(depaPos, destPos), + inputEvent: inputEvent, + input: (option === null || option === void 0 ? void 0 : option.input) || null, + isTrusted: !!inputEvent, + done: this.animationEnd + }; + }; + + __proto._animateLoop = function (param, complete) { + var _this = this; + + if (param.duration) { + this._animateParam = __assign$1(__assign$1({}, param), { + startTime: new Date().getTime() + }); + var originalIntendedPos_1 = map(param.destPos, function (v) { + return v; + }); + + var state_1 = this._initState(this._animateParam); + + var loop_1 = function () { + _this._raf = null; + var animateParam = _this._animateParam; + + var nextState = _this._getNextState(state_1); + + var isCanceled = !_this.eventManager.triggerChange(nextState.pos, state_1.pos); + state_1 = nextState; + + if (nextState.finished) { + animateParam.destPos = _this._getFinalPos(animateParam.destPos, originalIntendedPos_1); + + if (!equal(animateParam.destPos, _this.axisManager.get(Object.keys(animateParam.destPos)))) { + _this.eventManager.triggerChange(animateParam.destPos, nextState.pos); + } + + complete(); + return; + } else if (isCanceled) { + _this.finish(false); + } else { + _this._raf = requestAnimationFrame(loop_1); + } + }; + + loop_1(); + } else { + this.eventManager.triggerChange(param.destPos); + complete(); + } + }; + /** + * Get estimated final value. + * + * If destPos is within the 'error range' of the original intended position, the initial intended position is returned. + * - eg. original intended pos: 100, destPos: 100.0000000004 ==> return 100; + * If dest Pos is outside the 'range of error' compared to the originally intended pos, it is returned rounded based on the originally intended pos. + * - eg. original intended pos: 100.123 destPos: 50.12345 => return 50.123 + * @param originalIntendedPos + * @param destPos + */ + + + __proto._getFinalPos = function (destPos, originalIntendedPos) { + var _this = this; // compare destPos and originalIntendedPos + // eslint-disable-next-line @typescript-eslint/naming-convention + + + var ERROR_LIMIT = 0.000001; + var finalPos = map(destPos, function (value, key) { + if (value >= originalIntendedPos[key] - ERROR_LIMIT && value <= originalIntendedPos[key] + ERROR_LIMIT) { + // In error range, return original intended + return originalIntendedPos[key]; + } else { + // Out of error range, return rounded pos. + var roundUnit = _this._getRoundUnit(value, key); + + var result = roundNumber(value, roundUnit); + return result; + } + }); + return finalPos; + }; + + __proto._getRoundUnit = function (val, key) { + var roundUnit = this._options.round; // manual mode + + var minRoundUnit = null; // auto mode + // auto mode + + if (!roundUnit) { + // Get minimum round unit + var options = this.axisManager.getAxisOptions(key); + minRoundUnit = inversePow(Math.max(getDecimalPlace(options.range[0]), getDecimalPlace(options.range[1]), getDecimalPlace(val))); + } + + return minRoundUnit || roundUnit; + }; + + return AnimationManager; + }(); + + var EasingManager = + /*#__PURE__*/ + function (_super) { + __extends$1(EasingManager, _super); + + function EasingManager() { + var _this = _super !== null && _super.apply(this, arguments) || this; + + _this._useDuration = true; + return _this; + } + + var __proto = EasingManager.prototype; + + __proto.interpolate = function (displacement, threshold) { + var initSlope = this._easing(0.00001) / 0.00001; + return this._easing(displacement / (threshold * initSlope)) * threshold; + }; + + __proto.updateAnimation = function (options) { + var animateParam = this._animateParam; + + if (!animateParam) { + return; + } + + var diffTime = new Date().getTime() - animateParam.startTime; + var pos = (options === null || options === void 0 ? void 0 : options.destPos) || animateParam.destPos; + var duration = (options === null || options === void 0 ? void 0 : options.duration) || animateParam.duration; + + if ((options === null || options === void 0 ? void 0 : options.restart) || duration <= diffTime) { + this.setTo(pos, duration - diffTime); + return; + } + + if (options === null || options === void 0 ? void 0 : options.destPos) { + var currentPos = this.axisManager.get(); // When destination is changed, new delta should be calculated as remaining percent. + // For example, moving x:0, y:0 to x:200, y:200 and it has current easing percent of 92%. coordinate is x:184 and y:184 + // If destination changes to x:300, y:300. xdelta:200, ydelta:200 changes to xdelta:116, ydelta:116 and use remaining easingPer as 100%, not 8% as previous. + // Therefore, original easingPer by time is kept. And divided by (1 - self._initialEasingPer) which means new total easing percent. Like calculating 8% as 100%. + + this._initialEasingPer = this._prevEasingPer; + animateParam.delta = this.axisManager.getDelta(currentPos, pos); + animateParam.destPos = pos; + } + + if (options === null || options === void 0 ? void 0 : options.duration) { + var ratio = (diffTime + this._durationOffset) / animateParam.duration; // Use durationOffset for keeping animation ratio after duration is changed. + // newRatio = (diffTime + newDurationOffset) / newDuration = oldRatio + // newDurationOffset = oldRatio * newDuration - diffTime + + this._durationOffset = ratio * duration - diffTime; + animateParam.duration = duration; + } + }; + + __proto._initState = function (info) { + this._initialEasingPer = 0; + this._prevEasingPer = 0; + this._durationOffset = 0; + return { + pos: info.depaPos, + easingPer: 0, + finished: false + }; + }; + + __proto._getNextState = function (prevState) { + var _this = this; + + var animateParam = this._animateParam; + var prevPos = prevState.pos; + var destPos = animateParam.destPos; + var directions = map(prevPos, function (value, key) { + return value <= destPos[key] ? 1 : -1; + }); + var diffTime = new Date().getTime() - animateParam.startTime; + var ratio = (diffTime + this._durationOffset) / animateParam.duration; + + var easingPer = this._easing(ratio); + + var toPos = this.axisManager.map(prevPos, function (pos, options, key) { + var nextPos = ratio >= 1 ? destPos[key] : pos + animateParam.delta[key] * (easingPer - _this._prevEasingPer) / (1 - _this._initialEasingPer); // Subtract distance from distance already moved. + // Recalculate the remaining distance. + // Fix the bouncing phenomenon by changing the range. + + var circulatedPos = getCirculatedPos(nextPos, options.range, options.circular); + + if (nextPos !== circulatedPos) { + // circular + var rangeOffset = directions[key] * (options.range[1] - options.range[0]); + destPos[key] -= rangeOffset; + prevPos[key] -= rangeOffset; + } + + return circulatedPos; + }); + this._prevEasingPer = easingPer; + return { + pos: toPos, + easingPer: easingPer, + finished: easingPer >= 1 + }; + }; + + __proto._easing = function (p) { + return p > 1 ? 1 : this._options.easing(p); + }; + + return EasingManager; + }(AnimationManager); + + /** + * @typedef {Object} AxisOption The Axis information. The key of the axis specifies the name to use as the logical virtual coordinate system. + * @ko 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다. + * @param {Number[]} [range] The coordinate of range 좌표 범위 + * @param {Number} [range[0]=0] The coordinate of the minimum 최소 좌표 + * @param {Number} [range[1]=0] The coordinate of the maximum 최대 좌표 + * @param {Number[]} [bounce] The size of bouncing area. The coordinates can exceed the coordinate area as much as the bouncing area based on user action. If the coordinates does not exceed the bouncing area when an element is dragged, the coordinates where bouncing effects are applied are retuned back into the coordinate area바운스 영역의 크기. 사용자의 동작에 따라 좌표가 좌표 영역을 넘어 바운스 영역의 크기만큼 더 이동할 수 있다. 사용자가 끌어다 놓는 동작을 했을 때 좌표가 바운스 영역에 있으면, 바운스 효과가 적용된 좌표가 다시 좌표 영역 안으로 들어온다 + * @param {Number} [bounce[0]=0] The size of coordinate of the minimum area 최소 좌표 바운스 영역의 크기 + * @param {Number} [bounce[1]=0] The size of coordinate of the maximum area 최대 좌표 바운스 영역의 크기 + * @param {Boolean[]} [circular] Indicates whether a circular element is available. If it is set to "true" and an element is dragged outside the coordinate area, the element will appear on the other side.순환 여부. 'true'로 설정한 방향의 좌표 영역 밖으로 엘리먼트가 이동하면 반대 방향에서 엘리먼트가 나타난다 + * @param {Boolean} [circular[0]=false] Indicates whether to circulate to the coordinate of the minimum 최소 좌표 방향의 순환 여부 + * @param {Boolean} [circular[1]=false] Indicates whether to circulate to the coordinate of the maximum 최대 좌표 방향의 순환 여부 + **/ + + /** + * @typedef {Object} AxesOption The option object of the eg.Axes module + * @ko eg.Axes 모듈의 옵션 객체 + * @param {Function} [easing=easing.easeOutCubic] The easing function to apply to an animation 애니메이션에 적용할 easing 함수 + * @param {Number} [maximumDuration=Infinity] Maximum duration of the animation 가속도에 의해 애니메이션이 동작할 때의 최대 좌표 이동 시간 + * @param {Number} [minimumDuration=0] Minimum duration of the animation 가속도에 의해 애니메이션이 동작할 때의 최소 좌표 이동 시간 + * @param {Number} [deceleration=0.0006] Deceleration of the animation where acceleration is manually enabled by user. A higher value indicates shorter running time. 사용자의 동작으로 가속도가 적용된 애니메이션의 감속도. 값이 높을수록 애니메이션 실행 시간이 짧아진다 + * @param {Boolean} [interruptable=true] Indicates whether an animation is interruptible. + * - true: It can be paused or stopped by user action or the API. + * - false: It cannot be paused or stopped by user action or the API while it is running. + * 진행 중인 애니메이션 중지 가능 여부. + * - true: 사용자의 동작이나 API로 애니메이션을 중지할 수 있다. + * - false: 애니메이션이 진행 중일 때는 사용자의 동작이나 API가 적용되지 않는다 + * @param {Number} [round=null] Rounding unit. For example, 0.1 rounds to 0.1 decimal point(6.1234 => 6.1), 5 rounds to 5 (93 => 95) + * [Details](https://github.com/naver/egjs-axes/wiki/round-option)반올림 단위. 예를 들어 0.1 은 소숫점 0.1 까지 반올림(6.1234 => 6.1), 5 는 5 단위로 반올림(93 => 95). + * [상세내용](https://github.com/naver/egjs-axes/wiki/round-option) + * @param {Boolean} [nested=false] Whether the event propagates to other instances when the coordinates reach the end of the movable area 좌표가 이동 가능한 영역의 끝까지 도달했을 때 다른 인스턴스들로의 이벤트 전파 여부 + **/ + + /** + * A module used to change the information of user action entered by various input devices such as touch screen or mouse into the logical virtual coordinates. You can easily create a UI that responds to user actions. + * @ko 터치 입력 장치나 마우스와 같은 다양한 입력 장치를 통해 전달 받은 사용자의 동작을 논리적인 가상 좌표로 변경하는 모듈이다. 사용자 동작에 반응하는 UI를 손쉽게 만들수 있다. + * @extends eg.Component + * + * @param {Object.} axis Axis information managed by eg.Axes. The key of the axis specifies the name to use as the logical virtual coordinate system. eg.Axes가 관리하는 축 정보. 축의 키는 논리적인 가상 좌표계로 사용할 이름을 지정한다. + * @param {AxesOption} [options={}] The option object of the eg.Axes moduleeg.Axes 모듈의 옵션 객체 + * @param {Object.} [startPos=null] The coordinates to be moved when creating an instance. not triggering change event.인스턴스 생성시 이동할 좌표, change 이벤트는 발생하지 않음. + * + * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * ```js + * // 1. Initialize eg.Axes + * const axes = new eg.Axes({ + * something1: { + * range: [0, 150], + * bounce: 50 + * }, + * something2: { + * range: [0, 200], + * bounce: 100 + * }, + * somethingN: { + * range: [1, 10], + * } + * }, { + * deceleration : 0.0024 + * }); + * + * // 2. attach event handler + * axes.on({ + * "hold" : function(evt) { + * }, + * "release" : function(evt) { + * }, + * "animationStart" : function(evt) { + * }, + * "animationEnd" : function(evt) { + * }, + * "change" : function(evt) { + * } + * }); + * + * // 3. Initialize inputTypes + * const panInputArea = new eg.Axes.PanInput("#area", { + * scale: [0.5, 1] + * }); + * const panInputHmove = new eg.Axes.PanInput("#hmove"); + * const panInputVmove = new eg.Axes.PanInput("#vmove"); + * const pinchInputArea = new eg.Axes.PinchInput("#area", { + * scale: 1.5 + * }); + * + * // 4. Connect eg.Axes and InputTypes + * // [PanInput] When the mouse or touchscreen is down and moved. + * // Connect the 'something2' axis to the mouse or touchscreen x position and + * // connect the 'somethingN' axis to the mouse or touchscreen y position. + * axes.connect(["something2", "somethingN"], panInputArea); // or axes.connect("something2 somethingN", panInputArea); + * + * // Connect only one 'something1' axis to the mouse or touchscreen x position. + * axes.connect(["something1"], panInputHmove); // or axes.connect("something1", panInputHmove); + * + * // Connect only one 'something2' axis to the mouse or touchscreen y position. + * axes.connect(["", "something2"], panInputVmove); // or axes.connect(" something2", panInputVmove); + * + * // [PinchInput] Connect 'something2' axis when two pointers are moving toward (zoom-in) or away from each other (zoom-out). + * axes.connect("something2", pinchInputArea); + * ``` + */ + + var Axes = + /*#__PURE__*/ + function (_super) { + __extends$1(Axes, _super); + /** + * + */ + + + function Axes(axis, options, startPos) { + if (axis === void 0) { + axis = {}; + } + + if (options === void 0) { + options = {}; + } + + if (startPos === void 0) { + startPos = null; + } + + var _this = _super.call(this) || this; + + _this.axis = axis; + _this._inputs = []; + _this.options = __assign$1({ + easing: function (x) { + return 1 - Math.pow(1 - x, 3); + }, + interruptable: true, + maximumDuration: Infinity, + minimumDuration: 0, + deceleration: 0.0006, + round: null, + nested: false + }, options); + _this.interruptManager = new InterruptManager(_this.options); + _this.axisManager = new AxisManager(_this.axis); + _this.eventManager = new EventManager(_this); + _this.animationManager = new EasingManager(_this); + _this.inputObserver = new InputObserver(_this); + + _this.eventManager.setAnimationManager(_this.animationManager); + + if (startPos) { + _this.eventManager.triggerChange(startPos); + } + + return _this; + } + /** + * Connect the axis of eg.Axes to the inputType. + * @ko eg.Axes의 축과 inputType을 연결한다 + * @param {(String[]|String)} axes The name of the axis to associate with inputType inputType과 연결할 축의 이름 + * @param {Object} inputType The inputType instance to associate with the axis of eg.Axes eg.Axes의 축과 연결할 inputType 인스턴스 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * } + * }); + * + * axes.connect("x", new eg.Axes.PanInput("#area1")) + * .connect("x xOther", new eg.Axes.PanInput("#area2")) + * .connect(" xOther", new eg.Axes.PanInput("#area3")) + * .connect(["x"], new eg.Axes.PanInput("#area4")) + * .connect(["xOther", "x"], new eg.Axes.PanInput("#area5")) + * .connect(["", "xOther"], new eg.Axes.PanInput("#area6")); + * ``` + */ + + + var __proto = Axes.prototype; + + __proto.connect = function (axes, inputType) { + var mapped; + + if (typeof axes === "string") { + mapped = axes.split(" "); + } else { + mapped = axes.concat(); + } // check same instance + + + if (~this._inputs.indexOf(inputType)) { + this.disconnect(inputType); + } + + inputType.mapAxes(mapped); + inputType.connect(this.inputObserver); + + this._inputs.push(inputType); + + return this; + }; + /** + * Disconnect the axis of eg.Axes from the inputType. + * @ko eg.Axes의 축과 inputType의 연결을 끊는다. + * @param {Object} [inputType] An inputType instance associated with the axis of eg.Axes eg.Axes의 축과 연결한 inputType 인스턴스 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * } + * }); + * + * const input1 = new eg.Axes.PanInput("#area1"); + * const input2 = new eg.Axes.PanInput("#area2"); + * const input3 = new eg.Axes.PanInput("#area3"); + * + * axes.connect("x", input1); + * .connect("x xOther", input2) + * .connect(["xOther", "x"], input3); + * + * axes.disconnect(input1); // disconnects input1 + * axes.disconnect(); // disconnects all of them + * ``` + */ + + + __proto.disconnect = function (inputType) { + if (inputType) { + var index = this._inputs.indexOf(inputType); + + if (index >= 0) { + this._inputs[index].disconnect(); + + this._inputs.splice(index, 1); + } + } else { + this._inputs.forEach(function (v) { + return v.disconnect(); + }); + + this._inputs = []; + } + + return this; + }; + /** + * Returns the current position of the coordinates. + * @ko 좌표의 현재 위치를 반환한다 + * @param {Object} [axes] The names of the axis 축 이름들 + * @return {Object.} Axis coordinate information 축 좌표 정보 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.get(); // {"x": 0, "xOther": -100, "zoom": 50} + * axes.get(["x", "zoom"]); // {"x": 0, "zoom": 50} + * ``` + */ + + + __proto.get = function (axes) { + return this.axisManager.get(axes); + }; + /** + * Moves an axis to specific coordinates. + * @ko 좌표를 이동한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.setTo({"x": 30, "zoom": 60}); + * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60} + * + * axes.setTo({"x": 100, "xOther": 60}, 1000); // animatation + * + * // after 1000 ms + * axes.get(); // {"x": 100, "xOther": 60, "zoom": 60} + * ``` + */ + + + __proto.setTo = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + this.animationManager.setTo(pos, duration); + return this; + }; + /** + * Moves an axis from the current coordinates to specific coordinates. + * @ko 현재 좌표를 기준으로 좌표를 이동한다. + * @param {Object.} pos The coordinate to move to 이동할 좌표 + * @param {Number} [duration=0] Duration of the animation (unit: ms) 애니메이션 진행 시간(단위: ms) + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.setBy({"x": 30, "zoom": 10}); + * axes.get(); // {"x": 30, "xOther": -100, "zoom": 60} + * + * axes.setBy({"x": 70, "xOther": 60}, 1000); // animatation + * + * // after 1000 ms + * axes.get(); // {"x": 100, "xOther": -40, "zoom": 60} + * ``` + */ + + + __proto.setBy = function (pos, duration) { + if (duration === void 0) { + duration = 0; + } + + this.animationManager.setBy(pos, duration); + return this; + }; + /** + * Stop an animation in progress. + * @ko 재생 중인 애니메이션을 정지한다. + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * }); + * + * axes.setTo({"x": 10}, 1000); // start animatation + * + * // after 500 ms + * axes.stopAnimation(); // stop animation during movement. + * ``` + */ + + + __proto.stopAnimation = function () { + this.animationManager.stopAnimation(); + return this; + }; + /** + * Change the destination of an animation in progress. + * @ko 재생 중인 애니메이션의 목적지와 진행 시간을 변경한다. + * @param {UpdateAnimationOption} pos The coordinate to move to 이동할 좌표 + * @return {eg.Axes} An instance of a module itself 모듈 자신의 인스턴스 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 200] + * }, + * "y": { + * range: [0, 200] + * } + * }); + * + * axes.setTo({"x": 50, "y": 50}, 1000); // trigger animation by setTo + * + * // after 500 ms + * axes.updateAnimation({destPos: {"x": 100, "y": 100}}); // animation will end after 500 ms, at {"x": 100, "y": 100} + * + * // after 500 ms + * axes.setTo({"x": 50, "y": 50}, 1000); // trigger animation by setTo + * + * // after 700 ms + * axes.updateAnimation({destPos: {"x": 100, "y": 100}, duration: 1500, restart: true}); // this works same as axes.setTo({"x": 100, "y": 100}, 800) since restart is true. + * ``` + */ + + + __proto.updateAnimation = function (options) { + this.animationManager.updateAnimation(options); + return this; + }; + /** + * Returns whether there is a coordinate in the bounce area of ​​the target axis. + * @ko 대상 축 중 bounce영역에 좌표가 존재하는지를 반환한다 + * @param {Object} [axes] The names of the axis 축 이름들 + * @return {Boolen} Whether the bounce area exists. bounce 영역 존재 여부 + * @example + * ```js + * const axes = new eg.Axes({ + * "x": { + * range: [0, 100] + * }, + * "xOther": { + * range: [-100, 100] + * }, + * "zoom": { + * range: [50, 30] + * } + * }); + * + * axes.isBounceArea(["x"]); + * axes.isBounceArea(["x", "zoom"]); + * axes.isBounceArea(); + * ``` + */ + + + __proto.isBounceArea = function (axes) { + return this.axisManager.isOutside(axes); + }; + /** + * Destroys properties, and events used in a module and disconnect all connections to inputTypes. + * @ko 모듈에 사용한 속성, 이벤트를 해제한다. 모든 inputType과의 연결을 끊는다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.eventManager.destroy(); + }; + /** + * @name VERSION + * @desc Version info string + * @ko 버전정보 문자열 + * + * @constant + * @type {String} + * @example + * ```js + * eg.Axes.VERSION; // ex) 3.3.3 + * ``` + */ + + + Axes.VERSION = "3.3.0"; + /* eslint-enable */ + + /** + * @name TRANSFORM + * @desc Returns the transform attribute with CSS vendor prefixes. + * @ko CSS vendor prefixes를 붙인 transform 속성을 반환한다. + * + * @constant + * @type {String} + * @example + * ```js + * eg.Axes.TRANSFORM; // "transform" or "webkitTransform" + * ``` + */ + + Axes.TRANSFORM = TRANSFORM$1; + /** + * @name DIRECTION_NONE + * @constant + * @type {Number} + */ + + Axes.DIRECTION_NONE = DIRECTION_NONE; + /** + * @name DIRECTION_LEFT + * @constant + * @type {Number} + */ + + Axes.DIRECTION_LEFT = DIRECTION_LEFT; + /** + * @name DIRECTION_RIGHT + * @constant + * @type {Number} + */ + + Axes.DIRECTION_RIGHT = DIRECTION_RIGHT; + /** + * @name DIRECTION_UP + * @constant + * @type {Number} + */ + + Axes.DIRECTION_UP = DIRECTION_UP; + /** + * @name DIRECTION_DOWN + * @constant + * @type {Number} + */ + + Axes.DIRECTION_DOWN = DIRECTION_DOWN; + /** + * @name DIRECTION_HORIZONTAL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_HORIZONTAL = DIRECTION_HORIZONTAL; + /** + * @name DIRECTION_VERTICAL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_VERTICAL = DIRECTION_VERTICAL; + /** + * @name DIRECTION_ALL + * @constant + * @type {Number} + */ + + Axes.DIRECTION_ALL = DIRECTION_ALL; + return Axes; + }(Component); + + /* eslint-disable @typescript-eslint/no-empty-function */ + + var getDirectionByAngle = function (angle, thresholdAngle) { + if (thresholdAngle < 0 || thresholdAngle > 90) { + return DIRECTION_NONE; + } + + var toAngle = Math.abs(angle); + return toAngle > thresholdAngle && toAngle < 180 - thresholdAngle ? DIRECTION_VERTICAL : DIRECTION_HORIZONTAL; + }; + var useDirection = function (checkType, direction, userDirection) { + if (userDirection) { + return !!(direction === DIRECTION_ALL || direction & checkType && userDirection & checkType); + } else { + return !!(direction & checkType); + } + }; + /** + * @typedef {Object} PanInputOption The option object of the eg.Axes.PanInput module. + * @ko eg.Axes.PanInput 모듈의 옵션 객체 + * @param {String[]} [inputType=["touch", "mouse", "pointer"]] Types of input devices + * - touch: Touch screen + * - mouse: Mouse + * - pointer: Mouse and touch 입력 장치 종류 + * - touch: 터치 입력 장치 + * - mouse: 마우스 + * - pointer: 마우스 및 터치 + * @param {String[]} [inputButton=["left"]] List of buttons to allow input + * - left: Left mouse button and normal touch + * - middle: Mouse wheel press + * - right: Right mouse button 입력을 허용할 버튼 목록 + * - left: 마우스 왼쪽 버튼 + * - middle: 마우스 휠 눌림 + * - right: 마우스 오른쪽 버튼 + * @param {Number[]} [scale] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [scale[0]=1] horizontal axis scale 수평축 배율 + * @param {Number} [scale[1]=1] vertical axis scale 수직축 배율 + * @param {Number} [thresholdAngle=45] The threshold value that determines whether user action is horizontal or vertical (0~90) 사용자의 동작이 가로 방향인지 세로 방향인지 판단하는 기준 각도(0~90) + * @param {Number} [threshold=0] Minimal pan distance required before recognizing 사용자의 Pan 동작을 인식하기 위해산 최소한의 거리 + * @param {Number} [iOSEdgeSwipeThreshold=30] Area (px) that can go to the next page when swiping the right edge in iOS safari iOS Safari에서 오른쪽 엣지를 스와이프 하는 경우 다음 페이지로 넘어갈 수 있는 영역(px) + * @param {String} [touchAction=null] Value that overrides the element's "touch-action" css property. If set to null, it is automatically set to prevent scrolling in the direction of the connected axis. 엘리먼트의 "touch-action" CSS 속성을 덮어쓰는 값. 만약 null로 설정된 경우, 연결된 축 방향으로의 스크롤을 방지하게끔 자동으로 설정된다. + **/ + + /** + * A module that passes the amount of change to eg.Axes when the mouse or touchscreen is down and moved. use less than two axes. + * @ko 마우스나 터치 스크린을 누르고 움직일때의 변화량을 eg.Axes에 전달하는 모듈. 두개 이하의 축을 사용한다. + * + * @example + * ```js + * const pan = new eg.Axes.PanInput("#area", { + * inputType: ["touch"], + * scale: [1, 1.3], + * }); + * + * // Connect the 'something2' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved. + * // Connect the 'somethingN' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved. + * axes.connect(["something2", "somethingN"], pan); // or axes.connect("something2 somethingN", pan); + * + * // Connect only one 'something1' axis to the mouse or touchscreen x position when the mouse or touchscreen is down and moved. + * axes.connect(["something1"], pan); // or axes.connect("something1", pan); + * + * // Connect only one 'something2' axis to the mouse or touchscreen y position when the mouse or touchscreen is down and moved. + * axes.connect(["", "something2"], pan); // or axes.connect(" something2", pan); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.PanInput module eg.Axes.PanInput 모듈을 사용할 엘리먼트 + * @param {PanInputOption} [options={}] The option object of the eg.Axes.PanInput moduleeg.Axes.PanInput 모듈의 옵션 객체 + */ + + var PanInput = + /*#__PURE__*/ + function () { + /** + * + */ + function PanInput(el, options) { + var _this = this; + + this.axes = []; + this.element = null; + this._enabled = false; + this._activeEvent = null; + this._atRightEdge = false; + this._rightEdgeTimer = 0; + + this._forceRelease = function () { + var activeEvent = _this._activeEvent; + var prevEvent = activeEvent.prevEvent; + activeEvent.onRelease(); + + _this._observer.release(_this, prevEvent, [0, 0]); + + _this._detachWindowEvent(activeEvent); + }; + + this._voidFunction = function () {}; + + this.element = $(el); + this.options = __assign$1({ + inputType: ["touch", "mouse", "pointer"], + inputButton: [MOUSE_LEFT], + scale: [1, 1], + thresholdAngle: 45, + threshold: 0, + iOSEdgeSwipeThreshold: IOS_EDGE_THRESHOLD, + releaseOnScroll: false, + touchAction: null + }, options); + this._onPanstart = this._onPanstart.bind(this); + this._onPanmove = this._onPanmove.bind(this); + this._onPanend = this._onPanend.bind(this); + } + + var __proto = PanInput.prototype; + + __proto.mapAxes = function (axes) { + var useHorizontal = !!axes[0]; + var useVertical = !!axes[1]; + + if (useHorizontal && useVertical) { + this._direction = DIRECTION_ALL; + } else if (useHorizontal) { + this._direction = DIRECTION_HORIZONTAL; + } else if (useVertical) { + this._direction = DIRECTION_VERTICAL; + } else { + this._direction = DIRECTION_NONE; + } + + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this._activeEvent) { + this._detachElementEvent(); + + this._detachWindowEvent(this._activeEvent); + } + + this._attachElementEvent(observer); + + this._originalCssProps = setCssProps(this.element, this.options, this._direction); + return this; + }; + + __proto.disconnect = function () { + this._detachElementEvent(); + + this._detachWindowEvent(this._activeEvent); + + if (!isCssPropsFromAxes(this._originalCssProps)) { + revertCssProps(this.element, this._originalCssProps); + } + + this._direction = DIRECTION_NONE; + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {PanInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {PanInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onPanstart = function (event) { + var activeEvent = this._activeEvent; + var panEvent = activeEvent.onEventStart(event, this.options.inputButton); + + if (!panEvent || !this._enabled || activeEvent.getTouches(event) > 1) { + return; + } + + if (panEvent.srcEvent.cancelable !== false) { + var edgeThreshold = this.options.iOSEdgeSwipeThreshold; + + this._observer.hold(this, panEvent); + + this._atRightEdge = IS_IOS_SAFARI && panEvent.center.x > window.innerWidth - edgeThreshold; + + this._attachWindowEvent(activeEvent); + + activeEvent.prevEvent = panEvent; + } + }; + + __proto._onPanmove = function (event) { + var _this = this; + + var activeEvent = this._activeEvent; + var panEvent = activeEvent.onEventMove(event, this.options.inputButton); + + if (!panEvent || !this._enabled || activeEvent.getTouches(event) > 1) { + return; + } + + var _a = this.options, + iOSEdgeSwipeThreshold = _a.iOSEdgeSwipeThreshold, + releaseOnScroll = _a.releaseOnScroll; + var userDirection = getDirectionByAngle(panEvent.angle, this.options.thresholdAngle); + + if (releaseOnScroll && !panEvent.srcEvent.cancelable) { + this._onPanend(event); + + return; + } + + if (activeEvent.prevEvent && IS_IOS_SAFARI) { + var swipeLeftToRight = panEvent.center.x < 0; + + if (swipeLeftToRight) { + // iOS swipe left => right + this._forceRelease(); + + return; + } else if (this._atRightEdge) { + clearTimeout(this._rightEdgeTimer); // - is right to left + + var swipeRightToLeft = panEvent.deltaX < -iOSEdgeSwipeThreshold; + + if (swipeRightToLeft) { + this._atRightEdge = false; + } else { + // iOS swipe right => left + this._rightEdgeTimer = window.setTimeout(function () { + return _this._forceRelease(); + }, 100); + } + } + } + + var offset = this._getOffset([panEvent.offsetX, panEvent.offsetY], [useDirection(DIRECTION_HORIZONTAL, this._direction, userDirection), useDirection(DIRECTION_VERTICAL, this._direction, userDirection)]); + + var prevent = offset.some(function (v) { + return v !== 0; + }); + + if (prevent) { + if (panEvent.srcEvent.cancelable !== false) { + panEvent.srcEvent.preventDefault(); + } + + panEvent.srcEvent.stopPropagation(); + } + + panEvent.preventSystemEvent = prevent; + + if (prevent) { + this._observer.change(this, panEvent, toAxis(this.axes, offset)); + } + + activeEvent.prevEvent = panEvent; + }; + + __proto._onPanend = function (event) { + var activeEvent = this._activeEvent; + activeEvent.onEventEnd(event); + + if (!this._enabled || activeEvent.getTouches(event) !== 0) { + return; + } + + this._detachWindowEvent(activeEvent); + + clearTimeout(this._rightEdgeTimer); + var prevEvent = activeEvent.prevEvent; + + var velocity = this._getOffset([Math.abs(prevEvent.velocityX) * (prevEvent.offsetX < 0 ? -1 : 1), Math.abs(prevEvent.velocityY) * (prevEvent.offsetY < 0 ? -1 : 1)], [useDirection(DIRECTION_HORIZONTAL, this._direction), useDirection(DIRECTION_VERTICAL, this._direction)]); + + activeEvent.onRelease(); + + this._observer.release(this, prevEvent, velocity); + }; + + __proto._attachWindowEvent = function (activeEvent) { + var _this = this; + + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + window.addEventListener(event, _this._onPanmove, { + passive: false + }); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) { + window.addEventListener(event, _this._onPanend, { + passive: false + }); + }); + }; + + __proto._detachWindowEvent = function (activeEvent) { + var _this = this; + + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + window.removeEventListener(event, _this._onPanmove); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) { + window.removeEventListener(event, _this._onPanend); + }); + }; + + __proto._getOffset = function (properties, direction) { + var offset = [0, 0]; + var scale = this.options.scale; + + if (direction[0]) { + offset[0] = properties[0] * scale[0]; + } + + if (direction[1]) { + offset[1] = properties[1] * scale[1]; + } + + return offset; + }; + + __proto._attachElementEvent = function (observer) { + var _this = this; + + var activeEvent = convertInputType(this.options.inputType); + + if (!activeEvent) { + return; + } + + this._observer = observer; + this._enabled = true; + this._activeEvent = activeEvent; + activeEvent.start.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.addEventListener(event, _this._onPanstart); + }); // adding event listener to element prevents invalid behavior in iOS Safari + + activeEvent.move.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.addEventListener(event, _this._voidFunction); + }); + }; + + __proto._detachElementEvent = function () { + var _this = this; + + var activeEvent = this._activeEvent; + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.start.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, _this._onPanstart); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + var _a; + + (_a = _this.element) === null || _a === void 0 ? void 0 : _a.removeEventListener(event, _this._voidFunction); + }); + this._enabled = false; + this._observer = null; + }; + + return PanInput; + }(); + + /** + * @typedef {Object} PinchInputOption The option object of the eg.Axes.PinchInput module + * @ko eg.Axes.PinchInput 모듈의 옵션 객체 + * @param {Number} [scale=1] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [threshold=0] Minimal scale before recognizing 사용자의 Pinch 동작을 인식하기 위해산 최소한의 배율 + * @param {String[]} [inputType=["touch", "pointer"]] Types of input devices + * - touch: Touch screen + * - pointer: Mouse and touch 입력 장치 종류 + * - touch: 터치 입력 장치 + * - pointer: 마우스 및 터치 + * @param {String} [touchAction="none"] Value that overrides the element's "touch-action" css property. It is set to "none" to prevent scrolling during touch. 엘리먼트의 "touch-action" CSS 속성을 덮어쓰는 값. 터치 도중 스크롤을 방지하기 위해 "none" 으로 설정되어 있다. + **/ + + /** + * A module that passes the amount of change to eg.Axes when two pointers are moving toward (zoom-in) or away from each other (zoom-out). use one axis. + * @ko 2개의 pointer를 이용하여 zoom-in하거나 zoom-out 하는 동작의 변화량을 eg.Axes에 전달하는 모듈. 한 개 의 축을 사용한다. + * @example + * ```js + * const pinch = new eg.Axes.PinchInput("#area", { + * scale: 1 + * }); + * + * // Connect 'something' axis when two pointers are moving toward (zoom-in) or away from each other (zoom-out). + * axes.connect("something", pinch); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.PinchInput module eg.Axes.PinchInput 모듈을 사용할 엘리먼트 + * @param {PinchInputOption} [options] The option object of the eg.Axes.PinchInput moduleeg.Axes.PinchInput 모듈의 옵션 객체 + */ + + var PinchInput = + /*#__PURE__*/ + function () { + /** + * + */ + function PinchInput(el, options) { + this.axes = []; + this.element = null; + this._pinchFlag = false; + this._enabled = false; + this._activeEvent = null; + this.element = $(el); + this.options = __assign$1({ + scale: 1, + threshold: 0, + inputType: ["touch", "pointer"], + touchAction: "none" + }, options); + this._onPinchStart = this._onPinchStart.bind(this); + this._onPinchMove = this._onPinchMove.bind(this); + this._onPinchEnd = this._onPinchEnd.bind(this); + } + + var __proto = PinchInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this._activeEvent) { + this._detachEvent(); + } + + this._attachEvent(observer); + + this._originalCssProps = setCssProps(this.element, this.options, DIRECTION_ALL); + return this; + }; + + __proto.disconnect = function () { + this._detachEvent(); + + if (!isCssPropsFromAxes(this._originalCssProps)) { + revertCssProps(this.element, this._originalCssProps); + } + + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {PinchInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {PinchInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onPinchStart = function (event) { + var activeEvent = this._activeEvent; + var pinchEvent = activeEvent.onEventStart(event); + + if (!pinchEvent || !this._enabled || activeEvent.getTouches(event) !== 2) { + return; + } + + this._baseValue = this._observer.get(this)[this.axes[0]]; + + this._observer.hold(this, event); + + this._pinchFlag = true; + activeEvent.prevEvent = pinchEvent; + }; + + __proto._onPinchMove = function (event) { + var activeEvent = this._activeEvent; + var pinchEvent = activeEvent.onEventMove(event); + + if (!pinchEvent || !this._pinchFlag || !this._enabled || activeEvent.getTouches(event) !== 2) { + return; + } + + var offset = this._getOffset(pinchEvent.scale, activeEvent.prevEvent.scale); + + this._observer.change(this, event, toAxis(this.axes, [offset])); + + activeEvent.prevEvent = pinchEvent; + }; + + __proto._onPinchEnd = function (event) { + var activeEvent = this._activeEvent; + activeEvent.onEventEnd(event); + + if (!this._pinchFlag || !this._enabled || activeEvent.getTouches(event) >= 2) { + return; + } + + activeEvent.onRelease(); + + this._observer.release(this, event, [0], 0); + + this._baseValue = null; + this._pinchFlag = false; + }; + + __proto._attachEvent = function (observer) { + var _this = this; + + var activeEvent = convertInputType(this.options.inputType); + + if (!activeEvent) { + return; + } + + this._observer = observer; + this._enabled = true; + this._activeEvent = activeEvent; + activeEvent.start.forEach(function (event) { + _this.element.addEventListener(event, _this._onPinchStart, false); + }); + activeEvent.move.forEach(function (event) { + _this.element.addEventListener(event, _this._onPinchMove, false); + }); + activeEvent.end.forEach(function (event) { + _this.element.addEventListener(event, _this._onPinchEnd, false); + }); + }; + + __proto._detachEvent = function () { + var _this = this; + + var activeEvent = this._activeEvent; + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.start.forEach(function (event) { + _this.element.removeEventListener(event, _this._onPinchStart, false); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.move.forEach(function (event) { + _this.element.removeEventListener(event, _this._onPinchMove, false); + }); + activeEvent === null || activeEvent === void 0 ? void 0 : activeEvent.end.forEach(function (event) { + _this.element.removeEventListener(event, _this._onPinchEnd, false); + }); + this._enabled = false; + this._observer = null; + }; + + __proto._getOffset = function (pinchScale, prev) { + if (prev === void 0) { + prev = 1; + } + + return this._baseValue * (pinchScale - prev) * this.options.scale; + }; + + return PinchInput; + }(); + + /** + * @typedef {Object} WheelInputOption The option object of the eg.Axes.WheelInput module + * @ko eg.Axes.WheelInput 모듈의 옵션 객체 + * @param {Number} [scale=1] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [releaseDelay=300] Millisecond that trigger release event after last input마지막 입력 이후 release 이벤트가 트리거되기까지의 밀리초 + * @param {Boolean} [useNormalized=true] Whether to calculate scroll speed the same in all browsers모든 브라우저에서 스크롤 속도를 동일하게 처리할지 여부 + * @param {Boolean} [useAnimation=false] Whether to process coordinate changes through the mouse wheel as a continuous animation마우스 휠을 통한 좌표 변화를 연속적인 애니메이션으로 처리할지 여부 + **/ + + /** + * A module that passes the amount of change to eg.Axes when the mouse wheel is moved. use one axis. + * @ko 마우스 휠이 움직일때의 변화량을 eg.Axes에 전달하는 모듈. 한 개 의 축을 사용한다. + * + * @example + * ```js + * const wheel = new eg.Axes.WheelInput("#area", { + * scale: 1 + * }); + * + * // Connect 'something' axis when the mousewheel is moved. + * axes.connect("something", wheel); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.WheelInput module eg.Axes.WheelInput 모듈을 사용할 엘리먼트 + * @param {WheelInputOption} [options] The option object of the eg.Axes.WheelInput moduleeg.Axes.WheelInput 모듈의 옵션 객체 + */ + + var WheelInput = + /*#__PURE__*/ + function () { + /** + * + */ + function WheelInput(el, options) { + this.axes = []; + this.element = null; + this._enabled = false; + this._holding = false; + this._timer = null; + this.element = $(el); + this.options = __assign$1({ + scale: 1, + releaseDelay: 300, + useNormalized: true, + useAnimation: false + }, options); + this._onWheel = this._onWheel.bind(this); + } + + var __proto = WheelInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + this._detachEvent(); + + this._attachEvent(observer); + + return this; + }; + + __proto.disconnect = function () { + this._detachEvent(); + + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {WheelInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {WheelInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onWheel = function (event) { + var _this = this; + + if (!this._enabled) { + return; + } + + event.preventDefault(); + + if (event.deltaY === 0) { + return; + } + + if (!this._holding) { + this._observer.hold(this, event); + + this._holding = true; + } + + var offset = (event.deltaY > 0 ? -1 : 1) * this.options.scale * (this.options.useNormalized ? 1 : Math.abs(event.deltaY)); + + this._observer.change(this, event, toAxis(this.axes, [offset]), this.options.useAnimation); + + clearTimeout(this._timer); + this._timer = setTimeout(function () { + if (_this._holding) { + _this._holding = false; + + _this._observer.release(_this, event, [0]); + } + }, this.options.releaseDelay); + }; + + __proto._attachEvent = function (observer) { + this._observer = observer; + this.element.addEventListener("wheel", this._onWheel); + this._enabled = true; + }; + + __proto._detachEvent = function () { + this.element.removeEventListener("wheel", this._onWheel); + this._enabled = false; + this._observer = null; + + if (this._timer) { + clearTimeout(this._timer); + this._timer = null; + } + }; + + return WheelInput; + }(); + + var KEY_LEFT_ARROW = 37; + var KEY_A = 65; + var KEY_UP_ARROW = 38; + var KEY_W = 87; + var KEY_RIGHT_ARROW = 39; + var KEY_D = 68; + var KEY_DOWN_ARROW = 40; + var KEY_S = 83; + /* eslint-disable */ + + var DIRECTION_REVERSE = -1; + var DIRECTION_FORWARD = 1; + var DIRECTION_HORIZONTAL$1 = -1; + var DIRECTION_VERTICAL$1 = 1; + var DELAY = 80; + /** + * @typedef {Object} MoveKeyInputOption The option object of the eg.Axes.MoveKeyInput module + * @ko eg.Axes.MoveKeyInput 모듈의 옵션 객체 + * @param {Array} [scale] Coordinate scale that a user can move사용자의 동작으로 이동하는 좌표의 배율 + * @param {Number} [scale[0]=1] Coordinate scale for the first axis첫번째 축의 배율 + * @param {Number} [scale[1]=1] Coordinate scale for the decond axis두번째 축의 배율 + **/ + + /** + * A module that passes the amount of change to eg.Axes when the move key stroke is occured. use two axis. + * @ko 이동키 입력이 발생했을 때의 변화량을 eg.Axes에 전달하는 모듈. 두 개 의 축을 사용한다. + * + * @example + * ```js + * const moveKey = new eg.Axes.MoveKeyInput("#area", { + * scale: [1, 1] + * }); + * + * // Connect 'x', 'y' axes when the moveKey is pressed. + * axes.connect(["x", "y"], moveKey); + * ``` + * @param {HTMLElement|String|jQuery} element An element to use the eg.Axes.MoveKeyInput module eg.Axes.MoveKeyInput 모듈을 사용할 엘리먼트 + * @param {MoveKeyInputOption} [options] The option object of the eg.Axes.MoveKeyInput moduleeg.Axes.MoveKeyInput 모듈의 옵션 객체 + */ + + var MoveKeyInput = + /*#__PURE__*/ + function () { + /** + * + */ + function MoveKeyInput(el, options) { + this.axes = []; + this.element = null; + this._enabled = false; + this._holding = false; + this._timer = null; + this.element = $(el); + this.options = __assign$1({ + scale: [1, 1] + }, options); + this._onKeydown = this._onKeydown.bind(this); + this._onKeyup = this._onKeyup.bind(this); + } + + var __proto = MoveKeyInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + this._detachEvent(); // add tabindex="0" to the container for making it focusable + + + if (this.element.getAttribute("tabindex") !== "0") { + this.element.setAttribute("tabindex", "0"); + } + + this._attachEvent(observer); + + return this; + }; + + __proto.disconnect = function () { + this._detachEvent(); + + return this; + }; + /** + * Destroys elements, properties, and events used in a module. + * @ko 모듈에 사용한 엘리먼트와 속성, 이벤트를 해제한다. + */ + + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + }; + /** + * Enables input devices + * @ko 입력 장치를 사용할 수 있게 한다 + * @return {MoveKeyInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.enable = function () { + this._enabled = true; + return this; + }; + /** + * Disables input devices + * @ko 입력 장치를 사용할 수 없게 한다. + * @return {MoveKeyInput} An instance of a module itself 모듈 자신의 인스턴스 + */ + + + __proto.disable = function () { + this._enabled = false; + return this; + }; + /** + * Returns whether to use an input device + * @ko 입력 장치를 사용 여부를 반환한다. + * @return {Boolean} Whether to use an input device 입력장치 사용여부 + */ + + + __proto.isEnabled = function () { + return this._enabled; + }; + + __proto._onKeydown = function (event) { + if (!this._enabled) { + return; + } + + var isMoveKey = true; + var direction = DIRECTION_FORWARD; + var move = DIRECTION_HORIZONTAL$1; + + switch (event.keyCode) { + case KEY_LEFT_ARROW: + case KEY_A: + direction = DIRECTION_REVERSE; + break; + + case KEY_RIGHT_ARROW: + case KEY_D: + break; + + case KEY_DOWN_ARROW: + case KEY_S: + direction = DIRECTION_REVERSE; + move = DIRECTION_VERTICAL$1; + break; + + case KEY_UP_ARROW: + case KEY_W: + move = DIRECTION_VERTICAL$1; + break; + + default: + isMoveKey = false; + } + + if (move === DIRECTION_HORIZONTAL$1 && !this.axes[0] || move === DIRECTION_VERTICAL$1 && !this.axes[1]) { + isMoveKey = false; + } + + if (!isMoveKey) { + return; + } + + event.preventDefault(); + var offsets = move === DIRECTION_HORIZONTAL$1 ? [+this.options.scale[0] * direction, 0] : [0, +this.options.scale[1] * direction]; + + if (!this._holding) { + this._observer.hold(this, event); + + this._holding = true; + } + + clearTimeout(this._timer); + + this._observer.change(this, event, toAxis(this.axes, offsets)); + }; + + __proto._onKeyup = function (event) { + var _this = this; + + if (!this._holding) { + return; + } + + clearTimeout(this._timer); + this._timer = setTimeout(function () { + _this._observer.release(_this, event, [0, 0]); + + _this._holding = false; + }, DELAY); + }; + + __proto._attachEvent = function (observer) { + this._observer = observer; + this.element.addEventListener("keydown", this._onKeydown, false); + this.element.addEventListener("keypress", this._onKeydown, false); + this.element.addEventListener("keyup", this._onKeyup, false); + this._enabled = true; + }; + + __proto._detachEvent = function () { + this.element.removeEventListener("keydown", this._onKeydown, false); + this.element.removeEventListener("keypress", this._onKeydown, false); + this.element.removeEventListener("keyup", this._onKeyup, false); + this._enabled = false; + this._observer = null; + }; + + return MoveKeyInput; + }(); + + /** + * Common utilities + * @module glMatrix + */ + // Configuration Constants + var EPSILON = 0.000001; + var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; + var degree = Math.PI / 180; + /** + * Convert Degree To Radian + * + * @param {Number} a Angle in Degrees + */ + + function toRadian(a) { + return a * degree; + } + if (!Math.hypot) Math.hypot = function () { + var y = 0, + i = arguments.length; + + while (i--) { + y += arguments[i] * arguments[i]; + } + + return Math.sqrt(y); + }; + + /** + * 3x3 Matrix + * @module mat3 + */ + + /** + * Creates a new identity mat3 + * + * @returns {mat3} a new 3x3 matrix + */ + + function create() { + var out = new ARRAY_TYPE(9); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + } + + out[0] = 1; + out[4] = 1; + out[8] = 1; + return out; + } + /** + * Copies the upper-left 3x3 values into the given mat3. + * + * @param {mat3} out the receiving 3x3 matrix + * @param {ReadonlyMat4} a the source 4x4 matrix + * @returns {mat3} out + */ + + function fromMat4(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[4]; + out[4] = a[5]; + out[5] = a[6]; + out[6] = a[8]; + out[7] = a[9]; + out[8] = a[10]; + return out; + } + /** + * Inverts a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function invert(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b01 = a22 * a11 - a12 * a21; + var b11 = -a22 * a10 + a12 * a20; + var b21 = a21 * a10 - a11 * a20; // Calculate the determinant + + var det = a00 * b01 + a01 * b11 + a02 * b21; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = b01 * det; + out[1] = (-a22 * a01 + a02 * a21) * det; + out[2] = (a12 * a01 - a02 * a11) * det; + out[3] = b11 * det; + out[4] = (a22 * a00 - a02 * a20) * det; + out[5] = (-a12 * a00 + a02 * a10) * det; + out[6] = b21 * det; + out[7] = (-a21 * a00 + a01 * a20) * det; + out[8] = (a11 * a00 - a01 * a10) * det; + return out; + } + + /** + * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. + * @module mat4 + */ + + /** + * Creates a new identity mat4 + * + * @returns {mat4} a new 4x4 matrix + */ + + function create$1() { + var out = new ARRAY_TYPE(16); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + } + + out[0] = 1; + out[5] = 1; + out[10] = 1; + out[15] = 1; + return out; + } + /** + * Set a mat4 to the identity matrix + * + * @param {mat4} out the receiving matrix + * @returns {mat4} out + */ + + function identity(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Rotates a matrix by the given angle around the X axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateX(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[4] = a10 * c + a20 * s; + out[5] = a11 * c + a21 * s; + out[6] = a12 * c + a22 * s; + out[7] = a13 * c + a23 * s; + out[8] = a20 * c - a10 * s; + out[9] = a21 * c - a11 * s; + out[10] = a22 * c - a12 * s; + out[11] = a23 * c - a13 * s; + return out; + } + /** + * Rotates a matrix by the given angle around the Y axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateY(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[0] = a00 * c - a20 * s; + out[1] = a01 * c - a21 * s; + out[2] = a02 * c - a22 * s; + out[3] = a03 * c - a23 * s; + out[8] = a00 * s + a20 * c; + out[9] = a01 * s + a21 * c; + out[10] = a02 * s + a22 * c; + out[11] = a03 * s + a23 * c; + return out; + } + /** + * Calculates a 4x4 matrix from the given quaternion + * + * @param {mat4} out mat4 receiving operation result + * @param {ReadonlyQuat} q Quaternion to create matrix from + * + * @returns {mat4} out + */ + + function fromQuat(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[1] = yx + wz; + out[2] = zx - wy; + out[3] = 0; + out[4] = yx - wz; + out[5] = 1 - xx - zz; + out[6] = zy + wx; + out[7] = 0; + out[8] = zx + wy; + out[9] = zy - wx; + out[10] = 1 - xx - yy; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Generates a perspective projection matrix with the given bounds. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + + function perspective(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2), + nf; + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + nf = 1 / (near - far); + out[10] = (far + near) * nf; + out[14] = 2 * far * near * nf; + } else { + out[10] = -1; + out[14] = -2 * near; + } + + return out; + } + + /** + * 3 Dimensional Vector + * @module vec3 + */ + + /** + * Creates a new, empty vec3 + * + * @returns {vec3} a new 3D vector + */ + + function create$2() { + var out = new ARRAY_TYPE(3); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + return out; + } + /** + * Calculates the length of a vec3 + * + * @param {ReadonlyVec3} a vector to calculate length of + * @returns {Number} length of a + */ + + function length(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return Math.hypot(x, y, z); + } + /** + * Creates a new vec3 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} a new 3D vector + */ + + function fromValues(x, y, z) { + var out = new ARRAY_TYPE(3); + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Copy the values from one vec3 to another + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the source vector + * @returns {vec3} out + */ + + function copy(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Set the components of a vec3 to the given values + * + * @param {vec3} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} out + */ + + function set(out, x, y, z) { + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function subtract(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + return out; + } + /** + * Scales a vec3 by a scalar number + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec3} out + */ + + function scale(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + return out; + } + /** + * Normalize a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to normalize + * @returns {vec3} out + */ + + function normalize(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var len = x * x + y * y + z * z; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + out[2] = a[2] * len; + return out; + } + /** + * Calculates the dot product of two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + /** + * Computes the cross product of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function cross(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2]; + var bx = b[0], + by = b[1], + bz = b[2]; + out[0] = ay * bz - az * by; + out[1] = az * bx - ax * bz; + out[2] = ax * by - ay * bx; + return out; + } + /** + * Transforms the vec3 with a mat3. + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat3} m the 3x3 matrix to transform with + * @returns {vec3} out + */ + + function transformMat3(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + out[0] = x * m[0] + y * m[3] + z * m[6]; + out[1] = x * m[1] + y * m[4] + z * m[7]; + out[2] = x * m[2] + y * m[5] + z * m[8]; + return out; + } + /** + * Transforms the vec3 with a quat + * Can also be used for dual quaternions. (Multiply it with the real part) + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec3} out + */ + + function transformQuat(out, a, q) { + // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; + var x = a[0], + y = a[1], + z = a[2]; // var qvec = [qx, qy, qz]; + // var uv = vec3.cross([], qvec, a); + + var uvx = qy * z - qz * y, + uvy = qz * x - qx * z, + uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); + + var uuvx = qy * uvz - qz * uvy, + uuvy = qz * uvx - qx * uvz, + uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); + + var w2 = qw * 2; + uvx *= w2; + uvy *= w2; + uvz *= w2; // vec3.scale(uuv, uuv, 2); + + uuvx *= 2; + uuvy *= 2; + uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); + + out[0] = x + uvx + uuvx; + out[1] = y + uvy + uuvy; + out[2] = z + uvz + uuvz; + return out; + } + /** + * Alias for {@link vec3.length} + * @function + */ + + var len = length; + /** + * Perform some operation over an array of vec3s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach = function () { + var vec = create$2(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 3; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + } + + return a; + }; + }(); + + /** + * 4 Dimensional Vector + * @module vec4 + */ + + /** + * Creates a new, empty vec4 + * + * @returns {vec4} a new 4D vector + */ + + function create$3() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 0; + } + + return out; + } + /** + * Creates a new vec4 initialized with values from an existing vector + * + * @param {ReadonlyVec4} a vector to clone + * @returns {vec4} a new 4D vector + */ + + function clone(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a new vec4 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} a new 4D vector + */ + + function fromValues$1(x, y, z, w) { + var out = new ARRAY_TYPE(4); + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Copy the values from one vec4 to another + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the source vector + * @returns {vec4} out + */ + + function copy$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Normalize a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to normalize + * @returns {vec4} out + */ + + function normalize$1(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + var len = x * x + y * y + z * z + w * w; + + if (len > 0) { + len = 1 / Math.sqrt(len); + } + + out[0] = x * len; + out[1] = y * len; + out[2] = z * len; + out[3] = w * len; + return out; + } + /** + * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function exactEquals(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Perform some operation over an array of vec4s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach$1 = function () { + var vec = create$3(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 4; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + vec[3] = a[i + 3]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + a[i + 3] = vec[3]; + } + + return a; + }; + }(); + + /** + * Quaternion + * @module quat + */ + + /** + * Creates a new identity quat + * + * @returns {quat} a new quaternion + */ + + function create$4() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + out[3] = 1; + return out; + } + /** + * Sets a quat from the given angle and rotation axis, + * then returns it. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyVec3} axis the axis around which to rotate + * @param {Number} rad the angle in radians + * @returns {quat} out + **/ + + function setAxisAngle(out, axis, rad) { + rad = rad * 0.5; + var s = Math.sin(rad); + out[0] = s * axis[0]; + out[1] = s * axis[1]; + out[2] = s * axis[2]; + out[3] = Math.cos(rad); + return out; + } + /** + * Multiplies two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {quat} out + */ + + function multiply(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + out[0] = ax * bw + aw * bx + ay * bz - az * by; + out[1] = ay * bw + aw * by + az * bx - ax * bz; + out[2] = az * bw + aw * bz + ax * by - ay * bx; + out[3] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Performs a spherical linear interpolation between two quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + function slerp(out, a, b, t) { + // benchmarks: + // http://jsperf.com/quaternion-slerp-implementations + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + var omega, cosom, sinom, scale0, scale1; // calc cosine + + cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) + + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } // calculate coefficients + + + if (1.0 - cosom > EPSILON) { + // standard case (slerp) + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } else { + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + scale0 = 1.0 - t; + scale1 = t; + } // calculate final values + + + out[0] = scale0 * ax + scale1 * bx; + out[1] = scale0 * ay + scale1 * by; + out[2] = scale0 * az + scale1 * bz; + out[3] = scale0 * aw + scale1 * bw; + return out; + } + /** + * Calculates the conjugate of a quat + * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate conjugate of + * @returns {quat} out + */ + + function conjugate(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a quaternion from the given 3x3 rotation matrix. + * + * NOTE: The resultant quaternion is not normalized, so you should be sure + * to renormalize the quaternion yourself where necessary. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyMat3} m rotation matrix + * @returns {quat} out + * @function + */ + + function fromMat3(out, m) { + // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + // article "Quaternion Calculus and Fast Animation". + var fTrace = m[0] + m[4] + m[8]; + var fRoot; + + if (fTrace > 0.0) { + // |w| > 1/2, may as well choose w > 1/2 + fRoot = Math.sqrt(fTrace + 1.0); // 2w + + out[3] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; // 1/(4w) + + out[0] = (m[5] - m[7]) * fRoot; + out[1] = (m[6] - m[2]) * fRoot; + out[2] = (m[1] - m[3]) * fRoot; + } else { + // |w| <= 1/2 + var i = 0; + if (m[4] > m[0]) i = 1; + if (m[8] > m[i * 3 + i]) i = 2; + var j = (i + 1) % 3; + var k = (i + 2) % 3; + fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); + out[i] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; + out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; + out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; + } + + return out; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {ReadonlyQuat} a quaternion to clone + * @returns {quat} a new quaternion + * @function + */ + + var clone$1 = clone; + /** + * Creates a new quat initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} a new quaternion + * @function + */ + + var fromValues$2 = fromValues$1; + /** + * Copy the values from one quat to another + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the source quaternion + * @returns {quat} out + * @function + */ + + var copy$2 = copy$1; + /** + * Normalize a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quaternion to normalize + * @returns {quat} out + * @function + */ + + var normalize$2 = normalize$1; + /** + * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyQuat} a The first quaternion. + * @param {ReadonlyQuat} b The second quaternion. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + var exactEquals$1 = exactEquals; + /** + * Returns whether or not the quaternions have approximately the same elements in the same position. + * + * @param {ReadonlyQuat} a The first vector. + * @param {ReadonlyQuat} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + var equals$1 = equals; + /** + * Sets a quaternion to represent the shortest rotation from one + * vector to another. + * + * Both vectors are assumed to be unit length. + * + * @param {quat} out the receiving quaternion. + * @param {ReadonlyVec3} a the initial vector + * @param {ReadonlyVec3} b the destination vector + * @returns {quat} out + */ + + var rotationTo = function () { + var tmpvec3 = create$2(); + var xUnitVec3 = fromValues(1, 0, 0); + var yUnitVec3 = fromValues(0, 1, 0); + return function (out, a, b) { + var dot$1 = dot(a, b); + + if (dot$1 < -0.999999) { + cross(tmpvec3, xUnitVec3, a); + if (len(tmpvec3) < 0.000001) cross(tmpvec3, yUnitVec3, a); + normalize(tmpvec3, tmpvec3); + setAxisAngle(out, tmpvec3, Math.PI); + return out; + } else if (dot$1 > 0.999999) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } else { + cross(tmpvec3, a, b); + out[0] = tmpvec3[0]; + out[1] = tmpvec3[1]; + out[2] = tmpvec3[2]; + out[3] = 1 + dot$1; + return normalize$2(out, out); + } + }; + }(); + /** + * Performs a spherical linear interpolation with two control points + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {ReadonlyQuat} c the third operand + * @param {ReadonlyQuat} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + var sqlerp = function () { + var temp1 = create$4(); + var temp2 = create$4(); + return function (out, a, b, c, d, t) { + slerp(temp1, a, d, t); + slerp(temp2, b, c, t); + slerp(out, temp1, temp2, 2 * t * (1 - t)); + return out; + }; + }(); + /** + * Sets the specified quaternion with values corresponding to the given + * axes. Each axis is a vec3 and is expected to be unit length and + * perpendicular to all other specified axes. + * + * @param {ReadonlyVec3} view the vector representing the viewing direction + * @param {ReadonlyVec3} right the vector representing the local "right" direction + * @param {ReadonlyVec3} up the vector representing the local "up" direction + * @returns {quat} out + */ + + var setAxes = function () { + var matr = create(); + return function (out, view, right, up) { + matr[0] = right[0]; + matr[3] = right[1]; + matr[6] = right[2]; + matr[1] = up[0]; + matr[4] = up[1]; + matr[7] = up[2]; + matr[2] = -view[0]; + matr[5] = -view[1]; + matr[8] = -view[2]; + return normalize$2(out, fromMat3(out, matr)); + }; + }(); + + /** + * 2 Dimensional Vector + * @module vec2 + */ + + /** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */ + + function create$5() { + var out = new ARRAY_TYPE(2); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + } + + return out; + } + /** + * Creates a new vec2 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} a new 2D vector + */ + + function fromValues$3(x, y) { + var out = new ARRAY_TYPE(2); + out[0] = x; + out[1] = y; + return out; + } + /** + * Copy the values from one vec2 to another + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the source vector + * @returns {vec2} out + */ + + function copy$3(out, a) { + out[0] = a[0]; + out[1] = a[1]; + return out; + } + /** + * Normalize a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to normalize + * @returns {vec2} out + */ + + function normalize$3(out, a) { + var x = a[0], + y = a[1]; + var len = x * x + y * y; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + return out; + } + /** + * Calculates the dot product of two vec2's + * + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot$1(a, b) { + return a[0] * b[0] + a[1] * b[1]; + } + /** + * Perform some operation over an array of vec2s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach$2 = function () { + var vec = create$5(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 2; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + } + + return a; + }; + }(); + + /** + * Original Code + * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js + * Math Util + * modified by egjs + */ + + var quatToVec3 = function (quaternion) { + var baseV = fromValues(0, 0, 1); + transformQuat(baseV, baseV, quaternion); + return baseV; + }; + + var toDegree = function (a) { + return a * 180 / Math.PI; + }; + + var util = {}; + + util.isPowerOfTwo = function (n) { + return n && (n & n - 1) === 0; + }; + + util.extractPitchFromQuat = function (quaternion) { + var baseV = quatToVec3(quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + }; + + util.hypot = Math.hypot || function (x, y) { + return Math.sqrt(x * x + y * y); + }; // implement reference + // the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식 + // calculating angle between two vectors : http://darkpgmr.tistory.com/121 + + + var ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] + }; + + var getRotationDelta = function (prevQ, curQ, rotateKind) { + var targetAxis = fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + var meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + var prevQuaternion = clone$1(prevQ); + var curQuaternion = clone$1(curQ); + normalize$2(prevQuaternion, prevQuaternion); + normalize$2(curQuaternion, curQuaternion); + var prevPoint = fromValues(0, 0, 1); + var curPoint = fromValues(0, 0, 1); + transformQuat(prevPoint, prevPoint, prevQuaternion); + transformQuat(curPoint, curPoint, curQuaternion); + transformQuat(targetAxis, targetAxis, curQuaternion); + var rotateDistance = dot(targetAxis, cross(create$2(), prevPoint, curPoint)); + var rotateDirection = rotateDistance > 0 ? 1 : -1; // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + + var meshPoint2 = fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + var meshPoint3; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = fromValues(rotateDirection, 0, 0); + } + + transformQuat(meshPoint2, meshPoint2, curQuaternion); + transformQuat(meshPoint3, meshPoint3, curQuaternion); + var vecU = meshPoint2; + var vecV = meshPoint3; + var vecN = create$2(); + cross(vecN, vecU, vecV); + normalize(vecN, vecN); + var coefficientA = vecN[0]; + var coefficientB = vecN[1]; + var coefficientC = vecN[2]; // const coefficientD = -1 * vec3.dot(vecN, meshPoint1); + // a point on the plane + + curPoint = fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + transformQuat(curPoint, curPoint, curQuaternion); // a point should project on the plane + + prevPoint = fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + transformQuat(prevPoint, prevPoint, prevQuaternion); // distance between prevPoint and the plane + + var distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + var projectedPrevPoint = create$2(); + subtract(projectedPrevPoint, prevPoint, scale(create$2(), vecN, distance)); + var trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (length(projectedPrevPoint) * length(curPoint)); // defensive block + + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + + var theta = Math.acos(trigonometricRatio); + var crossVec = cross(create$2(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + var thetaDirection; + + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + + var deltaRadian = theta * thetaDirection * rotateDirection; + return toDegree(deltaRadian); + }; + + var angleBetweenVec2 = function (v1, v2) { + var det = v1[0] * v2[1] - v2[0] * v1[1]; + var theta = -Math.atan2(det, dot$1(v1, v2)); + return theta; + }; + + util.yawOffsetBetween = function (viewDir, targetDir) { + var viewDirXZ = fromValues$3(viewDir[0], viewDir[2]); + var targetDirXZ = fromValues$3(targetDir[0], targetDir[2]); + normalize$3(viewDirXZ, viewDirXZ); + normalize$3(targetDirXZ, targetDirXZ); + var theta = -angleBetweenVec2(viewDirXZ, targetDirXZ); + return theta; + }; + + util.sign = function (x) { + return Math.sign ? Math.sign(x) : Number(x > 0) - Number(x < 0) || +x; + }; + + util.toDegree = toDegree; + util.getRotationDelta = getRotationDelta; + util.angleBetweenVec2 = angleBetweenVec2; + + var toAxis$1 = function (source, offset) { + return offset.reduce(function (acc, v, i) { + if (source[i]) { + acc[source[i]] = v; + } + + return acc; + }, {}); + }; + + /** + * Returns a number value indiciating the version of Chrome being used, + * or otherwise `null` if not on Chrome. + * + * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19 + */ + + /** + * In Chrome m65, `devicemotion` events are broken but subsequently fixed + * in 65.0.3325.148. Since many browsers use Chromium, ensure that + * we scope this detection by branch and build numbers to provide + * a proper fallback. + * https://github.com/immersive-web/webvr-polyfill/issues/307 + */ + + var version = -1; // It should not be null because it will be compared with number + + var branch = null; + var build = null; + var match = /Chrome\/([0-9]+)\.(?:[0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(userAgent); + + if (match) { + version = parseInt(match[1], 10); + branch = match[2]; + build = match[3]; + } + + var CHROME_VERSION = version; + var IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === "3325" && parseInt(build, 10) < 148; + var IS_ANDROID = /Android/i.test(userAgent); + var CONTROL_MODE_VR = 1; + var CONTROL_MODE_YAWPITCH = 2; + var TOUCH_DIRECTION_NONE = 1; + var TOUCH_DIRECTION_YAW = 2; + var TOUCH_DIRECTION_PITCH = 4; + var TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH; + /* Const for MovableCoord */ + + var MC_DECELERATION = 0.0014; + var MC_MAXIMUM_DURATION = 1000; + var MC_BIND_SCALE = [0.20, 0.20]; + var MAX_FIELD_OF_VIEW = 110; + var PAN_SCALE = 320; // const DELTA_THRESHOLD = 0.015; + + var YAW_RANGE_HALF = 180; + var PITCH_RANGE_HALF = 90; + var CIRCULAR_PITCH_RANGE_HALF = 180; + var GYRO_MODE = { + NONE: "none", + YAWPITCH: "yawPitch", + VR: "VR" + }; + + /* eslint-disable */ + var MathUtil = win.MathUtil || {}; + MathUtil.degToRad = Math.PI / 180; + MathUtil.radToDeg = 180 / Math.PI; // Some minimal math functionality borrowed from THREE.Math and stripped down + // for the purposes of this library. + + MathUtil.Vector2 = function (x, y) { + this.x = x || 0; + this.y = y || 0; + }; + + MathUtil.Vector2.prototype = { + constructor: MathUtil.Vector2, + set: function (x, y) { + this.x = x; + this.y = y; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + return this; + }, + subVectors: function (a, b) { + this.x = a.x - b.x; + this.y = a.y - b.y; + return this; + } + }; + + MathUtil.Vector3 = function (x, y, z) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + }; + + MathUtil.Vector3.prototype = { + constructor: MathUtil.Vector3, + set: function (x, y, z) { + this.x = x; + this.y = y; + this.z = z; + return this; + }, + copy: function (v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + return this; + }, + length: function () { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + }, + normalize: function () { + var scalar = this.length(); + + if (scalar !== 0) { + var invScalar = 1 / scalar; + this.multiplyScalar(invScalar); + } else { + this.x = 0; + this.y = 0; + this.z = 0; + } + + return this; + }, + multiplyScalar: function (scalar) { + this.x *= scalar; + this.y *= scalar; + this.z *= scalar; + }, + applyQuaternion: function (q) { + var x = this.x; + var y = this.y; + var z = this.z; + var qx = q.x; + var qy = q.y; + var qz = q.z; + var qw = q.w; // calculate quat * vector + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + + this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return this; + }, + dot: function (v) { + return this.x * v.x + this.y * v.y + this.z * v.z; + }, + crossVectors: function (a, b) { + var ax = a.x; + var ay = a.y; + var az = a.z; + var bx = b.x; + var by = b.y; + var bz = b.z; + this.x = ay * bz - az * by; + this.y = az * bx - ax * bz; + this.z = ax * by - ay * bx; + return this; + } + }; + + MathUtil.Quaternion = function (x, y, z, w) { + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w !== undefined ? w : 1; + }; + + MathUtil.Quaternion.prototype = { + constructor: MathUtil.Quaternion, + set: function (x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + return this; + }, + copy: function (quaternion) { + this.x = quaternion.x; + this.y = quaternion.y; + this.z = quaternion.z; + this.w = quaternion.w; + return this; + }, + setFromEulerXYZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + return this; + }, + setFromEulerYXZ: function (x, y, z) { + var c1 = Math.cos(x / 2); + var c2 = Math.cos(y / 2); + var c3 = Math.cos(z / 2); + var s1 = Math.sin(x / 2); + var s2 = Math.sin(y / 2); + var s3 = Math.sin(z / 2); + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + return this; + }, + setFromAxisAngle: function (axis, angle) { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm + // assumes axis is normalized + var halfAngle = angle / 2; + var s = Math.sin(halfAngle); + this.x = axis.x * s; + this.y = axis.y * s; + this.z = axis.z * s; + this.w = Math.cos(halfAngle); + return this; + }, + multiply: function (q) { + return this.multiplyQuaternions(this, q); + }, + multiplyQuaternions: function (a, b) { + // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm + var qax = a.x; + var qay = a.y; + var qaz = a.z; + var qaw = a.w; + var qbx = b.x; + var qby = b.y; + var qbz = b.z; + var qbw = b.w; + this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; + this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; + this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; + this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; + return this; + }, + inverse: function () { + this.x *= -1; + this.y *= -1; + this.z *= -1; + this.normalize(); + return this; + }, + normalize: function () { + var l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + + if (l === 0) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 1; + } else { + l = 1 / l; + this.x = this.x * l; + this.y = this.y * l; + this.z = this.z * l; + this.w = this.w * l; + } + + return this; + }, + slerp: function (qb, t) { + if (t === 0) return this; + if (t === 1) return this.copy(qb); + var x = this.x; + var y = this.y; + var z = this.z; + var w = this.w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ + + var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z; + + if (cosHalfTheta < 0) { + this.w = -qb.w; + this.x = -qb.x; + this.y = -qb.y; + this.z = -qb.z; + cosHalfTheta = -cosHalfTheta; + } else { + this.copy(qb); + } + + if (cosHalfTheta >= 1.0) { + this.w = w; + this.x = x; + this.y = y; + this.z = z; + return this; + } + + var halfTheta = Math.acos(cosHalfTheta); + var sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta); + + if (Math.abs(sinHalfTheta) < 0.001) { + this.w = 0.5 * (w + this.w); + this.x = 0.5 * (x + this.x); + this.y = 0.5 * (y + this.y); + this.z = 0.5 * (z + this.z); + return this; + } + + var ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta; + var ratioB = Math.sin(t * halfTheta) / sinHalfTheta; + this.w = w * ratioA + this.w * ratioB; + this.x = x * ratioA + this.x * ratioB; + this.y = y * ratioA + this.y * ratioB; + this.z = z * ratioA + this.z * ratioB; + return this; + }, + setFromUnitVectors: function () { + // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final + // assumes direction vectors vFrom and vTo are normalized + var v1; + var r; + var EPS = 0.000001; + return function (vFrom, vTo) { + if (v1 === undefined) v1 = new MathUtil.Vector3(); + r = vFrom.dot(vTo) + 1; + + if (r < EPS) { + r = 0; + + if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) { + v1.set(-vFrom.y, vFrom.x, 0); + } else { + v1.set(0, -vFrom.z, vFrom.y); + } + } else { + v1.crossVectors(vFrom, vTo); + } + + this.x = v1.x; + this.y = v1.y; + this.z = v1.z; + this.w = r; + this.normalize(); + return this; + }; + }() + }; + + /* eslint-disable */ + + /* + * Copyright 2015 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + var _a; // tslint:disable: only-arrow-functions + var userAgent$1 = (_a = nav === null || nav === void 0 ? void 0 : nav.userAgent) !== null && _a !== void 0 ? _a : ""; + var Util = win.Util || {}; + Util.MIN_TIMESTEP = 0.001; + Util.MAX_TIMESTEP = 1; + + Util.base64 = function (mimeType, base64) { + return "data:" + mimeType + ";base64," + base64; + }; + + Util.clamp = function (value, min, max) { + return Math.min(Math.max(min, value), max); + }; + + Util.lerp = function (a, b, t) { + return a + (b - a) * t; + }; + + Util.isIOS = function () { + var isIOS = /iPad|iPhone|iPod/.test(nav === null || nav === void 0 ? void 0 : nav.platform); + return function () { + return isIOS; + }; + }(); + + Util.isWebViewAndroid = function () { + var isWebViewAndroid = userAgent$1.indexOf("Version") !== -1 && userAgent$1.indexOf("Android") !== -1 && userAgent$1.indexOf("Chrome") !== -1; + return function () { + return isWebViewAndroid; + }; + }(); + + Util.isSafari = function () { + var isSafari = /^((?!chrome|android).)*safari/i.test(userAgent$1); + return function () { + return isSafari; + }; + }(); + + Util.isFirefoxAndroid = function () { + var isFirefoxAndroid = userAgent$1.indexOf("Firefox") !== -1 && userAgent$1.indexOf("Android") !== -1; + return function () { + return isFirefoxAndroid; + }; + }(); + + Util.isR7 = function () { + var isR7 = userAgent$1.indexOf("R7 Build") !== -1; + return function () { + return isR7; + }; + }(); + + Util.isLandscapeMode = function () { + var rtn = win.orientation === 90 || win.orientation === -90; + return Util.isR7() ? !rtn : rtn; + }; // Helper method to validate the time steps of sensor timestamps. + + + Util.isTimestampDeltaValid = function (timestampDeltaS) { + if (isNaN(timestampDeltaS)) { + return false; + } + + if (timestampDeltaS <= Util.MIN_TIMESTEP) { + return false; + } + + if (timestampDeltaS > Util.MAX_TIMESTEP) { + return false; + } + + return true; + }; + + Util.getScreenWidth = function () { + return Math.max(win.screen.width, win.screen.height) * win.devicePixelRatio; + }; + + Util.getScreenHeight = function () { + return Math.min(win.screen.width, win.screen.height) * win.devicePixelRatio; + }; + + Util.requestFullscreen = function (element) { + if (Util.isWebViewAndroid()) { + return false; + } + + if (element.requestFullscreen) { + element.requestFullscreen(); + } else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } else { + return false; + } + + return true; + }; + + Util.exitFullscreen = function () { + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else if (doc.webkitExitFullscreen) { + doc.webkitExitFullscreen(); + } else if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } else { + return false; + } + + return true; + }; + + Util.getFullscreenElement = function () { + return doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement; + }; + + Util.linkProgram = function (gl, vertexSource, fragmentSource, attribLocationMap) { + // No error checking for brevity. + var vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vertexSource); + gl.compileShader(vertexShader); + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + for (var attribName in attribLocationMap) gl.bindAttribLocation(program, attribLocationMap[attribName], attribName); + + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + return program; + }; + + Util.getProgramUniforms = function (gl, program) { + var uniforms = {}; + var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + var uniformName = ""; + + for (var i = 0; i < uniformCount; i++) { + var uniformInfo = gl.getActiveUniform(program, i); + uniformName = uniformInfo.name.replace("[0]", ""); + uniforms[uniformName] = gl.getUniformLocation(program, uniformName); + } + + return uniforms; + }; + + Util.orthoMatrix = function (out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 2 * nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = (far + near) * nf; + out[15] = 1; + return out; + }; + + Util.copyArray = function (source, dest) { + for (var i = 0, n = source.length; i < n; i++) { + dest[i] = source[i]; + } + }; + + Util.isMobile = function () { + var check = false; + + (function (a) { + if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true; + })(userAgent$1 || (nav === null || nav === void 0 ? void 0 : nav.vendor) || win.opera); + + return check; + }; + + Util.extend = function (dest, src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dest[key] = src[key]; + } + } + + return dest; + }; + + Util.safariCssSizeWorkaround = function (canvas) { + // TODO(smus): Remove this workaround when Safari for iOS is fixed. + // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556). + // + // "To the last I grapple with thee; + // from hell's heart I stab at thee; + // for hate's sake I spit my last breath at thee." + // -- Moby Dick, by Herman Melville + if (Util.isIOS()) { + var width_1 = canvas.style.width; + var height_1 = canvas.style.height; + canvas.style.width = parseInt(width_1) + 1 + "px"; + canvas.style.height = parseInt(height_1) + "px"; + setTimeout(function () { + canvas.style.width = width_1; + canvas.style.height = height_1; + }, 100); + } // Debug only. + + + win.Util = Util; + win.canvas = canvas; + }; + + Util.isDebug = function () { + return Util.getQueryParameter("debug"); + }; + + Util.getQueryParameter = function (name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"); + var results = regex.exec(location.search); + return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); + }; + + Util.frameDataFromPose = function () { + var piOver180 = Math.PI / 180.0; + var rad45 = Math.PI * 0.25; // Borrowed from glMatrix. + + function mat4_perspectiveFromFieldOfView(out, fov, near, far) { + var upTan = Math.tan(fov ? fov.upDegrees * piOver180 : rad45); + var downTan = Math.tan(fov ? fov.downDegrees * piOver180 : rad45); + var leftTan = Math.tan(fov ? fov.leftDegrees * piOver180 : rad45); + var rightTan = Math.tan(fov ? fov.rightDegrees * piOver180 : rad45); + var xScale = 2.0 / (leftTan + rightTan); + var yScale = 2.0 / (upTan + downTan); + out[0] = xScale; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + out[4] = 0.0; + out[5] = yScale; + out[6] = 0.0; + out[7] = 0.0; + out[8] = -((leftTan - rightTan) * xScale * 0.5); + out[9] = (upTan - downTan) * yScale * 0.5; + out[10] = far / (near - far); + out[11] = -1.0; + out[12] = 0.0; + out[13] = 0.0; + out[14] = far * near / (near - far); + out[15] = 0.0; + return out; + } + + function mat4_fromRotationTranslation(out, q, v) { + // Quaternion math + var x = q[0]; + var y = q[1]; + var z = q[2]; + var w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - (yy + zz); + out[1] = xy + wz; + out[2] = xz - wy; + out[3] = 0; + out[4] = xy - wz; + out[5] = 1 - (xx + zz); + out[6] = yz + wx; + out[7] = 0; + out[8] = xz + wy; + out[9] = yz - wx; + out[10] = 1 - (xx + yy); + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + + function mat4_translate(out, a, v) { + var x = v[0]; + var y = v[1]; + var z = v[2]; + var a00; + var a01; + var a02; + var a03; + var a10; + var a11; + var a12; + var a13; + var a20; + var a21; + var a22; + var a23; + + if (a === out) { + out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; + out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; + out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; + out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; + } else { + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a03; + out[4] = a10; + out[5] = a11; + out[6] = a12; + out[7] = a13; + out[8] = a20; + out[9] = a21; + out[10] = a22; + out[11] = a23; + out[12] = a00 * x + a10 * y + a20 * z + a[12]; + out[13] = a01 * x + a11 * y + a21 * z + a[13]; + out[14] = a02 * x + a12 * y + a22 * z + a[14]; + out[15] = a03 * x + a13 * y + a23 * z + a[15]; + } + + return out; + } + + function mat4_invert(out, a) { + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + var a30 = a[12]; + var a31 = a[13]; + var a32 = a[14]; + var a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + return out; + } + + var defaultOrientation = new Float32Array([0, 0, 0, 1]); + var defaultPosition = new Float32Array([0, 0, 0]); + + function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) { + mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar); + var orientation = pose.orientation || defaultOrientation; + var position = pose.position || defaultPosition; + mat4_fromRotationTranslation(view, orientation, position); + if (parameters) mat4_translate(view, view, parameters.offset); + mat4_invert(view, view); + } + + return function (frameData, pose, vrDisplay) { + if (!frameData || !pose) return false; + frameData.pose = pose; + frameData.timestamp = pose.timestamp; + updateEyeMatrices(frameData.leftProjectionMatrix, frameData.leftViewMatrix, pose, vrDisplay.getEyeParameters("left"), vrDisplay); + updateEyeMatrices(frameData.rightProjectionMatrix, frameData.rightViewMatrix, pose, vrDisplay.getEyeParameters("right"), vrDisplay); + return true; + }; + }(); + + Util.isInsideCrossDomainIFrame = function () { + var isFramed = win.self !== win.top; + var refDomain = Util.getDomainFromUrl(doc.referrer); + var thisDomain = Util.getDomainFromUrl(win.location.href); + return isFramed && refDomain !== thisDomain; + }; // From http://stackoverflow.com/a/23945027. + + + Util.getDomainFromUrl = function (url) { + var domain; // Find & remove protocol (http, ftp, etc.) and get domain. + + if (url.indexOf("://") > -1) { + domain = url.split("/")[2]; + } else { + domain = url.split("/")[0]; + } // find & remove port number + + + domain = domain.split(":")[0]; + return domain; + }; + + /* eslint-disable */ + /** + * Given an orientation and the gyroscope data, predicts the future orientation + * of the head. This makes rendering appear faster. + * + * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf + * @param {Number} predictionTimeS time from head movement to the appearance of + * the corresponding image. + */ + + var PosePredictor = + /*#__PURE__*/ + function () { + function PosePredictor(predictionTimeS) { + this.predictionTimeS = predictionTimeS; // The quaternion corresponding to the previous state. + + this.previousQ = new MathUtil.Quaternion(); // Previous time a prediction occurred. + + this.previousTimestampS = null; // The delta quaternion that adjusts the current pose. + + this.deltaQ = new MathUtil.Quaternion(); // The output quaternion. + + this.outQ = new MathUtil.Quaternion(); + } + + var __proto = PosePredictor.prototype; + + __proto.getPrediction = function (currentQ, gyro, timestampS) { + if (!this.previousTimestampS) { + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return currentQ; + } // Calculate axis and angle based on gyroscope rotation rate data. + + + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + var angularSpeed = gyro.length(); // If we're rotating slowly, don't do prediction. + + if (angularSpeed < MathUtil.degToRad * 20) { + if (Util.isDebug()) { + console.log("Moving slowly, at %s deg/s: no prediction", (MathUtil.radToDeg * angularSpeed).toFixed(1)); + } + + this.outQ.copy(currentQ); + this.previousQ.copy(currentQ); + return this.outQ; + } // Get the predicted angle based on the time delta and latency. + + + var deltaT = timestampS - this.previousTimestampS; + var predictAngle = angularSpeed * this.predictionTimeS; + this.deltaQ.setFromAxisAngle(axis, predictAngle); + this.outQ.copy(this.previousQ); + this.outQ.multiply(this.deltaQ); + this.previousQ.copy(currentQ); + this.previousTimestampS = timestampS; + return this.outQ; + }; + + return PosePredictor; + }(); + + var STILLNESS_THRESHOLD = 200; // millisecond + + var DeviceMotion = + /*#__PURE__*/ + function (_super) { + __extends(DeviceMotion, _super); + + function DeviceMotion() { + var _this = _super.call(this) || this; + + _this._onDeviceMotion = _this._onDeviceMotion.bind(_this); + _this._onDeviceOrientation = _this._onDeviceOrientation.bind(_this); + _this._onChromeWithoutDeviceMotion = _this._onChromeWithoutDeviceMotion.bind(_this); + _this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION; + _this.isAndroid = IS_ANDROID; + _this.stillGyroVec = create$2(); + _this.rawGyroVec = create$2(); + _this.adjustedGyroVec = create$2(); + _this._timer = -1; + _this.lastDevicemotionTimestamp = 0; + _this._isEnabled = false; + + _this.enable(); + + return _this; + } + + var __proto = DeviceMotion.prototype; + + __proto.enable = function () { + if (this.isAndroid) { + win.addEventListener("deviceorientation", this._onDeviceOrientation); + } + + if (this.isWithoutDeviceMotion) { + win.addEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + } else { + win.addEventListener("devicemotion", this._onDeviceMotion); + } + + this._isEnabled = true; + }; + + __proto.disable = function () { + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("deviceorientation", this._onChromeWithoutDeviceMotion); + win.removeEventListener("devicemotion", this._onDeviceMotion); + this._isEnabled = false; + }; + + __proto._onChromeWithoutDeviceMotion = function (e) { + var alpha = e.alpha, + beta = e.beta, + gamma = e.gamma; // There is deviceorientation event trigged with empty values + // on Headless Chrome. + + if (alpha === null) { + return; + } // convert to radian + + + alpha = (alpha || 0) * Math.PI / 180; + beta = (beta || 0) * Math.PI / 180; + gamma = (gamma || 0) * Math.PI / 180; + this.trigger(new ComponentEvent$1("devicemotion", { + inputEvent: { + deviceorientation: { + alpha: alpha, + beta: beta, + gamma: -gamma + } + } + })); + }; + + __proto._onDeviceOrientation = function () { + var _this = this; + + if (this._timer) { + clearTimeout(this._timer); + } + + this._timer = win.setTimeout(function () { + if (new Date().getTime() - _this.lastDevicemotionTimestamp < STILLNESS_THRESHOLD) { + copy(_this.stillGyroVec, _this.rawGyroVec); + } + }, STILLNESS_THRESHOLD); + }; + + __proto._onDeviceMotion = function (e) { + // desktop chrome triggers devicemotion event with empthy sensor values. + // Those events should ignored. + var isGyroSensorAvailable = !(e.rotationRate.alpha == null); + var isGravitySensorAvailable = !(e.accelerationIncludingGravity.x == null); + + if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) { + return; + } + + var devicemotionEvent = __assign({}, e); + + devicemotionEvent.interval = e.interval; + devicemotionEvent.timeStamp = e.timeStamp; + devicemotionEvent.type = e.type; + devicemotionEvent.rotationRate = { + alpha: e.rotationRate.alpha, + beta: e.rotationRate.beta, + gamma: e.rotationRate.gamma + }; + devicemotionEvent.accelerationIncludingGravity = { + x: e.accelerationIncludingGravity.x, + y: e.accelerationIncludingGravity.y, + z: e.accelerationIncludingGravity.z + }; + devicemotionEvent.acceleration = { + x: e.acceleration.x, + y: e.acceleration.y, + z: e.acceleration.z + }; + + if (this.isAndroid) { + set(this.rawGyroVec, e.rotationRate.alpha || 0, e.rotationRate.beta || 0, e.rotationRate.gamma || 0); + subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec); + this.lastDevicemotionTimestamp = new Date().getTime(); + devicemotionEvent.adjustedRotationRate = { + alpha: this.adjustedGyroVec[0], + beta: this.adjustedGyroVec[1], + gamma: this.adjustedGyroVec[2] + }; + } + + this.trigger(new ComponentEvent$1("devicemotion", { + inputEvent: devicemotionEvent + })); + }; + + return DeviceMotion; + }(Component); + + var SensorSample = + /*#__PURE__*/ + function () { + function SensorSample(sample, timestampS) { + this.set(sample, timestampS); + } + + var __proto = SensorSample.prototype; + + __proto.set = function (sample, timestampS) { + this.sample = sample; + this.timestampS = timestampS; + }; + + __proto.copy = function (sensorSample) { + this.set(sensorSample.sample, sensorSample.timestampS); + }; + + return SensorSample; + }(); + + /* eslint-disable */ + /** + * An implementation of a simple complementary filter, which fuses gyroscope and + * accelerometer data from the 'devicemotion' event. + * + * Accelerometer data is very noisy, but stable over the long term. + * Gyroscope data is smooth, but tends to drift over the long term. + * + * This fusion is relatively simple: + * 1. Get orientation estimates from accelerometer by applying a low-pass filter + * on that data. + * 2. Get orientation estimates from gyroscope by integrating over time. + * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the + * short term. + */ + + var ComplementaryFilter = + /*#__PURE__*/ + function () { + function ComplementaryFilter(kFilter) { + this.addGyroMeasurement = function (vector, timestampS) { + this.currentGyroMeasurement.set(vector, timestampS); + var deltaT = timestampS - this.previousGyroMeasurement.timestampS; + + if (Util.isTimestampDeltaValid(deltaT)) { + this.run_(); + } + + this.previousGyroMeasurement.copy(this.currentGyroMeasurement); + }; + + this.kFilter = kFilter; // Raw sensor measurements. + + this.currentAccelMeasurement = new SensorSample(); + this.currentGyroMeasurement = new SensorSample(); + this.previousGyroMeasurement = new SensorSample(); // Set default look direction to be in the correct direction. + + if (Util.isIOS()) { + this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1); + } else { + this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1); + } + + this.previousFilterQ = new MathUtil.Quaternion(); + this.previousFilterQ.copy(this.filterQ); // Orientation based on the accelerometer. + + this.accelQ = new MathUtil.Quaternion(); // Whether or not the orientation has been initialized. + + this.isOrientationInitialized = false; // Running estimate of gravity based on the current orientation. + + this.estimatedGravity = new MathUtil.Vector3(); // Measured gravity based on accelerometer. + + this.measuredGravity = new MathUtil.Vector3(); // Debug only quaternion of gyro-based orientation. + + this.gyroIntegralQ = new MathUtil.Quaternion(); + } + + var __proto = ComplementaryFilter.prototype; + + __proto.addAccelMeasurement = function (vector, timestampS) { + this.currentAccelMeasurement.set(vector, timestampS); + }; + + __proto.getOrientation = function () { + return this.filterQ; + }; + + __proto.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); + + if (Util.isDebug()) { + console.log("Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)", MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ), this.estimatedGravity.x.toFixed(1), this.estimatedGravity.y.toFixed(1), this.estimatedGravity.z.toFixed(1), this.measuredGravity.x.toFixed(1), this.measuredGravity.y.toFixed(1), this.measuredGravity.z.toFixed(1)); + } // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + }; + + __proto.accelToQuaternion_ = function (accel) { + var normAccel = new MathUtil.Vector3(); + normAccel.copy(accel); + normAccel.normalize(); + var quat = new MathUtil.Quaternion(); + quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel); + quat.inverse(); + return quat; + }; + + __proto.gyroToQuaternionDelta_ = function (gyro, dt) { + // Extract axis and angle from the gyroscope data. + var quat = new MathUtil.Quaternion(); + var axis = new MathUtil.Vector3(); + axis.copy(gyro); + axis.normalize(); + quat.setFromAxisAngle(axis, gyro.length() * dt); + return quat; + }; + + return ComplementaryFilter; + }(); + + ComplementaryFilter.prototype.run_ = function () { + if (!this.isOrientationInitialized) { + this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); + this.previousFilterQ.copy(this.accelQ); + this.isOrientationInitialized = true; + return; + } + + var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. + + var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); + this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. + + this.filterQ.copy(this.previousFilterQ); + this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real + // gravity vector from accelerometer. + + var invFilterQ = new MathUtil.Quaternion(); + invFilterQ.copy(this.filterQ); + invFilterQ.inverse(); + this.estimatedGravity.set(0, 0, -1); + this.estimatedGravity.applyQuaternion(invFilterQ); + this.estimatedGravity.normalize(); + this.measuredGravity.copy(this.currentAccelMeasurement.sample); + this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion + // between the two. + + var deltaQ = new MathUtil.Quaternion(); + deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); + deltaQ.inverse(); // Calculate the SLERP target: current orientation plus the measured-estimated + // quaternion delta. + + var targetQ = new MathUtil.Quaternion(); + targetQ.copy(this.filterQ); + targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. + + this.filterQ.slerp(targetQ, 1 - this.kFilter); + this.previousFilterQ.copy(this.filterQ); + + if (!this.isFilterQuaternionInitialized) { + this.isFilterQuaternionInitialized = true; + } + }; + + ComplementaryFilter.prototype.getOrientation = function () { + if (this.isFilterQuaternionInitialized) { + return this.filterQ; + } else { + return null; + } + }; + + var K_FILTER = 0.98; + var PREDICTION_TIME_S = 0.040; + + var FusionPoseSensor = + /*#__PURE__*/ + function (_super) { + __extends(FusionPoseSensor, _super); + + function FusionPoseSensor() { + var _this = _super.call(this) || this; + + _this.deviceMotion = new DeviceMotion(); + _this.accelerometer = new MathUtil.Vector3(); + _this.gyroscope = new MathUtil.Vector3(); + _this._onDeviceMotionChange = _this._onDeviceMotionChange.bind(_this); + _this._onScreenOrientationChange = _this._onScreenOrientationChange.bind(_this); + _this.filter = new ComplementaryFilter(K_FILTER); + _this.posePredictor = new PosePredictor(PREDICTION_TIME_S); + _this.filterToWorldQ = new MathUtil.Quaternion(); + _this.isFirefoxAndroid = Util.isFirefoxAndroid(); // This includes iPhone & iPad(both desktop and mobile mode) ref #326 + + _this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP; // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18 + + _this.isChromeUsingDegrees = CHROME_VERSION >= 66; + _this._isEnabled = false; // Set the filter to world transform, depending on OS. + + if (_this.isIOS) { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2); + } else { + _this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2); + } + + _this.inverseWorldToScreenQ = new MathUtil.Quaternion(); + _this.worldToScreenQ = new MathUtil.Quaternion(); + _this.originalPoseAdjustQ = new MathUtil.Quaternion(); + + _this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -win.orientation * Math.PI / 180); + + _this._setScreenTransform(); // Adjust this filter for being in landscape mode. + + + if (Util.isLandscapeMode()) { + _this.filterToWorldQ.multiply(_this.inverseWorldToScreenQ); + } // Keep track of a reset transform for resetSensor. + + + _this.resetQ = new MathUtil.Quaternion(); + + _this.deviceMotion.on("devicemotion", _this._onDeviceMotionChange); + + _this.enable(); + + return _this; + } + + var __proto = FusionPoseSensor.prototype; + + __proto.enable = function () { + if (this.isEnabled()) { + return; + } + + this.deviceMotion.enable(); + this._isEnabled = true; + win.addEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.disable = function () { + if (!this.isEnabled()) { + return; + } + + this.deviceMotion.disable(); + this._isEnabled = false; + win.removeEventListener("orientationchange", this._onScreenOrientationChange); + }; + + __proto.isEnabled = function () { + return this._isEnabled; + }; + + __proto.destroy = function () { + this.disable(); + this.deviceMotion = null; + }; + + __proto.getOrientation = function () { + var _this = this; + + var orientation; // Hack around using deviceorientation instead of devicemotion + + if (this.deviceMotion.isWithoutDeviceMotion && this._deviceOrientationQ) { + this.deviceOrientationFixQ = this.deviceOrientationFixQ || function () { + var y = new MathUtil.Quaternion().setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -_this._alpha); + return y; + }(); + + orientation = this._deviceOrientationQ; + var out = new MathUtil.Quaternion(); + out.copy(orientation); + out.multiply(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.worldToScreenQ); + out.multiplyQuaternions(this.deviceOrientationFixQ, out); // return quaternion as glmatrix quaternion object + + var outQuat = fromValues$2(out.x, out.y, out.z, out.w); + return normalize$2(outQuat, outQuat); + } else { + // Convert from filter space to the the same system used by the + // deviceorientation event. + orientation = this.filter.getOrientation(); + + if (!orientation) { + return null; + } + + var out = this._convertFusionToPredicted(orientation); // return quaternion as glmatrix quaternion object + + + var outQuat = fromValues$2(out.x, out.y, out.z, out.w); + return normalize$2(outQuat, outQuat); + } + }; + + __proto._triggerChange = function () { + var orientation = this.getOrientation(); // if orientation is not prepared. don't trigger change event + + if (!orientation) { + return; + } + + if (!this._prevOrientation) { + this._prevOrientation = orientation; + return; + } + + if (equals$1(this._prevOrientation, orientation)) { + return; + } + + this.trigger(new ComponentEvent$1("change", { + quaternion: orientation + })); + }; + + __proto._convertFusionToPredicted = function (orientation) { + // Predict orientation. + this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS); // Convert to THREE coordinate system: -Z forward, Y up, X right. + + var out = new MathUtil.Quaternion(); + out.copy(this.filterToWorldQ); + out.multiply(this.resetQ); + out.multiply(this.predictedQ); + out.multiply(this.worldToScreenQ); + return out; + }; + + __proto._onDeviceMotionChange = function (_a) { + var inputEvent = _a.inputEvent; + var deviceorientation = inputEvent.deviceorientation; + var deviceMotion = inputEvent; + var accGravity = deviceMotion.accelerationIncludingGravity; + var rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate; + var timestampS = deviceMotion.timeStamp / 1000; + + if (deviceorientation) { + if (!this._alpha) { + this._alpha = deviceorientation.alpha; + } + + this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion(); + + this._deviceOrientationQ.setFromEulerYXZ(deviceorientation.beta, deviceorientation.alpha, deviceorientation.gamma); + + this._triggerChange(); + } else { + // Firefox Android timeStamp returns one thousandth of a millisecond. + if (this.isFirefoxAndroid) { + timestampS /= 1000; + } + + this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z); + this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma); // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate` + // is reported in degrees, so we first convert to radians. + + if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) { + this.gyroscope.multiplyScalar(Math.PI / 180); + } + + this.filter.addAccelMeasurement(this.accelerometer, timestampS); + this.filter.addGyroMeasurement(this.gyroscope, timestampS); + + this._triggerChange(); + + this.previousTimestampS = timestampS; + } + }; + + __proto._onScreenOrientationChange = function () { + this._setScreenTransform(); + }; + + __proto._setScreenTransform = function () { + this.worldToScreenQ.set(0, 0, 0, 1); + var orientation = win.orientation; + + switch (orientation) { + case 0: + break; + + case 90: + case -90: + case 180: + this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI); + break; + } + + this.inverseWorldToScreenQ.copy(this.worldToScreenQ); + this.inverseWorldToScreenQ.inverse(); + }; + + return FusionPoseSensor; + }(Component); + + var getDeltaYaw = function (prvQ, curQ) { + var yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + var yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(util.extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + }; + + var getDeltaPitch = function (prvQ, curQ) { + var pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + return pitchDelta; + }; // eslint-disable-next-line @typescript-eslint/ban-types + + + var TiltMotionInput = + /*#__PURE__*/ + function (_super) { + __extends(TiltMotionInput, _super); + + function TiltMotionInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.element = el; + _this._prevQuaternion = null; + _this._quaternion = null; + _this.fusionPoseSensor = null; + _this.options = __assign({ + scale: 1, + threshold: 0 + }, options); + _this._onPoseChange = _this._onPoseChange.bind(_this); + return _this; + } + + var __proto = TiltMotionInput.prototype; + + __proto.mapAxes = function (axes) { + this.axes = axes; + }; + + __proto.connect = function (observer) { + if (this.observer) { + return this; + } + + this.observer = observer; + this.fusionPoseSensor = new FusionPoseSensor(); + this.fusionPoseSensor.enable(); + + this._attachEvent(); + + return this; + }; + + __proto.disconnect = function () { + if (!this.observer) { + return this; + } + + this._dettachEvent(); + + this.fusionPoseSensor.disable(); + this.fusionPoseSensor.destroy(); + this.fusionPoseSensor = null; + this.observer = null; + return this; + }; + + __proto.destroy = function () { + this.disconnect(); + this.element = null; + this.options = null; + this.axes = null; + this._prevQuaternion = null; + this._quaternion = null; + }; + + __proto._onPoseChange = function (event) { + if (!this._prevQuaternion) { + this._prevQuaternion = clone$1(event.quaternion); + this._quaternion = clone$1(event.quaternion); + return; + } + + copy$2(this._prevQuaternion, this._quaternion); + copy$2(this._quaternion, event.quaternion); + this.observer.change(this, event, toAxis$1(this.axes, [getDeltaYaw(this._prevQuaternion, this._quaternion), getDeltaPitch(this._prevQuaternion, this._quaternion)])); + }; + + __proto._attachEvent = function () { + this.fusionPoseSensor.on("change", this._onPoseChange); + }; + + __proto._dettachEvent = function () { + this.fusionPoseSensor.off("change", this._onPoseChange); + }; + + return TiltMotionInput; + }(Component); + + var screenRotationAngleInst = null; + var refCount = 0; + + var ScreenRotationAngle = + /*#__PURE__*/ + function () { + function ScreenRotationAngle() { + refCount++; + + if (screenRotationAngleInst) { + return screenRotationAngleInst; + } + /* eslint-disable */ + + + screenRotationAngleInst = this; + /* eslint-enable */ + + this._onDeviceOrientation = this._onDeviceOrientation.bind(this); + this._onOrientationChange = this._onOrientationChange.bind(this); + this._spinR = 0; + this._screenOrientationAngle = 0; + win.addEventListener("deviceorientation", this._onDeviceOrientation); + win.addEventListener("orientationchange", this._onOrientationChange); + } + + var __proto = ScreenRotationAngle.prototype; + + __proto.getRadian = function () { + // Join with screen orientation + // this._testVal = this._spinR + ", " + this._screenOrientationAngle + ", " + window.orientation; + return this._spinR + toRadian(this._screenOrientationAngle); + }; + + __proto.unref = function () { + if (--refCount > 0) { + return; + } + + win.removeEventListener("deviceorientation", this._onDeviceOrientation); + win.removeEventListener("orientationchange", this._onOrientationChange); + this._spinR = 0; + this._screenOrientationAngle = 0; + /* eslint-disable */ + + screenRotationAngleInst = null; + /* eslint-enable */ + + refCount = 0; + }; + + __proto._onDeviceOrientation = function (e) { + if (e.beta === null || e.gamma === null) { + // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it. + return; + } // Radian + + + var betaR = toRadian(e.beta); + var gammaR = toRadian(e.gamma); + /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */ + + this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR)); + }; + + __proto._onOrientationChange = function () { + if (win.screen && win.screen.orientation && win.screen.orientation.angle !== undefined) { + this._screenOrientationAngle = screen.orientation.angle; + } else if (win.orientation !== undefined) { + /* iOS */ + this._screenOrientationAngle = win.orientation >= 0 ? win.orientation : 360 + win.orientation; + } + }; + + return ScreenRotationAngle; + }(); + + /** + * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle. + * + * The reason for using this function is that in VR mode, + * the roll angle is adjusted in the direction opposite to the screen rotation angle. + * + * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move. + * @extends PanInput + */ + + var RotationPanInput = + /*#__PURE__*/ + function (_super) { + __extends(RotationPanInput, _super); + /** + * Constructor + * @private + * @param {HTMLElement} el target element + * @param {Object} [options] The option object + * @param {Boolean} [options.useRotation] Whether to use rotation(or VR) + */ + + + function RotationPanInput(el, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this, el, options) || this; + + _this._useRotation = false; + _this._screenRotationAngle = null; + + _this.setUseRotation(!!(options && options.useRotation)); + + _this._userDirection = Axes.DIRECTION_ALL; + return _this; + } + + var __proto = RotationPanInput.prototype; + + __proto.setUseRotation = function (useRotation) { + this._useRotation = useRotation; + + if (this._screenRotationAngle) { + this._screenRotationAngle.unref(); + + this._screenRotationAngle = null; + } + + if (this._useRotation) { + this._screenRotationAngle = new ScreenRotationAngle(); + } + }; + + __proto.connect = function (observer) { + // User intetened direction + this._userDirection = this._direction; // In VR Mode, Use ALL direction if direction is not none + // Because horizontal and vertical is changed dynamically by screen rotation. + // this._direction is used to initialize hammerjs + + if (this._useRotation && this._direction & Axes.DIRECTION_ALL) { + this._direction = Axes.DIRECTION_HORIZONTAL; + } + + return _super.prototype.connect.call(this, observer); + }; + + __proto.destroy = function () { + if (this._useRotation && this._screenRotationAngle) { + this._screenRotationAngle.unref(); + } + + _super.prototype.destroy.call(this); + }; + + __proto._getOffset = function (properties, useDirection) { + if (this._useRotation === false) { + return _super.prototype._getOffset.call(this, properties, useDirection); + } + + var offset = _super.prototype._getOffset.call(this, properties, [true, true]); + + var newOffset = [0, 0]; + + var theta = this._screenRotationAngle.getRadian(); + + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); // RotateZ + + newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta; + newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta; // Use only user allowed direction. + + if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) { + newOffset[0] = 0; + } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) { + newOffset[1] = 0; + } + + return newOffset; + }; + + return RotationPanInput; + }(PanInput); + /** + * Override getDirectionByAngle to return DIRECTION_ALL + * Ref: https://github.com/naver/egjs-axes/issues/99 + * + * But we obey axes's rule. If axes's rule is problem, let's apply following code. + */ + // PanInput.getDirectionByAngle = function (angle, thresholdAngle) { + // return DIRECTION_ALL; + // }; + + var Y_AXIS_VECTOR = fromValues(0, 1, 0); + + var DeviceQuaternion = + /*#__PURE__*/ + function (_super) { + __extends(DeviceQuaternion, _super); + + function DeviceQuaternion() { + var _this = _super.call(this) || this; + + _this._fusionPoseSensor = new FusionPoseSensor(); + _this._quaternion = create$4(); + + _this._fusionPoseSensor.enable(); + + _this._fusionPoseSensor.on("change", function (e) { + _this._quaternion = e.quaternion; + + _this.trigger(new ComponentEvent$1("change", { + isTrusted: true + })); + }); + + return _this; + } + + var __proto = DeviceQuaternion.prototype; + + __proto.getCombinedQuaternion = function (yaw) { + var yawQ = setAxisAngle(create$4(), Y_AXIS_VECTOR, toRadian(-yaw)); + var conj = conjugate(create$4(), this._quaternion); // Multiply pitch quaternion -> device quaternion -> yaw quaternion + + var outQ = multiply(create$4(), conj, yawQ); + return outQ; + }; + + __proto.destroy = function () { + // detach all event handler + this.off(); + + if (this._fusionPoseSensor) { + this._fusionPoseSensor.off(); + + this._fusionPoseSensor.destroy(); + + this._fusionPoseSensor = null; + } + }; + + return DeviceQuaternion; + }(Component); + + var DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF]; + var DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF]; + var CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF]; + /** + * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates. + * @alias eg.YawPitchControl + * @extends eg.Component + * + * @support {"ie": "10+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + */ + + var YawPitchControl = + /*#__PURE__*/ + function (_super) { + __extends(YawPitchControl, _super); + /** + * @param {object} options The option object of the eg.YawPitch module + * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module + * @param {number} [options.yaw=0] initial yaw (degree) + * @param {number} [options.pitch=0] initial pitch (degree) + * @param {number} [options.fov=65] initial field of view (degree) + * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown + * @param {boolean} [options.useZoom=true] Indicates whether zoom is available + * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled + * @param {string} [config.gyroMode=yawPitch] Enables control through device motion. + * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move) + * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw + * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch + * @param {number[]} [options.fovRange=[30, 110] Range of FOV + * @param {number} [options.aspectRatio=1] Aspect Ratio + */ + + + function YawPitchControl(options) { + var _this = _super.call(this) || this; + + _this.options = {}; + + var opt = __assign({ + element: null, + yaw: 0, + pitch: 0, + fov: 65, + showPolePoint: false, + useZoom: true, + useKeyboard: true, + gyroMode: GYRO_MODE.YAWPITCH, + touchDirection: TOUCH_DIRECTION_ALL, + yawRange: DEFAULT_YAW_RANGE, + pitchRange: DEFAULT_PITCH_RANGE, + fovRange: [30, 110], + aspectRatio: 1 + /* TODO: Need Mandatory? */ + + }, options); + + _this._element = opt.element; + _this._initialFov = opt.fov; + _this._enabled = false; + _this._isAnimating = false; + _this._deviceQuaternion = null; + + _this._initAxes(opt); + + _this.option(opt); + + return _this; + } + /** + * Update Pan Scale + * + * Scale(Sensitivity) values of panning is related with fov and height. + * If at least one of them is changed, this function need to be called. + * @param {*} param + */ + + + var __proto = YawPitchControl.prototype; + + __proto.updatePanScale = function (param) { + if (param === void 0) { + param = {}; + } + + var fov = this._axes.get().fov; + + var areaHeight = param.height || parseInt(window.getComputedStyle(this._element).height, 10); + var scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight; + this._axesPanInput.options.scale = [scale, scale]; + this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW; + return this; + }; + /* + * Override component's option method + * to call method for updating values which is affected by option change. + * + * @param {*} args + */ + + + __proto.option = function (key, newValue) { + // Getter + if (!key) { + return this._getOptions(); + } else if (key && typeof key === "string" && typeof newValue === "undefined") { + return this._getOptions(key); + } // Setter + + + var newOptions = {}; + var changedKeyList = []; // TODO: if value is not changed, then do not push on changedKeyList. + + if (typeof key === "string") { + changedKeyList.push(key); + newOptions[key] = newValue; + } else { + var options = key; // Retrieving object here + + changedKeyList = Object.keys(options); + newOptions = __assign({}, options); + } + + this._setOptions(this._getValidatedOptions(newOptions)); + + this._applyOptions(changedKeyList); + + return this; + }; + /** + * Enable YawPitch functionality + * @method eg.YawPitch#enable + */ + + + __proto.enable = function () { + if (this._enabled) { + return this; + } + + this._enabled = true; // touchDirection is decided by parameter is valid string (Ref. Axes.connect) + + this._applyOptions(Object.keys(this.options)); // TODO: Is this code is needed? Check later. + + + this.updatePanScale(); + return this; + }; + /** + * Disable YawPitch functionality + * @method eg.YawPitch#disable + */ + + + __proto.disable = function (persistOrientation) { + if (persistOrientation === void 0) { + persistOrientation = false; + } + + if (!this._enabled) { + return this; + } // TODO: Check peristOrientation is needed! + + + if (!persistOrientation) { + this._resetOrientation(); + } + + this._axes.disconnect(); + + this._enabled = false; + return this; + }; + /** + * Set one or more of yaw, pitch, fov + * @param {Object} coordinate yaw, pitch, fov + * @param {Number} duration Animation duration. if it is above 0 then it's animated. + */ + + + __proto.lookAt = function (_a, duration) { + var yaw = _a.yaw, + pitch = _a.pitch, + fov = _a.fov; + + var pos = this._axes.get(); + + var y = yaw === undefined ? 0 : yaw - pos.yaw; + var p = pitch === undefined ? 0 : pitch - pos.pitch; + var f = fov === undefined ? 0 : fov - pos.fov; // Allow duration of animation to have more than MC_MAXIMUM_DURATION. + + this._axes.options.maximumDuration = Infinity; + + this._axes.setBy({ + yaw: y, + pitch: p, + fov: f + }, duration); + }; + + __proto.getYawPitch = function () { + var yawPitch = this._axes.get(); + + return { + yaw: yawPitch.yaw, + pitch: yawPitch.pitch + }; + }; + + __proto.getFov = function () { + return this._axes.get().fov; + }; + + __proto.getQuaternion = function () { + var pos = this._axes.get(); + + return this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + }; + + __proto.shouldRenderWithQuaternion = function () { + return this.options.gyroMode === GYRO_MODE.VR; + }; + /** + * Destroys objects + */ + + + __proto.destroy = function () { + /* eslint-disable @typescript-eslint/no-unused-expressions */ + this._axes && this._axes.destroy(); + this._axesPanInput && this._axesPanInput.destroy(); + this._axesWheelInput && this._axesWheelInput.destroy(); + this._axesTiltMotionInput && this._axesTiltMotionInput.destroy(); + this._axesPinchInput && this._axesPinchInput.destroy(); + this._axesMoveKeyInput && this._axesMoveKeyInput.destroy(); + this._deviceQuaternion && this._deviceQuaternion.destroy(); + /* eslint-enable @typescript-eslint/no-unused-expressions */ + }; + + __proto._initAxes = function (opt) { + var _this = this; + + var yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio); + + var pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint); + + var useRotation = opt.gyroMode === GYRO_MODE.VR; + this._axesPanInput = new RotationPanInput(this._element, { + useRotation: useRotation + }); + this._axesWheelInput = new WheelInput(this._element, { + scale: -4 + }); + this._axesTiltMotionInput = null; + this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, { + scale: -1 + }) : null; + this._axesMoveKeyInput = new MoveKeyInput(this._element, { + scale: [-6, 6] + }); + this._axes = new Axes({ + yaw: { + range: yRange, + circular: this._isCircular(yRange), + bounce: [0, 0] + }, + pitch: { + range: pRange, + circular: this._isCircular(pRange), + bounce: [0, 0] + }, + fov: { + range: opt.fovRange, + circular: [false, false], + bounce: [0, 0] + } + }, { + deceleration: MC_DECELERATION, + maximumDuration: MC_MAXIMUM_DURATION + }, { + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }).on({ + // TODO: change event type after Axes event type inference update + hold: function (evt) { + // Restore maximumDuration not to be spin too mush. + _this._axes.options.maximumDuration = MC_MAXIMUM_DURATION; + + _this.trigger(new ComponentEvent$1("hold", { + isTrusted: evt.isTrusted + })); + }, + change: function (evt) { + if (evt.delta.fov !== 0) { + _this._updateControlScale(evt); + + _this.updatePanScale(); + } + + _this._triggerChange(evt); + }, + release: function (evt) { + _this._triggerChange(evt); + }, + animationEnd: function (evt) { + _this.trigger(new ComponentEvent$1("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + }; + + __proto._getValidatedOptions = function (newOptions) { + if (newOptions.yawRange) { + newOptions.yawRange = this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio); + } + + if (newOptions.pitchRange) { + newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov); + } + + return newOptions; + }; + + __proto._getOptions = function (key) { + var value; + + if (typeof key === "string") { + value = this.options[key]; + } else if (arguments.length === 0) { + value = this.options; + } + + return value; + }; + + __proto._setOptions = function (options) { + for (var key in options) { + this.options[key] = options[key]; + } + }; + + __proto._applyOptions = function (keys) { + var options = this.options; + var axes = this._axes; + var isVR = options.gyroMode === GYRO_MODE.VR; + var isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH; // If it's VR mode, restrict user interaction to yaw direction only + + var touchDirection = isVR ? TOUCH_DIRECTION_YAW & options.touchDirection : options.touchDirection; // If one of below is changed, call updateControlScale() + + if (keys.some(function (key) { + return key === "showPolePoint" || key === "fov" || key === "aspectRatio" || key === "yawRange" || key === "pitchRange"; + })) { + // If fov is changed, update pan scale + if (keys.indexOf("fov") >= 0) { + axes.setTo({ + "fov": options.fov + }); + this.updatePanScale(); + } + + this._updateControlScale(); + } + + if (keys.some(function (key) { + return key === "fovRange"; + })) { + var fovRange = options.fovRange; + var prevFov = axes.get().fov; + var nextFov = axes.get().fov; + copy$3(axes.axis.fov.range, fovRange); + + if (nextFov < fovRange[0]) { + nextFov = fovRange[0]; + } else if (prevFov > fovRange[1]) { + nextFov = fovRange[1]; + } + + if (prevFov !== nextFov) { + axes.setTo({ + fov: nextFov + }, 0); + + this._updateControlScale(); + + this.updatePanScale(); + } + } + + if (keys.some(function (key) { + return key === "gyroMode"; + }) && SUPPORT_DEVICEMOTION) { + // Disconnect first + if (this._axesTiltMotionInput) { + this._axes.disconnect(this._axesTiltMotionInput); + + this._axesTiltMotionInput.destroy(); + + this._axesTiltMotionInput = null; + } + + if (this._deviceQuaternion) { + this._deviceQuaternion.destroy(); + + this._deviceQuaternion = null; + } + + if (isVR) { + this._initDeviceQuaternion(); + } else if (isYawPitch) { + this._axesTiltMotionInput = new TiltMotionInput(this._element); + + this._axes.connect(["yaw", "pitch"], this._axesTiltMotionInput); + } + + this._axesPanInput.setUseRotation(isVR); + } + + if (keys.some(function (key) { + return key === "useKeyboard"; + })) { + var useKeyboard = options.useKeyboard; + + if (useKeyboard) { + axes.connect(["yaw", "pitch"], this._axesMoveKeyInput); + } else { + axes.disconnect(this._axesMoveKeyInput); + } + } + + if (keys.some(function (key) { + return key === "useZoom"; + })) { + var useZoom = options.useZoom; // Disconnect first + + axes.disconnect(this._axesWheelInput); + + if (useZoom) { + axes.connect(["fov"], this._axesWheelInput); + } + } + + this._togglePinchInputByOption(options.touchDirection, options.useZoom); + + if (keys.some(function (key) { + return key === "touchDirection"; + }) && this._enabled) { + this._enableTouch(touchDirection); + } + }; + + __proto._togglePinchInputByOption = function (touchDirection, useZoom) { + if (this._axesPinchInput) { + // disconnect first + this._axes.disconnect(this._axesPinchInput); // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll. + + + if (useZoom && touchDirection === TOUCH_DIRECTION_ALL && // TODO: Get rid of using private property of axes instance. + this._axes._inputs.indexOf(this._axesPinchInput) === -1) { + this._axes.connect(["fov"], this._axesPinchInput); + } + } + }; + + __proto._enableTouch = function (direction) { + // Disconnect first + if (this._axesPanInput) { + this._axes.disconnect(this._axesPanInput); + } + + var yawEnabled = direction & TOUCH_DIRECTION_YAW ? "yaw" : null; + var pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? "pitch" : null; + + this._axes.connect([yawEnabled, pitchEnabled], this._axesPanInput); + }; + + __proto._initDeviceQuaternion = function () { + var _this = this; + + this._deviceQuaternion = new DeviceQuaternion(); + + this._deviceQuaternion.on("change", function (e) { + _this._triggerChange(e); + }); + }; + + __proto._getValidYawRange = function (newYawRange, newFov, newAspectRatio) { + var ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1); + + var fov = newFov || this._axes.get().fov; + + var horizontalFov = fov * ratio; + var isValid = newYawRange[1] - newYawRange[0] >= horizontalFov; + + if (isValid) { + return newYawRange; + } else { + return this.options.yawRange || DEFAULT_YAW_RANGE; + } + }; + + __proto._getValidPitchRange = function (newPitchRange, newFov) { + var fov = newFov || this._axes.get().fov; + + var isValid = newPitchRange[1] - newPitchRange[0] >= fov; + + if (isValid) { + return newPitchRange; + } else { + return this.options.pitchRange || DEFAULT_PITCH_RANGE; + } + }; + + __proto._isCircular = function (range) { + return range[1] - range[0] < 360 ? [false, false] : [true, true]; + }; + /** + * Update yaw/pitch min/max by 5 factor + * + * 1. showPolePoint + * 2. fov + * 3. yawRange + * 4. pitchRange + * 5. aspectRatio + * + * If one of above is changed, call this function + */ + + + __proto._updateControlScale = function (changeEvt) { + var opt = this.options; + + var fov = this._axes.get().fov; + + var pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint); + + var yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio); // TODO: If not changed!? + + + var pos = this._axes.get(); + + var y = pos.yaw; + var p = pos.pitch; + copy$3(this._axes.axis.yaw.range, yRange); + copy$3(this._axes.axis.pitch.range, pRange); + this._axes.axis.yaw.circular = this._isCircular(yRange); + this._axes.axis.pitch.circular = this._isCircular(pRange); + /** + * update yaw/pitch by it's range. + */ + + if (y < yRange[0]) { + y = yRange[0]; + } else if (y > yRange[1]) { + y = yRange[1]; + } + + if (p < pRange[0]) { + p = pRange[0]; + } else if (p > pRange[1]) { + p = pRange[1]; + } + + if (changeEvt) { + changeEvt.set({ + yaw: y, + pitch: p + }); + } + + this._axes.setTo({ + yaw: y, + pitch: p + }, 0); + + return this; + }; + + __proto._updatePitchRange = function (pitchRange, fov, showPolePoint) { + if (this.options.gyroMode === GYRO_MODE.VR) { + // Circular pitch on VR + return CIRCULAR_PITCH_RANGE; + } + + var verticalAngle = pitchRange[1] - pitchRange[0]; + var halfFov = fov / 2; + var isPanorama = verticalAngle < 180; + + if (showPolePoint && !isPanorama) { + // Use full pinch range + return pitchRange.concat(); + } // Round value as movableCood do. + + + return [pitchRange[0] + halfFov, pitchRange[1] - halfFov]; + }; + + __proto._updateYawRange = function (yawRange, fov, aspectRatio) { + if (this.options.gyroMode === GYRO_MODE.VR) { + return DEFAULT_YAW_RANGE; + } + + var horizontalAngle = yawRange[1] - yawRange[0]; + /** + * Full 360 Mode + */ + + if (horizontalAngle >= 360) { + // Don't limit yaw range on Full 360 mode. + return yawRange.concat(); + } + /** + * Panorama mode + */ + // Ref : https://github.com/naver/egjs-view360/issues/290 + + + var halfHorizontalFov = util.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(toRadian(fov / 2)))); // Round value as movableCood do. + + return [yawRange[0] + halfHorizontalFov, yawRange[1] - halfHorizontalFov]; + }; // TODO: update param type after Axes event type inference update + + + __proto._triggerChange = function (evt) { + var pos = this._axes.get(); + + var opt = this.options; + var event = { + targetElement: opt.element, + isTrusted: evt.isTrusted, + yaw: pos.yaw, + pitch: pos.pitch, + fov: pos.fov, + quaternion: null + }; + + if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) { + event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw); + } + + this.trigger(new ComponentEvent$1("change", event)); + }; // TODO: makes constant to be logic + + + __proto._adjustAspectRatio = function (input) { + var inputRange = [0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670, 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19, 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26, 2.30, 2.60, 3.00, 5.00, 6.00]; + var outputRange = [0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710, 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15, 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72, 1.82, 1.92, 2.00, 2.24, 2.30]; + var rangeIdx = -1; + + for (var i = 0; i < inputRange.length - 1; i++) { + if (inputRange[i] <= input && inputRange[i + 1] >= input) { + rangeIdx = i; + break; + } + } + + if (rangeIdx === -1) { + if (inputRange[0] > input) { + return outputRange[0]; + } else { + // FIXME: this looks definitely wrong + return outputRange[outputRange[0].length - 1]; + } + } + + var inputA = inputRange[rangeIdx]; + var inputB = inputRange[rangeIdx + 1]; + var outputA = outputRange[rangeIdx]; + var outputB = outputRange[rangeIdx + 1]; + return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA)); + }; + + __proto._lerp = function (a, b, fraction) { + return a + fraction * (b - a); + }; + + __proto._resetOrientation = function () { + var opt = this.options; + + this._axes.setTo({ + yaw: opt.yaw, + pitch: opt.pitch, + fov: opt.fov + }, 0); + + return this; + }; + + YawPitchControl.VERSION = VERSION; // Expose DeviceOrientationControls sub module for test purpose + + YawPitchControl.CONTROL_MODE_VR = CONTROL_MODE_VR; + YawPitchControl.CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH; + YawPitchControl.TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL; + YawPitchControl.TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW; + YawPitchControl.TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH; + YawPitchControl.TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE; + return YawPitchControl; + }(Component); + + /* + Copyright (c) NAVER Corp. + name: @egjs/component + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-component + version: 2.2.2 + */ + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __values$2(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + function isUndefined$1(value) { + return typeof value === "undefined"; + } + /** + * A class used to manage events in a component + * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스 + * @alias eg.Component + */ + + + var Component$1 = + /*#__PURE__*/ + function () { + /** + * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"} + */ + function Component() { + /** + * @deprecated + * @private + */ + this.options = {}; + this._eventHandler = {}; + } + /** + * Triggers a custom event. + * @ko 커스텀 이벤트를 발생시킨다 + * @param {string} eventName The name of the custom event to be triggered 발생할 커스텀 이벤트의 이름 + * @param {object} customEvent Event data to be sent when triggering a custom event 커스텀 이벤트가 발생할 때 전달할 데이터 + * @param {any[]} restParam Additional parameters when triggering a custom event 커스텀 이벤트가 발생할 때 필요시 추가적으로 전달할 데이터 + * @return Indicates whether the event has occurred. If the stop() method is called by a custom event handler, it will return false and prevent the event from occurring. Ref 이벤트 발생 여부. 커스텀 이벤트 핸들러에서 stop() 메서드를 호출하면 'false'를 반환하고 이벤트 발생을 중단한다. 참고 + * @example + * ``` + * class Some extends eg.Component { + * some(){ + * if(this.trigger("beforeHi")){ // When event call to stop return false. + * this.trigger("hi");// fire hi event. + * } + * } + * } + * + * const some = new Some(); + * some.on("beforeHi", (e) => { + * if(condition){ + * e.stop(); // When event call to stop, `hi` event not call. + * } + * }); + * some.on("hi", (e) => { + * // `currentTarget` is component instance. + * console.log(some === e.currentTarget); // true + * }); + * // If you want to more know event design. You can see article. + * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F + * ``` + */ + + + var __proto = Component.prototype; + + __proto.trigger = function (eventName) { + var _this = this; + + var params = []; + + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + + var handlerList = this._eventHandler[eventName] || []; + var hasHandlerList = handlerList.length > 0; + + if (!hasHandlerList) { + return true; + } + + var customEvent = params[0] || {}; + var restParams = params.slice(1); // If detach method call in handler in first time then handler list calls. + + handlerList = handlerList.concat(); + var isCanceled = false; // This should be done like this to pass previous tests + + customEvent.eventType = eventName; + + customEvent.stop = function () { + isCanceled = true; + }; + + customEvent.currentTarget = this; + var arg = [customEvent]; + + if (restParams.length >= 1) { + arg = arg.concat(restParams); + } + + handlerList.forEach(function (handler) { + handler.apply(_this, arg); + }); + return !isCanceled; + }; + /** + * Executed event just one time. + * @ko 이벤트가 한번만 실행된다. + * @param {string} eventName The name of the event to be attached 등록할 이벤트의 이름 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ``` + * class Some extends eg.Component { + * hi() { + * alert("hi"); + * } + * thing() { + * this.once("hi", this.hi); + * } + * + * var some = new Some(); + * some.thing(); + * some.trigger("hi"); + * // fire alert("hi"); + * some.trigger("hi"); + * // Nothing happens + * ``` + */ + + + __proto.once = function (eventName, handlerToAttach) { + var _this = this; + + if (typeof eventName === "object" && isUndefined$1(handlerToAttach)) { + var eventHash = eventName; + + for (var key in eventHash) { + this.once(key, eventHash[key]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var listener_1 = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + handlerToAttach.apply(_this, args); + + _this.off(eventName, listener_1); + }; + + this.on(eventName, listener_1); + } + + return this; + }; + /** + * Checks whether an event has been attached to a component. + * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다. + * @param {string} eventName The name of the event to be attached 등록 여부를 확인할 이벤트의 이름 + * @return {boolean} Indicates whether the event is attached. 이벤트 등록 여부 + * @example + * ``` + * class Some extends eg.Component { + * some() { + * this.hasOn("hi");// check hi event. + * } + * } + * ``` + */ + + + __proto.hasOn = function (eventName) { + return !!this._eventHandler[eventName]; + }; + /** + * Attaches an event to a component. + * @ko 컴포넌트에 이벤트를 등록한다. + * @param {string} eventName The name of the event to be attached 등록할 이벤트의 이름 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ``` + * class Some extends eg.Component { + * hi() { + * console.log("hi"); + * } + * some() { + * this.on("hi",this.hi); //attach event + * } + * } + * ``` + */ + + + __proto.on = function (eventName, handlerToAttach) { + if (typeof eventName === "object" && isUndefined$1(handlerToAttach)) { + var eventHash = eventName; + + for (var name in eventHash) { + this.on(name, eventHash[name]); + } + + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var handlerList = this._eventHandler[eventName]; + + if (isUndefined$1(handlerList)) { + this._eventHandler[eventName] = []; + handlerList = this._eventHandler[eventName]; + } + + handlerList.push(handlerToAttach); + } + + return this; + }; + /** + * Detaches an event from the component. + * @ko 컴포넌트에 등록된 이벤트를 해제한다 + * @param {string} eventName The name of the event to be detached 해제할 이벤트의 이름 + * @param {function} handlerToDetach The handler function of the event to be detached 해제할 이벤트의 핸들러 함수 + * @return An instance of a component itself 컴포넌트 자신의 인스턴스 + * @example + * ``` + * class Some extends eg.Component { + * hi() { + * console.log("hi"); + * } + * some() { + * this.off("hi",this.hi); //detach event + * } + * } + * ``` + */ + + + __proto.off = function (eventName, handlerToDetach) { + var e_1, _a; // Detach all event handlers. + + + if (isUndefined$1(eventName)) { + this._eventHandler = {}; + return this; + } // Detach all handlers for eventname or detach event handlers by object. + + + if (isUndefined$1(handlerToDetach)) { + if (typeof eventName === "string") { + delete this._eventHandler[eventName]; + return this; + } else { + var eventHash = eventName; + + for (var name in eventHash) { + this.off(name, eventHash[name]); + } + + return this; + } + } // Detach single event handler + + + var handlerList = this._eventHandler[eventName]; + + if (handlerList) { + var idx = 0; + + try { + for (var handlerList_1 = __values$2(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) { + var handlerFunction = handlerList_1_1.value; + + if (handlerFunction === handlerToDetach) { + handlerList.splice(idx, 1); + break; + } + + idx++; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1); + } finally { + if (e_1) throw e_1.error; + } + } + } + + return this; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @example + * eg.Component.VERSION; // ex) 2.0.0 + * @memberof eg.Component + */ + + + Component.VERSION = "2.2.2"; + return Component; + }(); + + /* + Copyright (c) 2020-present NAVER Corp. + name: @egjs/imready + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-imready + version: 1.1.2 + */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics$2 = function (d, b) { + extendStatics$2 = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + }; + + return extendStatics$2(d, b); + }; + + function __extends$2(d, b) { + extendStatics$2(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign$2 = function () { + __assign$2 = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign$2.apply(this, arguments); + }; + function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + + for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; + + return r; + } + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + var isWindow = typeof window !== "undefined"; + var ua = isWindow ? window.navigator.userAgent : ""; + var SUPPORT_COMPUTEDSTYLE = isWindow ? !!("getComputedStyle" in window) : false; + var IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua); + var SUPPORT_ADDEVENTLISTENER = isWindow ? !!("addEventListener" in document) : false; + var WIDTH = "width"; + var HEIGHT = "height"; + + function getAttribute(el, name) { + return el.getAttribute(name) || ""; + } + function toArray$1(arr) { + return [].slice.call(arr); + } + function hasSizeAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return !!target.getAttribute(prefix + "width"); + } + function hasLoadingAttribute(target) { + return "loading" in target && target.getAttribute("loading") === "lazy"; + } + function hasSkipAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return !!target.getAttribute(prefix + "skip"); + } + function addEvent(element, type, handler) { + if (SUPPORT_ADDEVENTLISTENER) { + element.addEventListener(type, handler, false); + } else if (element.attachEvent) { + element.attachEvent("on" + type, handler); + } else { + element["on" + type] = handler; + } + } + function removeEvent(element, type, handler) { + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else if (element.detachEvent) { + element.detachEvent("on" + type, handler); + } else { + element["on" + type] = null; + } + } + function innerWidth(el) { + return getSize(el, "Width"); + } + function innerHeight(el) { + return getSize(el, "Height"); + } + function getStyles(el) { + return (SUPPORT_COMPUTEDSTYLE ? window.getComputedStyle(el) : el.currentStyle) || {}; + } + + function getSize(el, name) { + var size = el["client" + name] || el["offset" + name]; + return parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0; + } + + function getContentElements(element, tags, prefix) { + var skipElements = toArray$1(element.querySelectorAll(__spreadArrays(["[" + prefix + "skip] [" + prefix + "width]"], tags.map(function (tag) { + return ["[" + prefix + "skip] " + tag, tag + "[" + prefix + "skip]", "[" + prefix + "width] " + tag].join(", "); + })).join(", "))); + return toArray$1(element.querySelectorAll("[" + prefix + "width], " + tags.join(", "))).filter(function (el) { + return skipElements.indexOf(el) === -1; + }); + } + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + var elements = []; + function addAutoSizer(element, prefix) { + !elements.length && addEvent(window, "resize", resizeAllAutoSizers); + element.__PREFIX__ = prefix; + elements.push(element); + resize(element); + } + function removeAutoSizer(element, prefix) { + var index = elements.indexOf(element); + + if (index < 0) { + return; + } + + var fixed = getAttribute(element, prefix + "fixed"); + delete element.__PREFIX__; + element.style[fixed === HEIGHT ? WIDTH : HEIGHT] = ""; + elements.splice(index, 1); + !elements.length && removeEvent(window, "resize", resizeAllAutoSizers); + } + + function resize(element, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + var elementPrefix = element.__PREFIX__ || prefix; + var dataWidth = parseInt(getAttribute(element, "" + elementPrefix + WIDTH), 10) || 0; + var dataHeight = parseInt(getAttribute(element, "" + elementPrefix + HEIGHT), 10) || 0; + var fixed = getAttribute(element, elementPrefix + "fixed"); + + if (fixed === HEIGHT) { + var size = innerHeight(element) || dataHeight; + element.style[WIDTH] = dataWidth / dataHeight * size + "px"; + } else { + var size = innerWidth(element) || dataWidth; + element.style[HEIGHT] = dataHeight / dataWidth * size + "px"; + } + } + + function resizeAllAutoSizers() { + elements.forEach(function (element) { + resize(element); + }); + } + + var Loader = + /*#__PURE__*/ + function (_super) { + __extends$2(Loader, _super); + + function Loader(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.isReady = false; + _this.isPreReady = false; + _this.hasDataSize = false; + _this.hasLoading = false; + _this.isSkip = false; + + _this.onCheck = function (e) { + _this.clear(); + + if (e && e.type === "error") { + _this.onError(_this.element); + } // I'm pre-ready and ready! + + + var withPreReady = !_this.hasDataSize && !_this.hasLoading; + + _this.onReady(withPreReady); + }; + + _this.options = __assign$2({ + prefix: "data-" + }, options); + _this.element = element; + _this.hasDataSize = hasSizeAttribute(element, _this.options.prefix); + _this.hasLoading = hasLoadingAttribute(element); + _this.isSkip = hasSkipAttribute(_this.element); + return _this; + } + + var __proto = Loader.prototype; + + __proto.check = function () { + if (this.isSkip || !this.checkElement()) { + // I'm Ready + this.onAlreadyReady(true); + return false; + } + + if (this.hasDataSize) { + addAutoSizer(this.element, this.options.prefix); + } + + if (this.hasDataSize || this.hasLoading) { + // I'm Pre Ready + this.onAlreadyPreReady(); + } // Wati Pre Ready, Ready + + + return true; + }; + + __proto.addEvents = function () { + var _this = this; + + var element = this.element; + this.constructor.EVENTS.forEach(function (name) { + addEvent(element, name, _this.onCheck); + }); + }; + + __proto.clear = function () { + var _this = this; + + var element = this.element; + this.constructor.EVENTS.forEach(function (name) { + removeEvent(element, name, _this.onCheck); + }); + this.removeAutoSizer(); + }; + + __proto.destroy = function () { + this.clear(); + this.off(); + }; + + __proto.removeAutoSizer = function () { + if (this.hasDataSize) { + // I'm already ready. + var prefix = this.options.prefix; + removeAutoSizer(this.element, prefix); + } + }; + + __proto.onError = function (target) { + this.trigger("error", { + element: this.element, + target: target + }); + }; + + __proto.onPreReady = function () { + if (this.isPreReady) { + return; + } + + this.isPreReady = true; + this.trigger("preReady", { + element: this.element, + hasLoading: this.hasLoading, + isSkip: this.isSkip + }); + }; + + __proto.onReady = function (withPreReady) { + if (this.isReady) { + return; + } + + if (withPreReady) { + this.isPreReady = true; + } + + this.removeAutoSizer(); + this.isReady = true; + this.trigger("ready", { + element: this.element, + withPreReady: withPreReady, + hasLoading: this.hasLoading, + isSkip: this.isSkip + }); + }; + + __proto.onAlreadyError = function (target) { + var _this = this; + + setTimeout(function () { + _this.onError(target); + }); + }; + + __proto.onAlreadyPreReady = function () { + var _this = this; + + setTimeout(function () { + _this.onPreReady(); + }); + }; + + __proto.onAlreadyReady = function (withPreReady) { + var _this = this; + + setTimeout(function () { + _this.onReady(withPreReady); + }); + }; + + Loader.EVENTS = []; + return Loader; + }(Component$1); + + var ElementLoader = + /*#__PURE__*/ + function (_super) { + __extends$2(ElementLoader, _super); + + function ElementLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = ElementLoader.prototype; + + __proto.setHasLoading = function (hasLoading) { + this.hasLoading = hasLoading; + }; + + __proto.check = function () { + if (this.isSkip) { + // I'm Ready + this.onAlreadyReady(true); + return false; + } + + if (this.hasDataSize) { + addAutoSizer(this.element, this.options.prefix); + this.onAlreadyPreReady(); + } else { + // has not data size + this.trigger("requestChildren"); + } + + return true; + }; + + __proto.checkElement = function () { + return true; + }; + + __proto.destroy = function () { + this.clear(); + this.trigger("requestDestroy"); + this.off(); + }; + + __proto.onAlreadyPreReady = function () { + // has data size + _super.prototype.onAlreadyPreReady.call(this); + + this.trigger("reqeustReadyChildren"); + }; + + ElementLoader.EVENTS = []; + return ElementLoader; + }(Loader); + + /** + * @alias eg.ImReady + * @extends eg.Component + */ + + var ImReadyManager = + /*#__PURE__*/ + function (_super) { + __extends$2(ImReadyManager, _super); + /** + * @param - ImReady's options + */ + + + function ImReadyManager(options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.readyCount = 0; + _this.preReadyCount = 0; + _this.totalCount = 0; + _this.totalErrorCount = 0; + _this.isPreReadyOver = true; + _this.elementInfos = []; + _this.options = __assign$2({ + loaders: {}, + prefix: "data-" + }, options); + return _this; + } + /** + * Checks whether elements are in the ready state. + * @ko 엘리먼트가 준비 상태인지 체크한다. + * @elements - Elements to check ready status. 준비 상태를 체크할 엘리먼트들. + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReadyElement: e => { + * // 1, 3 + * // 2, 3 + * // 3, 3 + * console.log(e.preReadyCount, e.totalCount), + * }, + * }); + * ``` + */ + + + var __proto = ImReadyManager.prototype; + + __proto.check = function (elements) { + var _this = this; + + var prefix = this.options.prefix; + this.clear(); + this.elementInfos = toArray$1(elements).map(function (element, index) { + var loader = _this.getLoader(element, { + prefix: prefix + }); + + loader.check(); + loader.on("error", function (e) { + _this.onError(index, e.target); + }).on("preReady", function (e) { + var info = _this.elementInfos[index]; + info.hasLoading = e.hasLoading; + info.isSkip = e.isSkip; + + var isPreReady = _this.checkPreReady(index); + + _this.onPreReadyElement(index); + + isPreReady && _this.onPreReady(); + }).on("ready", function (_a) { + var withPreReady = _a.withPreReady, + hasLoading = _a.hasLoading, + isSkip = _a.isSkip; + var info = _this.elementInfos[index]; + info.hasLoading = hasLoading; + info.isSkip = isSkip; + + var isPreReady = withPreReady && _this.checkPreReady(index); + + var isReady = _this.checkReady(index); // Pre-ready and ready occur simultaneously + + + withPreReady && _this.onPreReadyElement(index); + + _this.onReadyElement(index); + + isPreReady && _this.onPreReady(); + isReady && _this.onReady(); + }); + return { + loader: loader, + element: element, + hasLoading: false, + hasError: false, + isPreReady: false, + isReady: false, + isSkip: false + }; + }); + var length = this.elementInfos.length; + this.totalCount = length; + + if (!length) { + setTimeout(function () { + _this.onPreReady(); + + _this.onReady(); + }); + } + + return this; + }; + /** + * Gets the total count of elements to be checked. + * @ko 체크하는 element의 총 개수를 가져온다. + */ + + + __proto.getTotalCount = function () { + return this.totalCount; + }; + /** + * Whether the elements are all pre-ready. (all sizes are known) + * @ko 엘리먼트들이 모두 사전 준비가 됐는지 (사이즈를 전부 알 수 있는지) 여부. + */ + + + __proto.isPreReady = function () { + return this.elementInfos.every(function (info) { + return info.isPreReady; + }); + }; + /** + * Whether the elements are all ready. + * @ko 엘리먼트들이 모두 준비가 됐는지 여부. + */ + + + __proto.isReady = function () { + return this.elementInfos.every(function (info) { + return info.isReady; + }); + }; + /** + * Whether an error has occurred in the elements in the current state. + * @ko 현재 상태에서 엘리먼트들이 에러가 발생했는지 여부. + */ + + + __proto.hasError = function () { + return this.totalErrorCount > 0; + }; + /** + * Clears events of elements being checked. + * @ko 체크 중인 엘리먼트들의 이벤트를 해제 한다. + */ + + + __proto.clear = function () { + this.isPreReadyOver = false; + this.totalCount = 0; + this.preReadyCount = 0; + this.readyCount = 0; + this.totalErrorCount = 0; + this.elementInfos.forEach(function (info) { + if (!info.isReady && info.loader) { + info.loader.destroy(); + } + }); + this.elementInfos = []; + }; + /** + * Destory all events. + * @ko 모든 이벤트를 해제 한다. + */ + + + __proto.destroy = function () { + this.clear(); + this.off(); + }; + + __proto.getLoader = function (element, options) { + var _this = this; + + var tagName = element.tagName.toLowerCase(); + var loaders = this.options.loaders; + var tags = Object.keys(loaders); + + if (loaders[tagName]) { + return new loaders[tagName](element, options); + } + + var loader = new ElementLoader(element, options); + var children = toArray$1(element.querySelectorAll(tags.join(", "))); + loader.setHasLoading(children.some(function (el) { + return hasLoadingAttribute(el); + })); + var withPreReady = false; + var childrenImReady = this.clone().on("error", function (e) { + loader.onError(e.target); + }).on("ready", function () { + loader.onReady(withPreReady); + }); + loader.on("requestChildren", function () { + // has not data size + var contentElements = getContentElements(element, tags, _this.options.prefix); + childrenImReady.check(contentElements).on("preReady", function (e) { + withPreReady = e.isReady; + + if (!withPreReady) { + loader.onPreReady(); + } + }); + }).on("reqeustReadyChildren", function () { + // has data size + // loader call preReady + // check only video, image elements + childrenImReady.check(children); + }).on("requestDestroy", function () { + childrenImReady.destroy(); + }); + return loader; + }; + + __proto.clone = function () { + return new ImReadyManager(__assign$2({}, this.options)); + }; + + __proto.checkPreReady = function (index) { + this.elementInfos[index].isPreReady = true; + ++this.preReadyCount; + + if (this.preReadyCount < this.totalCount) { + return false; + } + + return true; + }; + + __proto.checkReady = function (index) { + this.elementInfos[index].isReady = true; + ++this.readyCount; + + if (this.readyCount < this.totalCount) { + return false; + } + + return true; + }; + + __proto.onError = function (index, target) { + var info = this.elementInfos[index]; + info.hasError = true; + /** + * An event occurs if the image, video fails to load. + * @ko 이미지, 비디오가 로딩에 실패하면 이벤트가 발생한다. + * @event eg.ImReady#error + * @param {eg.ImReady.OnError} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {HTMLElement} [e.element] - The element with error images.오류난 이미지가 있는 엘리먼트 + * @param {number} [e.index] - The item's index with error images. 오류난 이미지가 있는 엘리먼트의 인덱스 + * @param {HTMLElement} [e.target] - Error image target in element 엘리먼트의 오류난 이미지 타겟 + * @param {number} [e.errorCount] - The number of elements with errors 에러가 있는 엘리먼트들의 개수 + * @param {number} [e.totalErrorCount] - The total number of targets with errors 에러가 있는 타겟들의 총 개수 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check([document.querySelector("div")]).on({ + * error: e => { + * //
...
, 0, + * console.log(e.element, e.index, e.target), + * }, + * }); + * ``` + */ + + this.trigger("error", { + element: info.element, + index: index, + target: target, + errorCount: this.getErrorCount(), + totalErrorCount: ++this.totalErrorCount + }); + }; + + __proto.onPreReadyElement = function (index) { + var info = this.elementInfos[index]; + /** + * An event occurs when the element is pre-ready (when the loading attribute is applied or the size is known) + * @ko 해당 엘리먼트가 사전 준비되었을 때(loading 속성이 적용되었거나 사이즈를 알 수 있을 때) 이벤트가 발생한다. + * @event eg.ImReady#preReadyElement + * @param {eg.ImReady.OnPreReadyElement} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {HTMLElement} [e.element] - The pre-ready element.사전 준비된 엘리먼트 + * @param {number} [e.index] - The index of the pre-ready element. 사전 준비된 엘리먼트의 인덱스 + * @param {number} [e.preReadyCount] - Number of elements pre-ready 사전 준비된 엘리먼트들의 개수 + * @param {number} [e.readyCount] - Number of elements ready 준비된 엘리먼트들의 개수 + * @param {number} [e.totalCount] - Total number of elements 엘리먼트들의 총 개수 + * @param {boolean} [e.isPreReady] - Whether all elements are pre-ready 모든 엘리먼트가 사전 준비가 끝났는지 여부 + * @param {boolean} [e.isReady] - Whether all elements are ready 모든 엘리먼트가 준비가 끝났는지 여부 + * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied loading 속성이 적용되었는지 여부 + * @param {boolean} [e.isSkip] - Whether the check is omitted due to skip attribute skip 속성으로 인하여 체크가 생략됐는지 여부 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReadyElement: e => { + * // 1, 3 + * // 2, 3 + * // 3, 3 + * console.log(e.preReadyCount, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger("preReadyElement", { + element: info.element, + index: index, + preReadyCount: this.preReadyCount, + readyCount: this.readyCount, + totalCount: this.totalCount, + isPreReady: this.isPreReady(), + isReady: this.isReady(), + hasLoading: info.hasLoading, + isSkip: info.isSkip + }); + }; + + __proto.onPreReady = function () { + this.isPreReadyOver = true; + /** + * An event occurs when all element are pre-ready (When all elements have the loading attribute applied or the size is known) + * @ko 모든 엘리먼트들이 사전 준비된 경우 (모든 엘리먼트들이 loading 속성이 적용되었거나 사이즈를 알 수 있는 경우) 이벤트가 발생한다. + * @event eg.ImReady#preReady + * @param {eg.ImReady.OnPreReady} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {number} [e.readyCount] - Number of elements ready 준비된 엘리먼트들의 개수 + * @param {number} [e.totalCount] - Total number of elements 엘리먼트들의 총 개수 + * @param {boolean} [e.isReady] - Whether all elements are ready 모든 엘리먼트가 준비가 끝났는지 여부 + * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied loading 속성이 적용되었는지 여부 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReady: e => { + * // 0, 3 + * console.log(e.readyCount, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger("preReady", { + readyCount: this.readyCount, + totalCount: this.totalCount, + isReady: this.isReady(), + hasLoading: this.hasLoading() + }); + }; + + __proto.onReadyElement = function (index) { + var info = this.elementInfos[index]; + /** + * An event occurs when the element is ready + * @ko 해당 엘리먼트가 준비가 되었을 때 이벤트가 발생한다. + * @event eg.ImReady#readyElement + * @param {eg.ImReady.OnReadyElement} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {HTMLElement} [e.element] - The ready element.준비된 엘리먼트 + * @param {number} [e.index] - The index of the ready element. 준비된 엘리먼트의 인덱스 + * @param {boolean} [e.hasError] - Whether there is an error in the element 해당 엘리먼트에 에러가 있는지 여부 + * @param {number} [e.errorCount] - The number of elements with errors 에러가 있는 엘리먼트들의 개수 + * @param {number} [e.totalErrorCount] - The total number of targets with errors 에러가 있는 타겟들의 총 개수 + * @param {number} [e.preReadyCount] - Number of elements pre-ready 사전 준비된 엘리먼트들의 개수 + * @param {number} [e.readyCount] - Number of elements ready 준비된 엘리먼트들의 개수 + * @param {number} [e.totalCount] - Total number of elements 엘리먼트들의 총 개수 + * @param {boolean} [e.isPreReady] - Whether all elements are pre-ready 모든 엘리먼트가 사전 준비가 끝났는지 여부 + * @param {boolean} [e.isReady] - Whether all elements are ready 모든 엘리먼트가 준비가 끝났는지 여부 + * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied loading 속성이 적용되었는지 여부 + * @param {boolean} [e.isPreReadyOver] - Whether pre-ready is over 사전 준비가 끝났는지 여부 + * @param {boolean} [e.isSkip] - Whether the check is omitted due to skip attribute skip 속성으로 인하여 체크가 생략됐는지 여부 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * readyElement: e => { + * // 1, 0, false, 3 + * // 2, 1, false, 3 + * // 3, 2, true, 3 + * console.log(e.readyCount, e.index, e.hasError, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger("readyElement", { + index: index, + element: info.element, + hasError: info.hasError, + errorCount: this.getErrorCount(), + totalErrorCount: this.totalErrorCount, + preReadyCount: this.preReadyCount, + readyCount: this.readyCount, + totalCount: this.totalCount, + isPreReady: this.isPreReady(), + isReady: this.isReady(), + hasLoading: info.hasLoading, + isPreReadyOver: this.isPreReadyOver, + isSkip: info.isSkip + }); + }; + + __proto.onReady = function () { + /** + * An event occurs when all element are ready + * @ko 모든 엘리먼트들이 준비된 경우 이벤트가 발생한다. + * @event eg.ImReady#ready + * @param {eg.ImReady.OnReady} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @param {number} [e.errorCount] - The number of elements with errors 에러가 있는 엘리먼트들의 개수 + * @param {number} [e.totalErrorCount] - The total number of targets with errors 에러가 있는 타겟들의 총 개수 + * @param {number} [e.totalCount] - Total number of elements 엘리먼트들의 총 개수 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReady: e => { + * // 0, 3 + * console.log(e.readyCount, e.totalCount), + * }, + * ready: e => { + * // 1, 3 + * console.log(e.errorCount, e.totalCount), + * }, + * }); + * ``` + */ + this.trigger("ready", { + errorCount: this.getErrorCount(), + totalErrorCount: this.totalErrorCount, + totalCount: this.totalCount + }); + }; + + __proto.getErrorCount = function () { + return this.elementInfos.filter(function (info) { + return info.hasError; + }).length; + }; + + __proto.hasLoading = function () { + return this.elementInfos.some(function (info) { + return info.hasLoading; + }); + }; + + return ImReadyManager; + }(Component$1); + + var ImageLoader = + /*#__PURE__*/ + function (_super) { + __extends$2(ImageLoader, _super); + + function ImageLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = ImageLoader.prototype; + + __proto.checkElement = function () { + var element = this.element; + var src = element.getAttribute("src"); + + if (element.complete && src) { + if (!element.naturalWidth) { + this.onAlreadyError(element); + } + + return false; + } + + this.addEvents(); + IS_IE && element.setAttribute("src", src); + return true; + }; + + ImageLoader.EVENTS = ["load", "error"]; + return ImageLoader; + }(Loader); + + var VideoLoader = + /*#__PURE__*/ + function (_super) { + __extends$2(VideoLoader, _super); + + function VideoLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = VideoLoader.prototype; + + __proto.checkElement = function () { + var element = this.element; // HAVE_NOTHING: 0, no information whether or not the audio/video is ready + // HAVE_METADATA: 1, HAVE_METADATA - metadata for the audio/video is ready + // HAVE_CURRENT_DATA: 2, data for the current playback position is available, but not enough data to play next frame/millisecond + // HAVE_FUTURE_DATA: 3, data for the current and at least the next frame is available + // HAVE_ENOUGH_DATA: 4, enough data available to start playing + + if (element.readyState >= 1) { + return false; + } + + if (element.error) { + this.onAlreadyError(element); + return false; + } + + this.addEvents(); + return true; + }; + + VideoLoader.EVENTS = ["loadedmetadata", "error"]; + return VideoLoader; + }(Loader); + + var ImReady = + /*#__PURE__*/ + function (_super) { + __extends$2(ImReady, _super); + + function ImReady(options) { + if (options === void 0) { + options = {}; + } + + return _super.call(this, __assign$2({ + loaders: { + img: ImageLoader, + video: VideoLoader + } + }, options)) || this; + } + + return ImReady; + }(ImReadyManager); + + /** + * Constant value for errors + * @ko 에러에 대한 상수 값 + * @namespace + * @name ERROR_TYPE + * @memberof eg.view360.PanoViewer + */ + + var ERROR_TYPE = { + /** + * Unsupported device + * @ko 미지원 기기 + * @name INVALID_DEVICE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 10 + */ + INVALID_DEVICE: 10, + + /** + * Webgl not support + * @ko WEBGL 미지원 + * @name NO_WEBGL + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 11 + */ + NO_WEBGL: 11, + + /** + * Failed to load image + * @ko 이미지 로드 실패 + * @name FAIL_IMAGE_LOAD + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 12 + */ + FAIL_IMAGE_LOAD: 12, + + /** + * Failed to bind texture + * @ko 텍스쳐 바인딩 실패 + * @name FAIL_BIND_TEXTURE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 13 + */ + FAIL_BIND_TEXTURE: 13, + + /** + * Only one resource(image or video) should be specified + * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함) + * @name INVALID_RESOURCE + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 14 + */ + INVALID_RESOURCE: 14, + + /** + * WebGL context lost occurred + * @ko WebGL context lost 발생 + * @name RENDERING_CONTEXT_LOST + * @memberof eg.view360.PanoViewer.ERROR_TYPE + * @constant + * @type {Number} + * @default 15 + */ + RENDERING_CONTEXT_LOST: 15 + }; + /** + * Constant value for events + * @ko 이벤트에 대한 상수 값 + * @namespace + * @name EVENTS + * @memberof eg.view360.PanoViewer + */ + + var PANOVIEWER_EVENTS = { + /** + * Events that is fired when PanoViewer is ready to show image and handle user interaction. + * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트 + * @name READY + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default ready + */ + READY: "ready", + + /** + * Events that is fired when direction or fov is changed. + * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트 + * @name VIEW_CHANGE + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default viewChange + */ + VIEW_CHANGE: "viewChange", + + /** + * Events that is fired when animation which is triggered by inertia is ended. + * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트 + * @name ANIMATION_END + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default animationEnd + */ + ANIMATION_END: "animationEnd", + + /** + * Events that is fired when error occurs + * @ko 에러 발생 시 발생하는 이벤트 + * @name ERROR + * @memberof eg.view360.PanoViewer.EVENTS + * @constant + * @type {String} + * @default error + */ + ERROR: "error" + }; + /** + * Constant value for projection type + * @ko 프로젝션 타입 대한 상수 값 + * @namespace + * @name PROJECTION_TYPE + * @memberof eg.view360.PanoViewer + */ + + var PROJECTION_TYPE = { + /** + * Constant value for equirectangular type. + * @ko equirectangular 에 대한 상수 값. + * @name EQUIRECTANGULAR + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default equirectangular + */ + EQUIRECTANGULAR: "equirectangular", + + /** + * Constant value for cubemap type. + * @ko cubemap 에 대한 상수 값. + * @name CUBEMAP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubemap + */ + CUBEMAP: "cubemap", + + /** + * Constant value for cubestrip type. + * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC. + * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다. + * @name CUBESTRIP + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default cubestrip + */ + CUBESTRIP: "cubestrip", + + /** + * Constant value for PANORAMA type. + * + * PANORAMA is a format for a panorma image which is taken from smartphone. + * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다. + * + * @name PANORAMA + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default panorama + */ + PANORAMA: "panorama", + + /** + * Constant value for EQUI_STEREOSCOPY type. + * + * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present. + * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다. + * + * @name STEREOSCOPIC_EQUI + * @memberof eg.view360.PanoViewer.PROJECTION_TYPE + * @constant + * @type {String} + * @default stereoequi + */ + STEREOSCOPIC_EQUI: "stereoequi" + }; + /** + * A constant value for the format of the stereoscopic equirectangular projection type. + * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값 + * @namespace + * @name STEREO_FORMAT + * @memberof eg.view360.PanoViewer + */ + + var STEREO_FORMAT = { + /** + * A constant value for format of top bottom stereoscopic 360 equirectangular projection. + * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name TOP_BOTTOM + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dv" + */ + TOP_BOTTOM: "3dv", + + /** + * A constant value for format of left right stereoscopic 360 equirectangular projection. + * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값. + * @name LEFT_RIGHT + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "3dh" + */ + LEFT_RIGHT: "3dh", + + /** + * A constant value specifying media is not in stereoscopic format. + * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값. + * @name NONE + * @memberof eg.view360.PanoViewer.STEREO_FORMAT + * @constant + * @type {String} + * @default "" + */ + NONE: "" + }; // eslint-disable-next-line @typescript-eslint/no-unused-vars + + var PANOVIEWER_OPTIONS = { + image: true, + video: true, + projectionType: true, + cubemapConfig: true, + stereoFormat: true, + width: true, + height: true, + yaw: true, + pitch: true, + fov: true, + showPolePoint: true, + useZoom: true, + useKeyboard: true, + gyroMode: true, + yawRange: true, + pitchRange: true, + fovRange: true, + touchDirection: true, + canvasClass: true + }; + var DEFAULT_CANVAS_CLASS = "view360-canvas"; + + var merge = function (target) { + var srcs = []; + + for (var _i = 1; _i < arguments.length; _i++) { + srcs[_i - 1] = arguments[_i]; + } + + srcs.forEach(function (source) { + Object.keys(source).forEach(function (key) { + var value = source[key]; + + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = __spread(target[key], value); + } else { + target[key] = value; + } + }); + }); + return target; + }; + var toImageElement = function (image) { + var images = image instanceof Array ? image : [image]; + var parsedImages = images.map(function (img) { + var imgEl = img; + + if (typeof img === "string") { + imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = img; + } + + return imgEl; + }); + return parsedImages.length === 1 ? parsedImages[0] : parsedImages; + }; + var toVideoElement = function (videoCandidate) { + if (videoCandidate instanceof HTMLVideoElement) { + return videoCandidate; + } else { + // url + var video_1 = document.createElement("video"); + video_1.setAttribute("crossorigin", "anonymous"); + video_1.setAttribute("webkit-playsinline", ""); + video_1.setAttribute("playsinline", ""); + + if (videoCandidate instanceof Array) { + videoCandidate.forEach(function (v) { + return appendSourceElement(video_1, v); + }); + } else { + appendSourceElement(video_1, videoCandidate); + } + + var sourceCount = video_1.querySelectorAll("source").length; + + if (sourceCount > 0) { + if (video_1.readyState < 1) { + video_1.load(); + } + } + + return video_1; + } + }; + /** + * + * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src} + */ + + var appendSourceElement = function (video, videoUrl) { + var videoSrc; + var videoType; + + if (typeof videoUrl === "object") { + videoSrc = videoUrl.src; + videoType = videoUrl.type; + } else if (typeof videoUrl === "string") { + videoSrc = videoUrl; + } + + if (!videoSrc) { + return false; + } + + var sourceElement = document.createElement("source"); + sourceElement.src = videoSrc; + + if (videoType) { + sourceElement.type = videoType; + } + + video.appendChild(sourceElement); + }; + + var WEBGL_ERROR_CODE = { + "0": "NO_ERROR", + "1280": "INVALID_ENUM", + "1281": "INVALID_VALUE", + "1282": "INVALID_OPERATION", + "1285": "OUT_OF_MEMORY", + "1286": "INVALID_FRAMEBUFFER_OPERATION", + "37442": "CONTEXT_LOST_WEBGL" + }; + var webglAvailability = null; // eslint-disable-next-line @typescript-eslint/naming-convention + + var WebGLUtils = + /*#__PURE__*/ + function () { + function WebGLUtils() {} + + WebGLUtils.createShader = function (gl, type, source) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + + if (success) { + return shader; + } // eslint-disable-next-line + + + console.error(gl.getShaderInfoLog(shader)); + return null; + }; + + WebGLUtils.createProgram = function (gl, vertexShader, fragmentShader) { + var program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + gl.deleteShader(vertexShader); + gl.deleteShader(fragmentShader); + var success = gl.getProgramParameter(program, gl.LINK_STATUS); + + if (success) { + return program; + } + + gl.deleteProgram(program); + return null; + }; + + WebGLUtils.initBuffer = function (gl, target + /* bind point */ + , data, itemSize, attr) { + var buffer = gl.createBuffer(); + gl.bindBuffer(target, buffer); + gl.bufferData(target, data, gl.STATIC_DRAW); + + if (buffer) { + buffer.itemSize = itemSize; + buffer.numItems = data.length / itemSize; + } + + if (attr !== undefined) { + gl.enableVertexAttribArray(attr); + gl.vertexAttribPointer(attr, buffer.itemSize, gl.FLOAT, false, 0, 0); + } + + return buffer; + }; + + WebGLUtils.getWebglContext = function (canvas, userContextAttributes) { + var e_1, _a; + + var webglIdentifiers = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + var context = null; + + var contextAttributes = __assign({ + preserveDrawingBuffer: false, + antialias: false + }, userContextAttributes); + + var onWebglcontextcreationerror = function (e) { + return e.statusMessage; + }; + + canvas.addEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + + try { + for (var webglIdentifiers_1 = __values(webglIdentifiers), webglIdentifiers_1_1 = webglIdentifiers_1.next(); !webglIdentifiers_1_1.done; webglIdentifiers_1_1 = webglIdentifiers_1.next()) { + var identifier = webglIdentifiers_1_1.value; + + try { + context = canvas.getContext(identifier, contextAttributes); + } catch (t) {} // eslint-disable-line no-empty + + + if (context) { + break; + } + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (webglIdentifiers_1_1 && !webglIdentifiers_1_1.done && (_a = webglIdentifiers_1.return)) _a.call(webglIdentifiers_1); + } finally { + if (e_1) throw e_1.error; + } + } + + canvas.removeEventListener("webglcontextcreationerror", onWebglcontextcreationerror); + return context; + }; + + WebGLUtils.createTexture = function (gl, textureTarget) { + var texture = gl.createTexture(); + gl.bindTexture(textureTarget, texture); + gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindTexture(textureTarget, null); + return texture; + }; + /** + * Returns the webgl availability of the current browser. + * @method WebGLUtils#isWebGLAvailable + * @retuen {Boolean} isWebGLAvailable + */ + + + WebGLUtils.isWebGLAvailable = function () { + if (webglAvailability === null) { + var canvas = document.createElement("canvas"); + var webglContext = WebGLUtils.getWebglContext(canvas); + webglAvailability = !!webglContext; // webglContext Resource forced collection + + if (webglContext) { + var loseContextExtension = webglContext.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + } + + return !!webglAvailability; + }; + /** + * Returns whether webgl is stable in the current browser. + * @method WebGLUtils#isStableWebGL + * @retuen {Boolean} isStableWebGL + */ + + + WebGLUtils.isStableWebGL = function () { + var agentInfo = agent(); + var isStableWebgl = true; + + if (agentInfo.os.name === "android") { + var version = parseFloat(agentInfo.os.version); + + if (version <= 4.3 && version >= 1) { + isStableWebgl = false; + } else if (version === 4.4) { + if (agentInfo.browser.name !== "chrome") { + isStableWebgl = false; + } + } + } + + return isStableWebgl; + }; + + WebGLUtils.getErrorNameFromWebGLErrorCode = function (code) { + if (!(code in WEBGL_ERROR_CODE)) { + return "UNKNOWN_ERROR"; + } + + return WEBGL_ERROR_CODE[code]; + }; + /** + * This function is wrapper for texImage2D to handle exceptions on texImage2D. + * Purpose is to prevent service from being stopped by script error. + */ + + + WebGLUtils.texImage2D = function (gl, target, pixels) { + try { + gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + } catch (error) { + /* eslint-disable no-console */ + console.error("WebGLUtils.texImage2D error:", error); + /* eslint-enable no-console */ + } + }; + + WebGLUtils.getMaxTextureSize = function (gl) { + // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test + return gl.getParameter(gl.MAX_TEXTURE_SIZE); + }; + + return WebGLUtils; + }(); + + var agentInfo = agent(); + var isIE11 = agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11; + var EVENTS = { + ERROR: "error" + }; + /** + * + * Extends Component for firing errors occurs internally. + */ + + var Renderer = + /*#__PURE__*/ + function (_super) { + __extends(Renderer, _super); + + function Renderer() { + var _this = _super.call(this) || this; + + _this._forceDimension = null; + _this._pixelCanvas = null; + _this._pixelContext = null; + return _this; + } + + var __proto = Renderer.prototype; + + __proto.render = function (_a) { + var gl = _a.gl, + shaderProgram = _a.shaderProgram, + indexBuffer = _a.indexBuffer, + mvMatrix = _a.mvMatrix, + pMatrix = _a.pMatrix; + gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); + gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); + + if (indexBuffer) { + gl.drawElements(gl.TRIANGLES, indexBuffer.numItems, gl.UNSIGNED_SHORT, 0); + } + }; // Define interface for Renderers + + /** + * Following MUST BE DEFINED on Child of Renderer + * + * DATA + * + * - getVertexPositionData + * - getIndexData + * - getTextureCoordData + * + * SOURCE + * + * - getVertexShaderSource + * - getFragmentShaderSource + * + * TEXTURE + * + * - bindTexture + */ + + + __proto.getDimension = function (pixelSource) { + var width = pixelSource.naturalWidth || pixelSource.videoWidth; + var height = pixelSource.naturalHeight || pixelSource.videoHeight; + return { + width: width, + height: height + }; + }; + /** + * Update data used by shader + */ + + + __proto.updateShaderData = function (param) { + /* + * Update following data in implementation layer. + * If the data is not changed, it does not need to implement this function. + * + * - _VERTEX_POSITION_DATA + * - _TEXTURE_COORD_DATA + * - _INDEX_DATA + */ + }; + /** + * + * @param {HTMLImageElement | HTMLVideoElement} image + * @param {Object = {width, height}} forceDimension Forced dimension to resize + */ + + + __proto._initPixelSource = function (image, forceDimension) { + if (forceDimension === void 0) { + forceDimension = null; + } + + var isIE11Video = isIE11 && image instanceof HTMLVideoElement; + + if (isIE11Video || forceDimension) { + var _a = forceDimension || this.getDimension(image), + width = _a.width, + height = _a.height; + + this._pixelCanvas = document.createElement("canvas"); + this._pixelCanvas.width = width; + this._pixelCanvas.height = height; + this._pixelContext = this._pixelCanvas.getContext("2d"); + } + + this._forceDimension = forceDimension; + }; + + __proto._getPixelSource = function (image) { + if (!this._pixelCanvas) { + return image; + } + /** + * IE11 && Video + * or + * Dimension is forced (Image is larger than texture size.) + */ + + + var contentDimension = this.getDimension(image); + var textureDimension = this._forceDimension || contentDimension; + + if (this._pixelCanvas.width !== textureDimension.width) { + this._pixelCanvas.width = textureDimension.width; + } + + if (this._pixelCanvas.height !== textureDimension.height) { + this._pixelCanvas.height = textureDimension.height; + } + + if (this._forceDimension) { + this._pixelContext.drawImage(image, 0, 0, contentDimension.width, contentDimension.height, 0, 0, textureDimension.width, textureDimension.height); + } else { + this._pixelContext.drawImage(image, 0, 0); + } + + return this._pixelCanvas; + }; + + __proto._extractTileConfig = function (imageConfig) { + var tileConfig = Array.isArray(imageConfig.tileConfig) ? imageConfig.tileConfig : Array.apply(void 0, __spread(Array(6))).map(function () { + return imageConfig.tileConfig; + }); + tileConfig = tileConfig.map(function (config) { + return __assign({ + flipHorizontal: false, + rotation: 0 + }, config); + }); + return tileConfig; + }; + + __proto._triggerError = function (error) { + /* eslint-disable no-console */ + console.error("Renderer Error:", error); + /* eslint-enable no-console */ + + this.trigger(new ComponentEvent$1(EVENTS.ERROR, { + message: typeof error === "string" ? error : error.message + })); + }; + + Renderer.EVENTS = EVENTS; + return Renderer; + }(Component); + + var CubeRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CubeRenderer, _super); + + function CubeRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeRenderer.prototype; + + CubeRenderer.extractOrder = function (imageConfig) { + return imageConfig.order || "RLUDBF"; + }; + + __proto.getVertexPositionData = function () { + CubeRenderer._VERTEX_POSITION_DATA = CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // top + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // bottom + 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + return CubeRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + if (CubeRenderer._INDEX_DATA) { + return CubeRenderer._INDEX_DATA; + } + + var indexData = []; + var vertexPositionData = this.getVertexPositionData(); + + for (var i = 0; i < vertexPositionData.length / 3; i += 4) { + indexData.push(i, i + 2, i + 1, i, i + 3, i + 2); + } + + CubeRenderer._INDEX_DATA = indexData; + return indexData; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; + var vertexOrder = "BFUDRL"; + var order = CubeRenderer.extractOrder(imageConfig); + var base = this.getVertexPositionData(); + + var tileConfig = this._extractTileConfig(imageConfig); + + var elemSize = 3; + var vertexPerTile = 4; + var trim = imageConfig.trim; + var texCoords = vertexOrder.split("").map(function (face) { + return tileConfig[order.indexOf(face)]; + }).map(function (config, i) { + var rotation = Math.floor(config.rotation / 90); + var ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2]; + + for (var r = 0; r < Math.abs(rotation); r++) { + if (config.flipHorizontal && rotation > 0 || !config.flipHorizontal && rotation < 0) { + ordermap.push(ordermap.shift()); + } else { + ordermap.unshift(ordermap.pop()); + } + } + + var elemPerTile = elemSize * vertexPerTile; + var tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile); + var tileTemp = []; + + for (var j = 0; j < vertexPerTile; j++) { + tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize); + } + + return tileTemp; + }).map(function (coord) { + return _this._shrinkCoord({ + image: image, + faceCoords: coord, + trim: trim + }); + }).reduce(function (acc, val) { + return __spread(acc, val.reduce(function (coords, coord) { + return __spread(coords, coord); + }, [])); + }, []); + return texCoords; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}"; + }; + + __proto.updateTexture = function (gl, image, imageConfig) { + var baseOrder = "RLUDBF"; + var order = CubeRenderer.extractOrder(imageConfig); + var orderMap = {}; + order.split("").forEach(function (v, i) { + orderMap[v] = i; + }); + + try { + if (image instanceof Array) { + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]); + } + } else { + var maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image); + + for (var surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) { + var tileIdx = orderMap[baseOrder[surfaceIdx]]; + var tile = this.extractTileFromImage(image, tileIdx, maxCubeMapTextureSize); + WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile); + } + } + } catch (e) { + this._triggerError(e); + } + }; + + __proto.bindTexture = function (gl, texture, image, imageConfig) { + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + this.updateTexture(gl, image, imageConfig); + }; + + __proto.getSourceTileSize = function (image) { + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var aspectRatio = width / height; + var inputTextureSize; + + if (aspectRatio === 1 / 6) { + inputTextureSize = width; + } else if (aspectRatio === 6) { + inputTextureSize = height; + } else if (aspectRatio === 2 / 3) { + inputTextureSize = width / 2; + } else { + inputTextureSize = width / 3; + } + + return inputTextureSize; + }; + + __proto.extractTileFromImage = function (image, tileIdx, outputTextureSize) { + var width = this.getDimension(image).width; + var inputTextureSize = this.getSourceTileSize(image); + var canvas = document.createElement("canvas"); + canvas.width = outputTextureSize; + canvas.height = outputTextureSize; + var context = canvas.getContext("2d"); + var tilePerRow = width / inputTextureSize; + var x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow); + var y = Math.floor(tileIdx / tilePerRow) * inputTextureSize; + context.drawImage(image, x, y, inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize); + return canvas; + }; + + __proto.getMaxCubeMapTextureSize = function (gl, image) { + var agentInfo = agent(); + var maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); + var imageWidth = this.getSourceTileSize(image); + + if (agentInfo.browser.name === "ie" && agentInfo.browser.majorVersion === 11) { + if (!util.isPowerOfTwo(imageWidth)) { + for (var i = 1; i < maxCubeMapTextureSize; i *= 2) { + if (i < imageWidth) { + continue; + } else { + imageWidth = i; + break; + } + } + } + } + + if (agentInfo.os.name === "ios") { + var majorVersion = agentInfo.os.majorVersion; // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다. + + if (majorVersion === 9) { + imageWidth = 1024; + } // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다. + + + if (majorVersion === 8) { + imageWidth = 512; + } + } // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수 + + + return Math.min(maxCubeMapTextureSize, imageWidth); + }; + + __proto._shrinkCoord = function (coordData) { + var image = coordData.image, + faceCoords = coordData.faceCoords, + trim = coordData.trim; + var inputTextureSize = Array.isArray(image) ? this.getDimension(image[0]).width : this.getSourceTileSize(image); // Shrink by "trim" px + + var SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize); + var axisMultipliers = [0, 1, 2].map(function (axisIndex) { + var axisDir = util.sign(faceCoords[0][axisIndex]); + var notSameDir = faceCoords.some(function (coord) { + return util.sign(coord[axisIndex]) !== axisDir; + }); + return notSameDir; + }).map(function (notSameDir) { + return notSameDir ? SHRINK_MULTIPLIER : 1; + }); + return faceCoords.map(function (coords) { + return coords.map(function (coord, axisIndex) { + return coord * axisMultipliers[axisIndex]; + }); + }); + }; + + CubeRenderer._VERTEX_POSITION_DATA = null; + CubeRenderer._INDEX_DATA = null; + return CubeRenderer; + }(Renderer); + + var CubeStripRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CubeStripRenderer, _super); + + function CubeStripRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CubeStripRenderer.prototype; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"; + }; + + __proto.getVertexPositionData = function () { + if (!this._vertices) { + this._vertices = [// back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + } + + return this._vertices; + }; + + __proto.getIndexData = function () { + var _this = this; // TODO: 한번만 계산하도록 수정하기 + + + var indices = function () { + var indexData = []; + + for (var i = 0; i < _this._vertices.length / 3; i += 4) { + indexData.push(i, i + 1, i + 2, i, i + 2, i + 3); + } + + return indexData; + }(); + + return indices; + }; + + __proto.getTextureCoordData = function (_a) { + var _this = this; + + var image = _a.image, + imageConfig = _a.imageConfig; // TODO: make it cols, rows as config. + + var cols = 3; + var rows = 2; + var textureSize = this.getDimension(image); + var trim = imageConfig.trim; + var order = imageConfig.order || "RLUDFB"; + var coords = []; // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다. + + for (var r = rows - 1; r >= 0; r--) { + for (var c = 0; c < cols; c++) { + var coord = [c / cols, r / rows, (c + 1) / cols, r / rows, (c + 1) / cols, (r + 1) / rows, c / cols, (r + 1) / rows]; + coords.push(coord); + } + } + + var tileConfigs = this._extractTileConfig(imageConfig); // Transform Coord By Flip & Rotation + + + coords = coords // shrink coord to avoid pixel bleeding + .map(function (coord) { + return _this._shrinkCoord(coord, textureSize, trim); + }).map(function (coord, i) { + return _this._transformCoord(coord, tileConfigs[i]); + }); // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치 + + return "BFUDRL".split("").map(function (face) { + return order.indexOf(face); + }).map(function (index) { + return coords[index]; + }).reduce(function (acc, val) { + return acc.concat(val); + }, []); + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto._transformCoord = function (coord, tileConfig) { + var newCoord = coord.slice(); + + if (tileConfig.flipHorizontal) { + newCoord = this._flipHorizontalCoord(newCoord); + } + + if (tileConfig.rotation) { + newCoord = this._rotateCoord(newCoord, tileConfig.rotation); + } + + return newCoord; + }; + + __proto._shrinkCoord = function (coord, textureSize, trim) { + var width = textureSize.width, + height = textureSize.height; // Shrink by "trim" px + + var SHRINK_Y = trim * (1 / height); + var SHRINK_X = trim * (1 / width); + return [coord[0] + SHRINK_X, coord[1] + SHRINK_Y, coord[2] - SHRINK_X, coord[3] + SHRINK_Y, coord[4] - SHRINK_X, coord[5] - SHRINK_Y, coord[6] + SHRINK_X, coord[7] - SHRINK_Y]; + }; + + __proto._rotateCoord = function (coord, rotationAngle) { + var SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord. + + var shiftCount = Math.floor(rotationAngle / 90) % 4; + + if (shiftCount === 0) { + return coord; + } + + var moved; + var rotatedCoord = []; + + if (shiftCount > 0) { + moved = coord.splice(0, shiftCount * SIZE); + rotatedCoord = coord.concat(moved); + } else { + moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE); + rotatedCoord = moved.concat(coord); + } + + return rotatedCoord; + }; + + __proto._flipHorizontalCoord = function (coord) { + return [coord[2], coord[3], coord[0], coord[1], coord[6], coord[7], coord[4], coord[5]]; + }; + + return CubeStripRenderer; + }(Renderer); + + var latitudeBands = 60; + var longitudeBands = 60; + var radius = 2; + var ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + var textureCoordData = []; + var vertexPositionData = []; + var indexData = []; + var latIdx; + var lngIdx; + + for (latIdx = 0; latIdx <= latitudeBands; latIdx++) { + var theta = (latIdx / latitudeBands - 0.5) * Math.PI; + var sinTheta = Math.sin(theta); + var cosTheta = Math.cos(theta); + + for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) { + var phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + var sinPhi = Math.sin(phi); + var cosPhi = Math.cos(phi); + var x = cosPhi * cosTheta; + var y = sinTheta; + var z = sinPhi * cosTheta; + var u = lngIdx / longitudeBands; + var v = latIdx / latitudeBands; + textureCoordData.push(u, v); + vertexPositionData.push(radius * x, radius * y, radius * z); + + if (lngIdx !== longitudeBands && latIdx !== latitudeBands) { + var a = latIdx * (longitudeBands + 1) + lngIdx; + var b = a + longitudeBands + 1; + indexData.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + + var SphereRenderer = + /*#__PURE__*/ + function (_super) { + __extends(SphereRenderer, _super); + + function SphereRenderer(format) { + var _this = _super.call(this) || this; + + _this._stereoFormat = format; + return _this; + } + + var __proto = SphereRenderer.prototype; + + __proto.render = function (ctx) { + var gl = ctx.gl, + shaderProgram = ctx.shaderProgram; + var leftEyeScaleOffset; + var rightEyeScaleOffset; + + switch (this._stereoFormat) { + case STEREO_FORMAT.TOP_BOTTOM: + leftEyeScaleOffset = [1, 0.5, 0, 0]; + rightEyeScaleOffset = [1, 0.5, 0, 0.5]; + break; + + case STEREO_FORMAT.LEFT_RIGHT: + leftEyeScaleOffset = [0.5, 1, 0, 0]; + rightEyeScaleOffset = [0.5, 1, 0.5, 0]; + break; + + default: + leftEyeScaleOffset = [1, 1, 0, 0]; + rightEyeScaleOffset = [1, 1, 0, 0]; + } + + var uTexScaleOffset = gl.getUniformLocation(shaderProgram, "uTexScaleOffset"); + gl.uniform4fv(uTexScaleOffset, __spread(leftEyeScaleOffset, rightEyeScaleOffset)); + + _super.prototype.render.call(this, ctx); + }; + + __proto.getVertexPositionData = function () { + return SphereRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return SphereRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return SphereRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device limit(" + maxSize + "))"); + + return; + } // Pixel Source for IE11 & Video + + + this._initPixelSource(image); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + SphereRenderer._VERTEX_POSITION_DATA = vertexPositionData; + SphereRenderer._TEXTURE_COORD_DATA = textureCoordData; + SphereRenderer._INDEX_DATA = indexData; + return SphereRenderer; + }(Renderer); + + var MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6; + var longitudeBands$1 = 60; + var textureCoordData$1 = []; + var vertexPositionData$1 = []; + var indexData$1 = []; + + var CylinderRenderer = + /*#__PURE__*/ + function (_super) { + __extends(CylinderRenderer, _super); + + function CylinderRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = CylinderRenderer.prototype; + + __proto.getVertexPositionData = function () { + return CylinderRenderer._VERTEX_POSITION_DATA; + }; + + __proto.getIndexData = function () { + return CylinderRenderer._INDEX_DATA; + }; + + __proto.getTextureCoordData = function () { + return CylinderRenderer._TEXTURE_COORD_DATA; + }; + + __proto.getVertexShaderSource = function () { + return "\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}"; + }; + + __proto.getFragmentShaderSource = function () { + return "\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}"; + }; + + __proto.updateTexture = function (gl, image) { + WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image)); + }; + + __proto.bindTexture = function (gl, texture, image) { + // Make sure image isn't too big + var _a = this.getDimension(image), + width = _a.width, + height = _a.height; + + var size = Math.max(width, height); + var maxSize = WebGLUtils.getMaxTextureSize(gl); + var resizeDimension; + + if (size > maxSize) { + this._triggerError("Image width(" + width + ") exceeds device texture limit(" + maxSize + "))"); // Request resizing texture. + + /** + * TODO: Is it need to apply on another projection type? + */ + + + resizeDimension = width > height ? { + width: maxSize, + height: maxSize * height / width + } : { + width: maxSize * width / height, + height: maxSize + }; + } // Pixel Source for IE11 & Video or resizing needed + + + this._initPixelSource(image, resizeDimension); + + gl.activeTexture(gl.TEXTURE0); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.bindTexture(gl.TEXTURE_2D, texture); + this.updateTexture(gl, image); + }; + + __proto.updateShaderData = function (_a) { + var _b = _a.imageAspectRatio, + imageAspectRatio = _b === void 0 ? MIN_ASPECT_RATIO_FOR_FULL_PANORAMA : _b; + var lngIdx; + var cylinderMaxRadian; + var halfCylinderY; + var rotated; + var aspectRatio; // Exception case: orientation is rotated. + + if (imageAspectRatio < 1) { + /** + * If rotated is true, we assume that image is rotated counter clockwise. + * TODO: If there's other rotation, it is need to implement by each rotation. + */ + rotated = true; + aspectRatio = 1 / imageAspectRatio; + } else { + rotated = false; + aspectRatio = imageAspectRatio; + } + + if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) { + var fov = 360 / aspectRatio; + cylinderMaxRadian = 2 * Math.PI; // 360 deg + + halfCylinderY = Math.tan(toRadian(fov / 2)); + } else { + cylinderMaxRadian = aspectRatio; + halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1. + } // initialize shader data before update + + + textureCoordData$1.length = 0; + vertexPositionData$1.length = 0; + indexData$1.length = 0; + var CYLIDER_Y = [-halfCylinderY, halfCylinderY]; + var startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360) + // console.log("cylinderMaxRadian:", glMatrix.toDegree(cylinderMaxRadian), "CYLIDER_Y", CYLIDER_Y, "start angle", glMatrix.toDegree(startAngleForCenterAlign)); + + for (var yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength + /* bottom & top */ + ; yIdx++) { + for (lngIdx = 0; lngIdx <= longitudeBands$1; lngIdx++) { + var angle = startAngleForCenterAlign + lngIdx / longitudeBands$1 * cylinderMaxRadian; + var x = Math.cos(angle); + var y = CYLIDER_Y[yIdx]; + var z = Math.sin(angle); + var u = void 0; + var v = void 0; + + if (rotated) { + // Rotated 90 degree (counter clock wise) + u = 1 - yIdx; // yLength - yIdx; + + v = lngIdx / longitudeBands$1; + } else { + // // Normal case (Not rotated) + u = lngIdx / longitudeBands$1; + v = yIdx; + } + + textureCoordData$1.push(u, v); + vertexPositionData$1.push(x, y, z); + + if (yIdx === 0 && lngIdx < longitudeBands$1) { + var a = lngIdx; + var b = a + longitudeBands$1 + 1; + indexData$1.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + }; + + CylinderRenderer._VERTEX_POSITION_DATA = vertexPositionData$1; + CylinderRenderer._TEXTURE_COORD_DATA = textureCoordData$1; + CylinderRenderer._INDEX_DATA = indexData$1; + return CylinderRenderer; + }(Renderer); + + var VR_DISPLAY_PRESENT_CHANGE = "vrdisplaypresentchange"; + var DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1]; + var DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1]; + var EYES = { + LEFT: "left", + RIGHT: "right" + }; + + var VRManager = + /*#__PURE__*/ + function () { + function VRManager() { + var _this = this; + + this.destroy = function () { + var vrDisplay = _this._vrDisplay; + + _this.removeEndCallback(_this.destroy); + + if (vrDisplay && vrDisplay.isPresenting) { + void vrDisplay.exitPresent(); + } + + _this._clear(); + }; + + this._frameData = new window.VRFrameData(); + + this._clear(); + } + + var __proto = VRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._vrDisplay; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function () { + return Boolean(this._vrDisplay); + }; + + __proto.beforeRender = function (gl) { + // Render to the default backbuffer + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + }; + + __proto.afterRender = function () { + this._vrDisplay.submitFrame(); + }; + + __proto.getEyeParams = function (gl) { + var display = this._vrDisplay; + var halfWidth = gl.drawingBufferWidth * 0.5; + var height = gl.drawingBufferHeight; + var frameData = this._frameData; + display.getFrameData(frameData); + var leftMVMatrix = frameData.leftViewMatrix; + var rightMVMatrix = frameData.rightViewMatrix; + rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset); + rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset); + return [{ + viewport: [0, 0, halfWidth, height], + mvMatrix: leftMVMatrix, + pMatrix: frameData.leftProjectionMatrix + }, { + viewport: [halfWidth, 0, halfWidth, height], + mvMatrix: rightMVMatrix, + pMatrix: frameData.rightProjectionMatrix + }]; + }; + + __proto.isPresenting = function () { + return Boolean(this._vrDisplay && this._vrDisplay.isPresenting); + }; + + __proto.addEndCallback = function (callback) { + window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.removeEndCallback = function (callback) { + window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback); + }; + + __proto.requestPresent = function (canvas) { + var _this = this; + + return navigator.getVRDisplays().then(function (displays) { + var vrDisplay = displays.length && displays[0]; + + if (!vrDisplay) { + return Promise$1.reject(new Error("No displays available.")); + } + + if (!vrDisplay.capabilities.canPresent) { + return Promise$1.reject(new Error("Display lacking capability to present.")); + } + + return vrDisplay.requestPresent([{ + source: canvas + }]).then(function () { + var leftEye = vrDisplay.getEyeParameters(EYES.LEFT); + var rightEye = vrDisplay.getEyeParameters(EYES.RIGHT); + canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2; + canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight); + + _this._setDisplay(vrDisplay); + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setDisplay = function (vrDisplay) { + this._vrDisplay = vrDisplay; + var layers = vrDisplay.getLayers(); + + if (layers.length) { + var layer = layers[0]; + this._leftBounds = layer.leftBounds; + this._rightBounds = layer.rightBounds; + } + + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._vrDisplay = null; + this._leftBounds = DEFAULT_LEFT_BOUNDS; + this._rightBounds = DEFAULT_RIGHT_BOUNDS; + this._yawOffset = 0; + }; + + return VRManager; + }(); + + var XR_REFERENCE_SPACE = "local"; + + var XRManager = + /*#__PURE__*/ + function () { + function XRManager(options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + this.destroy = function () { + var xrSession = _this._xrSession; + + _this.removeEndCallback(_this.destroy); + + if (xrSession) { + // Capture to avoid errors + xrSession.end().then(function () { + return void 0; + }, function () { + return void 0; + }); + } + + _this._clear(); + }; + + this._clear(); + + this._options = options; + } + + var __proto = XRManager.prototype; + Object.defineProperty(__proto, "context", { + get: function () { + return this._xrSession; + }, + enumerable: false, + configurable: true + }); + + __proto.canRender = function (frame) { + var pose = frame.getViewerPose(this._xrRefSpace); + return Boolean(pose); + }; + + __proto.beforeRender = function (gl, frame) { + var session = frame.session; + var baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + }; // eslint-disable-next-line @typescript-eslint/no-empty-function + + + __proto.afterRender = function () {}; + + __proto.getEyeParams = function (gl, frame) { + var _this = this; + + var session = frame.session; + var pose = frame.getViewerPose(this._xrRefSpace); + + if (!pose) { + // Can't render + return null; + } + + var glLayer = session.renderState.baseLayer; + return pose.views.map(function (view) { + var viewport = glLayer.getViewport(view); + var mvMatrix = view.transform.inverse.matrix; + + if (IS_SAFARI_ON_DESKTOP) { + rotateX(mvMatrix, mvMatrix, toRadian(180)); + } + + rotateY(mvMatrix, mvMatrix, _this._yawOffset); + return { + viewport: [viewport.x, viewport.y, viewport.width, viewport.height], + mvMatrix: mvMatrix, + pMatrix: view.projectionMatrix + }; + }); + }; + + __proto.isPresenting = function () { + return this._presenting; + }; + + __proto.addEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.addEventListener("end", callback); + }; + + __proto.removeEndCallback = function (callback) { + var _a; + + (_a = this._xrSession) === null || _a === void 0 ? void 0 : _a.removeEventListener("end", callback); + }; + + __proto.requestPresent = function (canvas, gl) { + return __awaiter(this, void 0, void 0, function () { + var options, attributes; + + var _this = this; + + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + options = merge({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + attributes = gl.getContextAttributes(); + if (!(attributes && attributes.xrCompatible !== true)) return [3 + /*break*/ + , 2]; + return [4 + /*yield*/ + , gl.makeXRCompatible()]; + + case 1: + _a.sent(); + + _a.label = 2; + + case 2: + return [2 + /*return*/ + , navigator.xr.requestSession("immersive-vr", options).then(function (session) { + var xrLayer = new window.XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + return session.requestReferenceSpace(XR_REFERENCE_SPACE).then(function (refSpace) { + _this._setSession(session, xrLayer, refSpace); + }); + })]; + } + }); + }); + }; + + __proto.setYawOffset = function (offset) { + this._yawOffset = offset; + }; + + __proto._setSession = function (session, xrLayer, refSpace) { + this._xrSession = session; + this._xrLayer = xrLayer; + this._xrRefSpace = refSpace; + this._presenting = true; + this.addEndCallback(this.destroy); + }; + + __proto._clear = function () { + this._xrSession = null; + this._xrLayer = null; + this._xrRefSpace = null; + this._presenting = false; + this._yawOffset = 0; + this._options = {}; + }; + + return XRManager; + }(); + + var WebGLAnimator = + /*#__PURE__*/ + function () { + function WebGLAnimator() { + var _this = this; + /** + * There can be more than 1 argument when we use XRSession's raf + */ + + + this._onLoop = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + _this._callback.apply(_this, __spread(args)); + + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + }; + /** + * MacOS X Safari Bug Fix + * This code guarantees that rendering should be occurred. + * + * In MacOS X(10.14.2), Safari (12.0.2) + * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term + * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms) + * So browser cannot render the frame and may be freezing. + */ + + + this._onLoopNextTick = function () { + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + var before = performance.now(); + + _this._callback.apply(_this, __spread(args)); + + var diff = performance.now() - before; + + if (_this._rafTimer >= 0) { + clearTimeout(_this._rafTimer); + _this._rafTimer = -1; + } + /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */ + + + if (diff < 16) { + _this._rafId = _this._context.requestAnimationFrame(_this._onLoop); + } else { + /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */ + _this._rafTimer = window.setTimeout(_this._onLoop, 0); + } + }; + + this._callback = null; + this._context = window; + this._rafId = -1; + this._rafTimer = -1; + } + + var __proto = WebGLAnimator.prototype; + + __proto.setCallback = function (callback) { + this._callback = callback; + }; + + __proto.setContext = function (context) { + this._context = context; + }; + + __proto.start = function () { + var context = this._context; + var callback = this._callback; // No context / callback set + + if (!context || !callback) return; // Animation already started + + if (this._rafId >= 0 || this._rafTimer >= 0) return; + + if (IS_SAFARI_ON_DESKTOP) { + this._rafId = context.requestAnimationFrame(this._onLoopNextTick); + } else { + this._rafId = context.requestAnimationFrame(this._onLoop); + } + }; + + __proto.stop = function () { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + + this._rafId = -1; + this._rafTimer = -1; + }; + + return WebGLAnimator; + }(); + + var ImageType = PROJECTION_TYPE; // eslint-disable-next-line @typescript-eslint/naming-convention + + var DEVICE_PIXEL_RATIO = devicePixelRatio || 1; // DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다. + + if (DEVICE_PIXEL_RATIO > 2) { + DEVICE_PIXEL_RATIO = 2; + } // define custom events name + + /** + * TODO: how to manage events/errortype with PanoViewer + * + * I think renderer events should be seperated from viewer events although it has same name. + */ + + + var EVENTS$1 = { + BIND_TEXTURE: "bindTexture", + IMAGE_LOADED: "imageLoaded", + ERROR: "error", + RENDERING_CONTEXT_LOST: "renderingContextLost", + RENDERING_CONTEXT_RESTORE: "renderingContextRestore" + }; + var ERROR_TYPE$1 = { + INVALID_DEVICE: 10, + NO_WEBGL: 11, + FAIL_IMAGE_LOAD: 12, + RENDERER_ERROR: 13 + }; + + var PanoImageRenderer = + /*#__PURE__*/ + function (_super) { + __extends(PanoImageRenderer, _super); + + function PanoImageRenderer(image, width, height, isVideo, container, canvasClass, sphericalConfig, renderingContextAttributes) { + var _this = // Super constructor + _super.call(this) || this; + + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + + _this.exitVR = function () { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; + if (!vr) return; + vr.removeEndCallback(_this.exitVR); + vr.destroy(); + _this._vr = null; // Restore canvas & context on iOS + + if (IS_IOS) { + _this._restoreStyle(); + } + + _this.updateViewportDimensions(_this.width, _this.height); + + _this._updateViewport(); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + _this._bindBuffers(); + + _this._shouldForceDraw = true; + animator.stop(); + animator.setContext(window); + animator.setCallback(_this._render.bind(_this)); + animator.start(); + }; + + _this._renderStereo = function (time, frame) { + var e_1, _a; + + var vr = _this._vr; + var gl = _this.context; + var eyeParams = vr.getEyeParams(gl, frame); + if (!eyeParams) return; + vr.beforeRender(gl, frame); + + try { + // Render both eyes + for (var _b = __values([0, 1]), _c = _b.next(); !_c.done; _c = _b.next()) { + var eyeIndex = _c.value; + var eyeParam = eyeParams[eyeIndex]; + _this.mvMatrix = eyeParam.mvMatrix; + _this.pMatrix = eyeParam.pMatrix; + gl.viewport.apply(gl, __spread(eyeParam.viewport)); + gl.uniform1f(_this.shaderProgram.uEye, eyeIndex); + + _this._bindBuffers(); + + _this._draw(); + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + + vr.afterRender(); + }; + + _this._onFirstVRFrame = function (time, frame) { + var vr = _this._vr; + var gl = _this.context; + var animator = _this._animator; // If rendering is not ready, wait for next frame + + if (!vr.canRender(frame)) return; + var minusZDir = fromValues(0, 0, -1); + var eyeParam = vr.getEyeParams(gl, frame)[0]; // Extract only rotation + + var mvMatrix = fromMat4(create(), eyeParam.mvMatrix); + var pMatrix = fromMat4(create(), eyeParam.pMatrix); + var mvInv = invert(create(), mvMatrix); + var pInv = invert(create(), pMatrix); + var viewDir = transformMat3(create$2(), minusZDir, pInv); + transformMat3(viewDir, viewDir, mvInv); + var yawOffset = util.yawOffsetBetween(viewDir, fromValues(0, 0, 1)); + + if (yawOffset === 0) { + // If the yawOffset is exactly 0, then device sensor is not ready + // So read it again until it has any value in it + return; + } + + vr.setYawOffset(yawOffset); + animator.setCallback(_this._renderStereo); + }; + + _this.sphericalConfig = sphericalConfig; + _this.fieldOfView = sphericalConfig.fieldOfView; + _this.width = width; + _this.height = height; + _this._lastQuaternion = null; + _this._lastYaw = null; + _this._lastPitch = null; + _this._lastFieldOfView = null; + _this.pMatrix = create$1(); + _this.mvMatrix = create$1(); // initialzie pMatrix + + perspective(_this.pMatrix, toRadian(_this.fieldOfView), width / height, 0.1, 100); + _this.textureCoordBuffer = null; + _this.vertexBuffer = null; + _this.indexBuffer = null; + _this.canvas = _this._initCanvas(container, canvasClass, width, height); + + _this._setDefaultCanvasStyle(); + + _this._wrapper = null; // canvas wrapper + + _this._wrapperOrigStyle = null; + _this._renderingContextAttributes = renderingContextAttributes; + _this._image = null; + _this._imageConfig = null; + _this._imageIsReady = false; + _this._shouldForceDraw = false; + _this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still. + + _this._onContentLoad = _this._onContentLoad.bind(_this); + _this._onContentError = _this._onContentError.bind(_this); + _this._animator = new WebGLAnimator(); // VR/XR manager + + _this._vr = null; + + if (image) { + _this.setImage({ + image: image, + imageType: sphericalConfig.imageType, + isVideo: isVideo, + cubemapConfig: sphericalConfig.cubemapConfig + }); + } + + return _this; + } // FIXME: Please refactor me to have more loose connection to yawpitchcontrol + + + var __proto = PanoImageRenderer.prototype; + + __proto.setYawPitchControl = function (yawPitchControl) { + this._yawPitchControl = yawPitchControl; + }; + + __proto.getContent = function () { + return this._image; + }; + + __proto.setImage = function (_a) { + var image = _a.image, + imageType = _a.imageType, + _b = _a.isVideo, + isVideo = _b === void 0 ? false : _b, + cubemapConfig = _a.cubemapConfig; + this._imageIsReady = false; + this._isVideo = isVideo; + this._imageConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only */ + order: imageType === ImageType.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, cubemapConfig); + + this._setImageType(imageType); + + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._contentLoader = new ImReady().on("ready", this._onContentLoad).on("error", this._onContentError); + + if (isVideo) { + this._image = toVideoElement(image); + + this._contentLoader.check([this._image]); + + this._keepUpdate = true; + } else { + this._image = toImageElement(image); + + this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]); + + this._keepUpdate = false; + } + }; + + __proto.isImageLoaded = function () { + return !!this._image && this._imageIsReady && (!this._isVideo || this._image.readyState >= 2 + /* HAVE_CURRENT_DATA */ + ); + }; + + __proto.bindTexture = function () { + var _this = this; + + return new Promise$1(function (res, rej) { + var contentLoader = _this._contentLoader; + + if (!_this._image) { + return rej("Image is not defined"); + } + + if (!contentLoader) { + return rej("ImageLoader is not initialized"); + } + + if (contentLoader.isReady()) { + _this._bindTexture(); + + res(); + } else { + contentLoader.check(Array.isArray(_this._image) ? _this._image : [_this._image]); + contentLoader.once("ready", function (e) { + if (e.errorCount > 0) { + rej("Failed to load images."); + } else { + _this._bindTexture(); + + res(); + } + }); + } + }); + }; // 부모 엘리먼트에 canvas 를 붙임 + + + __proto.attachTo = function (parentElement) { + if (!this._hasExternalCanvas) { + this.detach(); + parentElement.appendChild(this.canvas); + } + + this._wrapper = parentElement; + }; + + __proto.forceContextLoss = function () { + if (this.hasRenderingContext()) { + var loseContextExtension = this.context.getExtension("WEBGL_lose_context"); + + if (loseContextExtension) { + loseContextExtension.loseContext(); + } + } + }; // 부모 엘리먼트에서 canvas 를 제거 + + + __proto.detach = function () { + if (!this._hasExternalCanvas && this.canvas.parentElement) { + this.canvas.parentElement.removeChild(this.canvas); + } + }; + + __proto.destroy = function () { + if (this._contentLoader) { + this._contentLoader.destroy(); + } + + this._animator.stop(); + + this.detach(); + this.forceContextLoss(); + this.off(); + this.canvas.removeEventListener("webglcontextlost", this._onWebglcontextlost); + this.canvas.removeEventListener("webglcontextrestored", this._onWebglcontextrestored); + }; + + __proto.hasRenderingContext = function () { + var ctx = this.context; + + if (!ctx || ctx.isContextLost() || !ctx.getProgramParameter(this.shaderProgram, ctx.LINK_STATUS)) { + return false; + } + + return true; + }; + + __proto.updateFieldOfView = function (fieldOfView) { + this.fieldOfView = fieldOfView; + + this._updateViewport(); + }; + + __proto.updateViewportDimensions = function (width, height) { + var viewPortChanged = false; + this.width = width; + this.height = height; + var w = width * DEVICE_PIXEL_RATIO; + var h = height * DEVICE_PIXEL_RATIO; + + if (w !== this.canvas.width) { + this.canvas.width = w; + viewPortChanged = true; + } + + if (h !== this.canvas.height) { + this.canvas.height = h; + viewPortChanged = true; + } + + if (!viewPortChanged) { + return; + } + + this._updateViewport(); + + this._shouldForceDraw = true; + }; + + __proto.keepUpdate = function (doUpdate) { + if (doUpdate && this.isImageLoaded() === false) { + // Force to draw a frame after image is loaded on render() + this._shouldForceDraw = true; + } + + this._keepUpdate = doUpdate; + }; + + __proto.startRender = function () { + this._animator.setCallback(this._render.bind(this)); + + this._animator.start(); + }; + + __proto.stopRender = function () { + this._animator.stop(); + }; + + __proto.renderWithQuaternion = function (quaternion, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastQuaternion && exactEquals$1(this._lastQuaternion, quaternion) && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // updatefieldOfView only if fieldOfView is changed. + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + this.mvMatrix = fromQuat(create$1(), quaternion); + + this._draw(); + + this._lastQuaternion = clone$1(quaternion); + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + + __proto.renderWithYawPitch = function (yaw, pitch, fieldOfView) { + if (!this.isImageLoaded()) { + return; + } + + if (this._keepUpdate === false && this._lastYaw !== null && this._lastYaw === yaw && this._lastPitch !== null && this._lastPitch === pitch && this.fieldOfView && this.fieldOfView === fieldOfView && this._shouldForceDraw === false) { + return; + } // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출 + + + if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) { + this.updateFieldOfView(fieldOfView); + } + + identity(this.mvMatrix); + rotateX(this.mvMatrix, this.mvMatrix, -toRadian(pitch)); + rotateY(this.mvMatrix, this.mvMatrix, -toRadian(yaw)); + + this._draw(); + + this._lastYaw = yaw; + this._lastPitch = pitch; + + if (this._shouldForceDraw) { + this._shouldForceDraw = false; + } + }; + /** + * Returns projection renderer by each type + */ + + + __proto.getProjectionRenderer = function () { + return this._renderer; + }; + /** + * @return Promise + */ + + + __proto.enterVR = function (options) { + var vr = this._vr; + + if (!WEBXR_SUPPORTED && !navigator.getVRDisplays) { + return Promise$1.reject("VR is not available on this browser."); + } + + if (vr && vr.isPresenting()) { + return Promise$1.resolve("VR already enabled."); + } + + return this._requestPresent(options); + }; + + __proto._setImageType = function (imageType) { + var _this = this; + + if (!imageType || this._imageType === imageType) { + return; + } + + this._imageType = imageType; + this._isCubeMap = imageType === ImageType.CUBEMAP; + + if (this._renderer) { + this._renderer.off(); + } + + switch (imageType) { + case ImageType.CUBEMAP: + this._renderer = new CubeRenderer(); + break; + + case ImageType.CUBESTRIP: + this._renderer = new CubeStripRenderer(); + break; + + case ImageType.PANORAMA: + this._renderer = new CylinderRenderer(); + break; + + case ImageType.STEREOSCOPIC_EQUI: + this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat); + break; + + default: + this._renderer = new SphereRenderer(STEREO_FORMAT.NONE); + break; + } + + this._renderer.on(Renderer.EVENTS.ERROR, function (e) { + _this.trigger(new ComponentEvent$1(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.RENDERER_ERROR, + message: e.message + })); + }); + + this._initWebGL(); + }; + + __proto._initCanvas = function (container, canvasClass, width, height) { + var canvasInContainer = container.querySelector("." + canvasClass); + + var canvas = canvasInContainer || this._createCanvas(canvasClass); + + this._hasExternalCanvas = !!canvasInContainer; + canvas.width = width; + canvas.height = height; + this._onWebglcontextlost = this._onWebglcontextlost.bind(this); + this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this); + canvas.addEventListener("webglcontextlost", this._onWebglcontextlost); + canvas.addEventListener("webglcontextrestored", this._onWebglcontextrestored); + return canvas; + }; + + __proto._createCanvas = function (className) { + var canvas = document.createElement("canvas"); + canvas.className = className; + return canvas; + }; + + __proto._setDefaultCanvasStyle = function () { + var canvas = this.canvas; + canvas.style.bottom = "0"; + canvas.style.left = "0"; + canvas.style.right = "0"; + canvas.style.top = "0"; + canvas.style.margin = "auto"; + canvas.style.maxHeight = "100%"; + canvas.style.maxWidth = "100%"; + canvas.style.outline = "none"; + canvas.style.position = "absolute"; + }; + + __proto._onContentError = function () { + this._imageIsReady = false; + this._image = null; + this.trigger(new ComponentEvent$1(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.FAIL_IMAGE_LOAD, + message: "failed to load image" + })); + return false; + }; + + __proto._triggerContentLoad = function () { + this.trigger(new ComponentEvent$1(EVENTS$1.IMAGE_LOADED, { + content: this._image, + isVideo: this._isVideo, + projectionType: this._imageType + })); + }; + + __proto._onContentLoad = function (e) { + if (e.errorCount > 0) return; + this._imageIsReady = true; + + this._triggerContentLoad(); + }; + + __proto._initShaderProgram = function () { + var gl = this.context; + + if (this.shaderProgram) { + gl.deleteProgram(this.shaderProgram); + this.shaderProgram = null; + } + + var renderer = this._renderer; + var vsSource = renderer.getVertexShaderSource(); + var fsSource = renderer.getFragmentShaderSource(); + var vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource); + var fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource); + var shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader); + + if (!shaderProgram) { + throw new Error("Failed to initialize shaders: " + WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())); + } + + gl.useProgram(shaderProgram); + shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); + shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); + shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); + shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler"); + shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord"); + shaderProgram.uEye = gl.getUniformLocation(shaderProgram, "uEye"); + gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); + gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute); // clear buffer + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); // Use TEXTURE0 + + gl.uniform1i(shaderProgram.samplerUniform, 0); + this.shaderProgram = shaderProgram; + }; + + __proto._onWebglcontextlost = function (e) { + e.preventDefault(); + this.trigger(new ComponentEvent$1(EVENTS$1.RENDERING_CONTEXT_LOST)); + }; + + __proto._onWebglcontextrestored = function () { + this._initWebGL(); + + this.trigger(new ComponentEvent$1(EVENTS$1.RENDERING_CONTEXT_RESTORE)); + }; + + __proto._updateViewport = function () { + perspective(this.pMatrix, toRadian(this.fieldOfView), this.canvas.width / this.canvas.height, 0.1, 100); + this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight); + }; + + __proto._initWebGL = function () { + var gl; // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed. + + try { + this._initRenderingContext(); + + gl = this.context; + this.updateViewportDimensions(this.width, this.height); + + this._initShaderProgram(); + } catch (e) { + this.trigger(new ComponentEvent$1(EVENTS$1.ERROR, { + type: ERROR_TYPE$1.NO_WEBGL, + message: "no webgl support" + })); + this.destroy(); + console.error(e); // eslint-disable-line no-console + + return; + } // 캔버스를 투명으로 채운다. + + + gl.clearColor(0, 0, 0, 0); + var textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D; + + if (this.texture) { + gl.deleteTexture(this.texture); + } + + this.texture = WebGLUtils.createTexture(gl, textureTarget); + + if (this._imageType === ImageType.CUBESTRIP) { + // TODO: Apply following options on other projection type. + gl.enable(gl.CULL_FACE); // gl.enable(gl.DEPTH_TEST); + } + }; + + __proto._initRenderingContext = function () { + if (this.hasRenderingContext()) { + return; + } + + if (!window.WebGLRenderingContext) { + throw new Error("WebGLRenderingContext not available."); + } + + this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes); + + if (!this.context) { + throw new Error("Failed to acquire 3D rendering context"); + } + }; + + __proto._initBuffers = function () { + var image = this._image; + + var vertexPositionData = this._renderer.getVertexPositionData(); + + var indexData = this._renderer.getIndexData(); + + var textureCoordData = this._renderer.getTextureCoordData({ + image: image, + imageConfig: this._imageConfig + }); + + var gl = this.context; + this.vertexBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3, this.shaderProgram.vertexPositionAttribute); + this.indexBuffer = WebGLUtils.initBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1); + this.textureCoordBuffer = WebGLUtils.initBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2, this.shaderProgram.textureCoordAttribute); + + this._bindBuffers(); + }; + + __proto._bindTexture = function () { + // Detect if it is EAC Format while CUBESTRIP mode. + // We assume it is EAC if image is not 3/2 ratio. + if (this._imageType === ImageType.CUBESTRIP) { + var _a = this._renderer.getDimension(this._image), + width = _a.width, + height = _a.height; + + var isEAC = width && height && width / height !== 1.5 ? 1 : 0; + this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram, "uIsEAC"), isEAC); + } else if (this._imageType === ImageType.PANORAMA) { + var _b = this._renderer.getDimension(this._image), + width = _b.width, + height = _b.height; + + var imageAspectRatio = width && height && width / height; + + this._renderer.updateShaderData({ + imageAspectRatio: imageAspectRatio + }); + } // initialize shader buffers after image is loaded.(by updateShaderData) + // because buffer may be differ by image size.(eg. CylinderRenderer) + + + this._initBuffers(); + + this._renderer.bindTexture(this.context, this.texture, this._image, this._imageConfig); + + this._shouldForceDraw = true; + this.trigger(new ComponentEvent$1(EVENTS$1.BIND_TEXTURE)); + }; + + __proto._updateTexture = function () { + this._renderer.updateTexture(this.context, this._image, this._imageConfig); + }; + + __proto._render = function () { + var yawPitchControl = this._yawPitchControl; + var fov = yawPitchControl.getFov(); + + if (yawPitchControl.shouldRenderWithQuaternion()) { + var quaternion = yawPitchControl.getQuaternion(); + this.renderWithQuaternion(quaternion, fov); + } else { + var yawPitch = yawPitchControl.getYawPitch(); + this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov); + } + }; + + __proto._bindBuffers = function () { + var gl = this.context; + var program = this.shaderProgram; + var vertexBuffer = this.vertexBuffer; + var textureCoordBuffer = this.textureCoordBuffer; + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.enableVertexAttribArray(program.vertexPositionAttribute); + gl.vertexAttribPointer(program.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer); + gl.enableVertexAttribArray(program.textureCoordAttribute); + gl.vertexAttribPointer(program.textureCoordAttribute, textureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); + }; + + __proto._draw = function () { + if (this._isVideo && this._keepUpdate) { + this._updateTexture(); + } + + this._renderer.render({ + gl: this.context, + shaderProgram: this.shaderProgram, + indexBuffer: this.indexBuffer, + mvMatrix: this.mvMatrix, + pMatrix: this.pMatrix + }); + }; + + __proto._requestPresent = function (options) { + var _this = this; + + var gl = this.context; + var canvas = this.canvas; + var animator = this._animator; + this._vr = WEBXR_SUPPORTED ? new XRManager(options) : new VRManager(); + var vr = this._vr; + animator.stop(); + return new Promise$1(function (resolve, reject) { + vr.requestPresent(canvas, gl).then(function () { + vr.addEndCallback(_this.exitVR); + animator.setContext(vr.context); + animator.setCallback(_this._onFirstVRFrame); + + if (IS_IOS) { + _this._setWrapperFullscreen(); + } + + _this._shouldForceDraw = true; + animator.start(); + resolve("success"); + }).catch(function (e) { + vr.destroy(); + _this._vr = null; + animator.start(); + reject(e); + }); + }); + }; + + __proto._setWrapperFullscreen = function () { + var wrapper = this._wrapper; + if (!wrapper) return; + this._wrapperOrigStyle = wrapper.getAttribute("style"); + var wrapperStyle = wrapper.style; + wrapperStyle.width = "100vw"; + wrapperStyle.height = "100vh"; + wrapperStyle.position = "fixed"; + wrapperStyle.left = "0"; + wrapperStyle.top = "0"; + wrapperStyle.zIndex = "9999"; + }; + + __proto._restoreStyle = function () { + var wrapper = this._wrapper; + var canvas = this.canvas; + if (!wrapper) return; + + if (this._wrapperOrigStyle) { + wrapper.setAttribute("style", this._wrapperOrigStyle); + } else { + wrapper.removeAttribute("style"); + } + + this._wrapperOrigStyle = null; // Restore canvas style + + canvas.removeAttribute("style"); + + this._setDefaultCanvasStyle(); + }; + + PanoImageRenderer.EVENTS = EVENTS$1; + PanoImageRenderer.ERROR_TYPE = ERROR_TYPE$1; + return PanoImageRenderer; + }(Component); + + /** + * @memberof eg.view360 + * @extends eg.Component + * PanoViewer + */ + + var PanoViewer = + /*#__PURE__*/ + function (_super) { + __extends(PanoViewer, _super); + /** + * @classdesc 360 media viewer + * @ko 360 미디어 뷰어 + * + * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트 + * @param options + * + * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정) + * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
+ * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다. + * @param {Object} [options.cubemapConfig.order = "RLUDBF"(ProjectionType === CUBEMAP) | "RLUDFB" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서 + * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다. + * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다. + * @param {String} [options.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
+ * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위) + * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위) + * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위) + * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위) + * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위) + * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다 + * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다. + * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키 + * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR")
{@link eg.view360.PanoViewer.GYRO_MODE}
+ * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위 + * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위 + * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위 + * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
+ * @param {String} [options.canvasClass="view360-canvas"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * + * @example + * ``` + * // PanoViewer Creation + * // create PanoViewer with option + * var PanoViewer = eg.view360.PanoViewer; + * // Area where the image will be displayed(HTMLElement) + * var container = document.getElementById("myPanoViewer"); + * + * var panoViewer = new PanoViewer(container, { + * // If projectionType is not specified, the default is "equirectangular". + * // Specifies an image of the "equirectangular" type. + * image: "/path/to/image/image.jpg" + * }); + * ``` + * + * @example + * ``` + * // Cubemap Config Setting Example + * // For support Youtube EAC projection, You should set cubemapConfig as follows. + * cubemapConfig: { + * order: "LFRDBU", + * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}] + * } + * ``` + */ + + + function PanoViewer(container, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; // Raises the error event if webgl is not supported. + + + if (!WebGLUtils.isWebGLAvailable()) { + setTimeout(function () { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.NO_WEBGL, + message: "no webgl support" + })); + }, 0); + return _this; + } + + if (!WebGLUtils.isStableWebGL()) { + setTimeout(function () { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_DEVICE, + message: "blacklisted browser" + })); + }, 0); + return _this; + } + + if (!!options.image && !!options.video) { + setTimeout(function () { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.INVALID_RESOURCE, + message: "Specifying multi resouces(both image and video) is not valid." + })); + }, 0); + return _this; + } // Check XR support at not when imported, but when created. + // This is intended to make polyfills easier to use. + + + checkXRSupport(); + _this._container = container; + _this._image = options.image || options.video; + _this._isVideo = !!options.video; + _this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + _this._cubemapConfig = __assign({ + /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/ + order: _this._projectionType === PROJECTION_TYPE.CUBEMAP ? "RLUDBF" : "RLUDFB", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, options.cubemapConfig); + _this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; // If the width and height are not provided, will use the size of the container. + + _this._width = options.width || parseInt(window.getComputedStyle(container).width, 10); + _this._height = options.height || parseInt(window.getComputedStyle(container).height, 10); + /** + * Cache the direction for the performance in renderLoop + * + * This value should be updated by "change" event of YawPitchControl. + */ + + _this._yaw = options.yaw || 0; + _this._pitch = options.pitch || 0; + _this._fov = options.fov || 65; + _this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH; + _this._quaternion = null; + _this._aspectRatio = _this._height !== 0 ? _this._width / _this._height : 1; + _this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS; + var fovRange = options.fovRange || [30, 110]; + var touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ? options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL; + + var yawPitchConfig = __assign(__assign({}, options), { + element: container, + yaw: _this._yaw, + pitch: _this._pitch, + fov: _this._fov, + gyroMode: _this._gyroMode, + fovRange: fovRange, + aspectRatio: _this._aspectRatio, + touchDirection: touchDirection + }); + + _this._isReady = false; + + _this._initYawPitchControl(yawPitchConfig); + + _this._initRenderer(_this._yaw, _this._pitch, _this._fov, _this._projectionType, _this._cubemapConfig); + + return _this; + } + /** + * Check whether the current environment can execute PanoViewer + * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다. + * @return PanoViewer executable PanoViewer 실행가능 여부 + */ + + + var __proto = PanoViewer.prototype; + + PanoViewer.isSupported = function () { + return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL(); + }; + /** + * Check whether the current environment supports the WebGL + * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다. + * @return WebGL support WebGL 지원여부 + */ + + + PanoViewer.isWebGLAvailable = function () { + return WebGLUtils.isWebGLAvailable(); + }; + /** + * Check whether the current environment supports the gyro sensor. + * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다. + * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수 + */ + + + PanoViewer.isGyroSensorAvailable = function (callback) { + if (!DeviceMotionEvent && callback) { + callback(false); + return; + } + + var onDeviceMotionChange; + + var checkGyro = function () { + return new Promise$1(function (res) { + onDeviceMotionChange = function (deviceMotion) { + var isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null); + res(isGyroSensorAvailable); + }; + + window.addEventListener("devicemotion", onDeviceMotionChange); + }); + }; + + var timeout = function () { + return new Promise$1(function (res) { + setTimeout(function () { + return res(false); + }, 1000); + }); + }; + + Promise$1.race([checkGyro(), timeout()]).then(function (isGyroSensorAvailable) { + window.removeEventListener("devicemotion", onDeviceMotionChange); + + if (callback) { + callback(isGyroSensorAvailable); + } + + PanoViewer.isGyroSensorAvailable = function (fb) { + if (fb) { + fb(isGyroSensorAvailable); + } + + return isGyroSensorAvailable; + }; + }); + }; + + PanoViewer._isValidTouchDirection = function (direction) { + return direction === PanoViewer.TOUCH_DIRECTION.NONE || direction === PanoViewer.TOUCH_DIRECTION.YAW || direction === PanoViewer.TOUCH_DIRECTION.PITCH || direction === PanoViewer.TOUCH_DIRECTION.ALL; + }; + /** + * Get the video element that the viewer is currently playing. You can use this for playback. + * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다. + * @return HTMLVideoElementHTMLVideoElement + * @example + * ``` + * var videoTag = panoViewer.getVideo(); + * videoTag.play(); // play the video! + * ``` + */ + + + __proto.getVideo = function () { + if (!this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the video information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정) + * @param {object} param + * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}("equirectangular")] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setVideo("/path/to/video/video.mp4", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR + * }); + * ``` + */ + + + __proto.setVideo = function (video, param) { + if (param === void 0) { + param = {}; + } + + if (video) { + this.setImage(video, { + projectionType: param.projectionType, + isVideo: true, + cubemapConfig: param.cubemapConfig, + stereoFormat: param.stereoFormat + }); + } + + return this; + }; + /** + * Get the image information that the viewer is currently using. + * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다. + * @return Image Object이미지 객체 + * @example + * var imageObj = panoViewer.getImage(); + */ + + + __proto.getImage = function () { + if (this._isVideo) { + return null; + } + + return this._photoSphereRenderer.getContent(); + }; + /** + * Set the image information to be used by the viewer. + * @ko 뷰어가 사용할 이미지 정보를 설정합니다. + * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.) + * @param {object} param Additional information이미지 추가 정보 + * @param {string} [param.projectionType="equirectangular"] Projection Type프로젝션 타입 + * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃 + * @param {string} [param.stereoFormat="3dv"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조. + * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부 + * + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setImage("/path/to/image/image.png", { + * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP + * }); + * ``` + */ + + + __proto.setImage = function (image, param) { + if (param === void 0) { + param = {}; + } + + var cubemapConfig = __assign({ + order: "RLUDBF", + tileConfig: { + flipHorizontal: false, + rotation: 0 + }, + trim: 0 + }, param.cubemapConfig); + + var stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM; + var isVideo = !!param.isVideo; + + if (this._image && this._isVideo !== isVideo) { + /* eslint-disable no-console */ + console.warn("PanoViewer is not currently supporting content type changes. (Image <--> Video)"); + /* eslint-enable no-console */ + + return this; + } + + if (image) { + this._deactivate(); + + this._image = image; + this._isVideo = isVideo; + this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR; + this._cubemapConfig = cubemapConfig; + this._stereoFormat = stereoFormat; + + this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig); + } + + return this; + }; + /** + * Set whether the renderer always updates the texture and renders. + * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다. + * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.keepUpdate = function (doUpdate) { + this._photoSphereRenderer.keepUpdate(doUpdate); + + return this; + }; + /** + * Get the current projection type (equirectangular/cube) + * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다. + * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE} + */ + + + __proto.getProjectionType = function () { + return this._projectionType; + }; + /** + * Activate the device's motion sensor, and return the Promise whether the sensor is enabled + * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element. + * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다. + * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다. + */ + + + __proto.enableSensor = function () { + return new Promise$1(function (resolve, reject) { + if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === "function") { + DeviceMotionEvent.requestPermission().then(function (permissionState) { + if (permissionState === "granted") { + resolve(); + } else { + reject(new Error("permission denied")); + } + }).catch(function (e) { + // This can happen when this method wasn't triggered by user interaction + reject(e); + }); + } else { + resolve(); + } + }); + }; + /** + * Disable the device's motion sensor. + * @ko 디바이스의 모션 센서를 비활성화합니다. + * @deprecated + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.disableSensor = function () { + return this; + }; + /** + * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred). + * This method must be used in the context of user interaction, like onclick callback on the button element. + * It can be rejected when an enabling device sensor fails or image/video is still loading("ready" event not triggered). + * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다) + * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다. + * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우("ready"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다. + * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요. + * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error) + */ + + + __proto.enterVR = function (options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + if (!this._isReady) { + return Promise$1.reject(new Error("PanoViewer is not ready to show image.")); + } + + return new Promise$1(function (resolve, reject) { + _this.enableSensor().then(function () { + return _this._photoSphereRenderer.enterVR(options); + }).then(function (res) { + return resolve(res); + }).catch(function (e) { + return reject(e); + }); + }); + }; + /** + * Exit VR stereo rendering mode. + * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.exitVR = function () { + this._photoSphereRenderer.exitVR(); + + return this; + }; + /** + * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}. + * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다. + * @param useZoom + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseZoom = function (useZoom) { + if (typeof useZoom === "boolean") { + this._yawPitchControl.option("useZoom", useZoom); + } + + return this; + }; + /** + * When true, enables the keyboard move key control: awsd, arrow keys + * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키) + * @param useKeyboard + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setUseKeyboard = function (useKeyboard) { + this._yawPitchControl.option("useKeyboard", useKeyboard); + + return this; + }; + /** + * Enables control through device motion. ("none", "yawPitch", "VR") + * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. ("none", "yawPitch", "VR") + * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE} + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * panoViewer.setGyroMode("yawPitch"); + * //equivalent + * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH); + * ``` + */ + + + __proto.setGyroMode = function (gyroMode) { + this._yawPitchControl.option("gyroMode", gyroMode); + + return this; + }; + /** + * Set the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 설정합니다. + * @param range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setFovRange([50, 90]); + */ + + + __proto.setFovRange = function (range) { + this._yawPitchControl.option("fovRange", range); + + return this; + }; + /** + * Get the range of controllable FOV values + * @ko 제어 가능한 FOV 구간을 반환합니다. + * @return FOV range + * @example + * var range = panoViewer.getFovRange(); // [50, 90] + */ + + + __proto.getFovRange = function () { + return this._yawPitchControl.option("fovRange"); + }; + /** + * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size. + * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다. + * @param {object} [size] + * @param {number} [size.width=width of the container] + * @param {number} [size.height=height of the container] + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.updateViewportDimensions = function (size) { + if (size === void 0) { + size = {}; + } + + if (!this._isReady) { + return this; + } + + var containerSize; + + if (size.width === undefined || size.height === undefined) { + containerSize = window.getComputedStyle(this._container); + } + + var width = size.width || parseInt(containerSize.width, 10); + var height = size.height || parseInt(containerSize.height, 10); // Skip if viewport is not changed. + + if (width === this._width && height === this._height) { + return this; + } + + this._width = width; + this._height = height; + this._aspectRatio = width / height; + + this._photoSphereRenderer.updateViewportDimensions(width, height); + + this._yawPitchControl.option("aspectRatio", this._aspectRatio); + + this._yawPitchControl.updatePanScale({ + height: height + }); + + this.lookAt({}, 0); + return this; + }; + /** + * Get the current field of view(FOV) + * @ko 현재 field of view(FOV) 값을 반환합니다. + */ + + + __proto.getFov = function () { + return this._fov; + }; + /** + * Get current yaw value + * @ko 현재 yaw 값을 반환합니다. + */ + + + __proto.getYaw = function () { + return this._yaw; + }; + /** + * Get current pitch value + * @ko 현재 pitch 값을 반환합니다. + */ + + + __proto.getPitch = function () { + return this._pitch; + }; + /** + * Get the range of controllable Yaw values + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + */ + + + __proto.getYawRange = function () { + return this._yawPitchControl.option("yawRange"); + }; + /** + * Get the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다. + */ + + + __proto.getPitchRange = function () { + return this._yawPitchControl.option("pitchRange"); + }; + /** + * Set the range of controllable yaw + * @ko 컨트롤 가능한 Yaw 구간을 반환합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setYawRange([-90, 90]); + */ + + + __proto.setYawRange = function (yawRange) { + this._yawPitchControl.option("yawRange", yawRange); + + return this; + }; + /** + * Set the range of controllable Pitch values + * @ko 컨트롤 가능한 Pitch 구간을 설정합니다. + * @param {number[]} range + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * panoViewer.setPitchRange([-40, 40]); + */ + + + __proto.setPitchRange = function (pitchRange) { + this._yawPitchControl.option("pitchRange", pitchRange); + + return this; + }; + /** + * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed. + * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다. + * @param showPolePoint + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.setShowPolePoint = function (showPolePoint) { + this._yawPitchControl.option("showPolePoint", showPolePoint); + + return this; + }; + /** + * Set a new view by setting camera configuration. Any parameters not specified remain the same. + * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다. + * @param {object} orientation + * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위) + * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위) + * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위) + * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초) + * @return PanoViewer instancePanoViewer 인스턴스 + * @example + * ``` + * // Change the yaw angle (absolute angle) to 30 degrees for one second. + * panoViewer.lookAt({yaw: 30}, 1000); + * ``` + */ + + + __proto.lookAt = function (orientation, duration) { + if (duration === void 0) { + duration = 0; + } + + if (!this._isReady) { + return this; + } + + var yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw; + var pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch; + + var pitchRange = this._yawPitchControl.option("pitchRange"); + + var verticalAngleOfImage = pitchRange[1] - pitchRange[0]; + var fov = orientation.fov !== undefined ? orientation.fov : this._fov; + + if (verticalAngleOfImage < fov) { + fov = verticalAngleOfImage; + } + + this._yawPitchControl.lookAt({ + yaw: yaw, + pitch: pitch, + fov: fov + }, duration); + + if (duration === 0) { + this._photoSphereRenderer.renderWithYawPitch(yaw, pitch, fov); + } + + return this; + }; + /** + * Set touch direction by which user can control. + * @ko 사용자가 조작가능한 터치 방향을 지정합니다. + * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @return PanoViewer instance + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Limit the touch direction to the yaw direction only. + * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW); + * ``` + */ + + + __proto.setTouchDirection = function (direction) { + if (PanoViewer._isValidTouchDirection(direction)) { + this._yawPitchControl.option("touchDirection", direction); + } + + return this; + }; + /** + * Returns touch direction by which user can control + * @ko 사용자가 조작가능한 터치 방향을 반환한다. + * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION} + * @example + * ``` + * panoViewer = new PanoViewer(el); + * // Returns the current touch direction. + * var dir = panoViewer.getTouchDirection(); + * ``` + */ + + + __proto.getTouchDirection = function () { + return this._yawPitchControl.option("touchDirection"); + }; + /** + * Destroy viewer. Remove all registered event listeners and remove viewer canvas. + * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다. + * @return PanoViewer instancePanoViewer 인스턴스 + */ + + + __proto.destroy = function () { + this._deactivate(); + + if (this._yawPitchControl) { + this._yawPitchControl.destroy(); + + this._yawPitchControl = null; + } + + return this; + }; // TODO: Remove parameters as they're just using private values + + + __proto._initRenderer = function (yaw, pitch, fov, projectionType, cubemapConfig) { + var _this = this; + + this._photoSphereRenderer = new PanoImageRenderer(this._image, this._width, this._height, this._isVideo, this._container, this._canvasClass, { + initialYaw: yaw, + initialPitch: pitch, + fieldOfView: fov, + imageType: projectionType, + cubemapConfig: cubemapConfig, + stereoFormat: this._stereoFormat + }); + + this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl); + + this._bindRendererHandler(); + + this._photoSphereRenderer.bindTexture().then(function () { + return _this._activate(); + }).catch(function () { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.FAIL_BIND_TEXTURE, + message: "failed to bind texture" + })); + }); + }; + /** + * @private + * update values of YawPitchControl if needed. + * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image. + * + * This function should be called after isReady status is true. + */ + + + __proto._updateYawPitchIfNeeded = function () { + if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) { + // update fov by aspect ratio + var image = this._photoSphereRenderer.getContent(); + + var imageAspectRatio = image.naturalWidth / image.naturalHeight; + var yawSize = void 0; + var maxFov = void 0; // If height is larger than width, then we assume it's rotated by 90 degree. + + if (imageAspectRatio < 1) { + // So inverse the aspect ratio. + imageAspectRatio = 1 / imageAspectRatio; + } + + if (imageAspectRatio < 6) { + yawSize = util.toDegree(imageAspectRatio); // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5 + + maxFov = util.toDegree(Math.atan(0.5)) * 2; + } else { + yawSize = 360; + maxFov = 360 / imageAspectRatio; // Make it 5 fixed as axes does. + } // console.log("_updateYawPitchIfNeeded", maxFov, "aspectRatio", image.naturalWidth, image.naturalHeight, "yawSize", yawSize); + + + var minFov = this._yawPitchControl.option("fovRange")[0]; // this option should be called after fov is set. + + + this._yawPitchControl.option({ + "fov": maxFov, + "yawRange": [-yawSize / 2, yawSize / 2], + "pitchRange": [-maxFov / 2, maxFov / 2], + "fovRange": [minFov, maxFov] + }); + + this.lookAt({ + fov: maxFov + }); + } + }; + + __proto._bindRendererHandler = function () { + var _this = this; + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.ERROR, function (e) { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, e)); + }); + + this._photoSphereRenderer.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, function () { + _this._deactivate(); + + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ERROR, { + type: ERROR_TYPE.RENDERING_CONTEXT_LOST, + message: "webgl rendering context lost" + })); + }); + }; + + __proto._initYawPitchControl = function (yawPitchConfig) { + var _this = this; + + this._yawPitchControl = new YawPitchControl(yawPitchConfig); + + this._yawPitchControl.on(PANOVIEWER_EVENTS.ANIMATION_END, function (e) { + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.ANIMATION_END, e)); + }); + + this._yawPitchControl.on("change", function (e) { + _this._yaw = e.yaw; + _this._pitch = e.pitch; + _this._fov = e.fov; + _this._quaternion = e.quaternion; + + _this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.VIEW_CHANGE, { + yaw: e.yaw, + pitch: e.pitch, + fov: e.fov, + quaternion: e.quaternion, + isTrusted: e.isTrusted + })); + }); + }; + + __proto._activate = function () { + this._photoSphereRenderer.attachTo(this._container); + + this._yawPitchControl.enable(); + + this.updateViewportDimensions(); + this._isReady = true; // update yawPitchControl after isReady status is true. + + this._updateYawPitchIfNeeded(); + + this.trigger(new ComponentEvent$1(PANOVIEWER_EVENTS.READY)); + + this._photoSphereRenderer.startRender(); + }; + /** + * Destroy webgl context and block user interaction and stop rendering + */ + + + __proto._deactivate = function () { + // Turn off the video if it has one + var video = this.getVideo(); + + if (video) { + video.pause(); + } + + if (this._isReady) { + this._photoSphereRenderer.stopRender(); + + this._yawPitchControl.disable(); + + this._isReady = false; + } + + if (this._photoSphereRenderer) { + this._photoSphereRenderer.destroy(); + + this._photoSphereRenderer = null; + } + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @type {String} + * @example + * eg.view360.PanoViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.PanoViewer + */ + + + PanoViewer.VERSION = VERSION; + PanoViewer.ERROR_TYPE = ERROR_TYPE; + PanoViewer.EVENTS = PANOVIEWER_EVENTS; + PanoViewer.PROJECTION_TYPE = PROJECTION_TYPE; + PanoViewer.GYRO_MODE = GYRO_MODE; // This should be deprecated! + // eslint-disable-next-line @typescript-eslint/naming-convention + + PanoViewer.ProjectionType = PROJECTION_TYPE; + PanoViewer.STEREO_FORMAT = STEREO_FORMAT; + /** + * Constant value for touch directions + * @ko 터치 방향에 대한 상수 값. + * @namespace + * @name TOUCH_DIRECTION + */ + + PanoViewer.TOUCH_DIRECTION = { + /** + * Constant value for none direction. + * @ko none 방향에 대한 상수 값. + * @name NONE + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 1 + */ + NONE: YawPitchControl.TOUCH_DIRECTION_NONE, + + /** + * Constant value for horizontal(yaw) direction. + * @ko horizontal(yaw) 방향에 대한 상수 값. + * @name YAW + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 6 + */ + YAW: YawPitchControl.TOUCH_DIRECTION_YAW, + + /** + * Constant value for vertical direction. + * @ko vertical(pitch) 방향에 대한 상수 값. + * @name PITCH + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 24 + */ + PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH, + + /** + * Constant value for all direction. + * @ko all 방향에 대한 상수 값. + * @name ALL + * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION + * @constant + * @type {Number} + * @default 30 + */ + ALL: YawPitchControl.TOUCH_DIRECTION_ALL + }; + return PanoViewer; + }(Component); + + var PanoViewer$1 = { + __proto__: null, + PanoViewer: PanoViewer, + VERSION: VERSION, + GYRO_MODE: GYRO_MODE, + PANOVIEWER_EVENTS: PANOVIEWER_EVENTS, + ERROR_TYPE: ERROR_TYPE, + PROJECTION_TYPE: PROJECTION_TYPE, + STEREO_FORMAT: STEREO_FORMAT, + PANOVIEWER_OPTIONS: PANOVIEWER_OPTIONS, + DEFAULT_CANVAS_CLASS: DEFAULT_CANVAS_CLASS + }; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + var SPINVIEWER_OPTIONS = { + imageUrl: true, + rowCount: true, + colCount: true, + width: true, + height: true, + autoHeight: true, + colRow: true, + scale: true, + frameIndex: true, + wrapperClass: true, + imageClass: true + }; + var SPINVIEWER_EVENTS = { + LOAD: "load", + IMAGE_ERROR: "imageError", + CHANGE: "change", + ANIMATION_END: "animationEnd" + }; + var DEFAULT_WRAPPER_CLASS = "view360-wrapper"; + var DEFAULT_IMAGE_CLASS = "view360-image"; + + /** + * @memberof eg.view360 + * @extends eg.Component + * SpriteImage + */ + + var SpriteImage = + /*#__PURE__*/ + function (_super) { + __extends(SpriteImage, _super); + /** + * @class eg.view360.SpriteImage + * @classdesc A module that displays a single or continuous image of any one of the "sprite images". SpinViewer internally uses SpriteImage to show each frame of the sprite image. + * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다. + * @extends eg.Component + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the "Sprite image". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
+ * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * + * // Initialize SpriteImage + * + * var el = document.getElementById("image-div"); + * var sprites = new eg.view360.SpriteImage(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 + * }); + */ + + + function SpriteImage(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + var opt = options || {}; + _this._el = element; + _this._rowCount = opt.rowCount || 1; + _this._colCount = opt.colCount || 1; + _this._totalCount = _this._rowCount * _this._colCount; // total frames + + _this._width = opt.width || "auto"; + _this._height = opt.height || "auto"; + _this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten. + + _this._colRow = [0, 0]; + + if (opt.colRow) { + _this._colRow = opt.colRow; + } else if (opt.frameIndex) { + _this.setFrameIndex(opt.frameIndex); + } + + _this._el.style.width = SpriteImage._getSizeString(_this._width); + _this._el.style.height = SpriteImage._getSizeString(_this._height); + var wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS; + var imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS; + + if (!opt.imageUrl) { + setTimeout(function () { + _this.trigger(new ComponentEvent$1("imageError", { + imageUrl: opt.imageUrl + })); + }, 0); + return _this; + } + + var imageInContainer = element.querySelector("." + imageClass); + var wrapperInContainer = element.querySelector("." + wrapperClass); + + if (wrapperInContainer && imageInContainer) { + // Set it to invisible to prevent wrapper being resized + imageInContainer.style.display = "none"; + } + + _this._image = imageInContainer || new Image(); + /** + * Event + */ + + var image = _this._image; + + image.onload = function () { + if (wrapperInContainer && imageInContainer) { + imageInContainer.style.display = ""; + } + + _this._bg = SpriteImage._createBgDiv(wrapperInContainer, image, _this._rowCount, _this._colCount, _this._autoHeight); + + _this._el.appendChild(_this._bg); + + _this.setColRow(_this._colRow[0], _this._colRow[1]); + + _this.trigger(new ComponentEvent$1("load", { + target: _this._el, + bgElement: _this._bg + })); + + if (_this._autoPlayReservedInfo) { + _this.play(_this._autoPlayReservedInfo); + + _this._autoPlayReservedInfo = null; + } + }; + + image.onerror = function () { + _this.trigger(new ComponentEvent$1("imageError", { + imageUrl: opt.imageUrl + })); + }; + + image.src = opt.imageUrl; + return _this; + } + + var __proto = SpriteImage.prototype; + + SpriteImage._createBgDiv = function (wrapperInContainer, img, rowCount, colCount, autoHeight) { + var el = wrapperInContainer || document.createElement("div"); + el.style.position = "relative"; + el.style.overflow = "hidden"; + img.style.position = "absolute"; + img.style.width = colCount * 100 + "%"; + img.style.height = rowCount * 100 + "%"; + /** Prevent image from being dragged on IE10, IE11, Safari especially */ + + img.ondragstart = function () { + return false; + }; // img.style.pointerEvents = "none"; + // Use hardware accelerator if available + + + if (SUPPORT_WILLCHANGE) { + img.style.willChange = "transform"; + } + + el.appendChild(img); + var unitWidth = img.naturalWidth / colCount; + var unitHeight = img.naturalHeight / rowCount; + + if (autoHeight) { + var r = unitHeight / unitWidth; + el.style.paddingBottom = r * 100 + "%"; + } else { + el.style.height = "100%"; + } + + return el; + }; + + SpriteImage._getSizeString = function (size) { + if (typeof size === "number") { + return size + "px"; + } + + return size; + }; + /** + * Specifies the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정 + * @method eg.view360.SpriteImage#setFrameIndex + * @param {Number} frameIndex frame index of a frame프레임의 인덱스 + * + * @example + * + * sprites.setFrameIndex(0, 1);// col = 0, row = 1 + */ + + + __proto.setFrameIndex = function (index) { + var colRow = this.toColRow(index); + this.setColRow(colRow[0], colRow[1]); + }; + /** + * Returns the frameIndex of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환 + * @method eg.view360.SpriteImage#getFrameIndex + * @return {Number} frame index frame 인덱스 + * + * @example + * + * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1 + * + */ + + + __proto.getFrameIndex = function () { + return this._colRow[1] * this._colCount + this._colRow[0]; + }; + /** + * Specifies the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정 + * @method eg.view360.SpriteImage#setColRow + * @param {Number} col Column number of a frame프레임의 행값 + * @param {Number} row Row number of a frame프레임의 열값 + * + * @example + * + * sprites.setlColRow(1, 2); // col = 1, row = 2 + */ + + + __proto.setColRow = function (col, row) { + if (row > this._rowCount - 1 || col > this._colCount - 1) { + return; + } + + if (this._image && TRANSFORM) { + // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser? + this._image.style[TRANSFORM] = "translate(" + -(col / this._colCount * 100) + "%, " + -(row / this._rowCount * 100) + "%)"; + } + + this._colRow = [col, row]; + }; + /** + * Returns the col and row values of the frame to be shown in the sprite image. + * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환 + * @method eg.view360.SpriteImage#gelColRow + * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열 + * + * @example + * + * var colRow = sprites.getlColRow(); + * // colRow = [1, 2] - index of col is 1, index of row is 2 + * + */ + + + __proto.getColRow = function () { + return this._colRow; + }; + /** + * Stop playing + * @ko play 되고 있던 프레임 재생을 중지합니다. + * @method eg.view360.SpriteImage#stop + * + * @example + * + * viewer.stop(); + * + */ + + + __proto.stop = function () { + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + }; + /** + * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'. + * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다. + * @method eg.view360.SpriteImage#play + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위 + * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복 + * + * @example + * + * viewer.play({angle: 16, playCount: 1}); + * + */ + + + __proto.play = function (_a) { + var _this = this; + + var _b = _a === void 0 ? { + interval: 1000 / this._totalCount, + playCount: 0 + } : _a, + interval = _b.interval, + playCount = _b.playCount; + + if (!this._bg) { + this._autoPlayReservedInfo = { + interval: interval, + playCount: playCount + }; + return; + } + + if (this._autoPlayTimer) { + clearInterval(this._autoPlayTimer); + this._autoPlayTimer = -1; + } + + var frameIndex = this.getFrameIndex(); + var count = 0; + var frameCount = 0; // for checking 1 cycle + + this._autoPlayTimer = window.setInterval(function () { + frameIndex %= _this._totalCount; + + var colRow = _this.toColRow(frameIndex); + + _this.setColRow(colRow[0], colRow[1]); + + frameIndex++; // Done 1 Cycle? + + if (++frameCount === _this._totalCount) { + frameCount = 0; + count++; + } + + if (playCount > 0 && count === playCount) { + clearInterval(_this._autoPlayTimer); + } + }, interval); + }; + + __proto.toColRow = function (frameIndex) { + var colCount = this._colCount; + var rowCount = this._rowCount; + + if (frameIndex < 0) { + return [0, 0]; + } else if (frameIndex >= this._totalCount) { + return [colCount - 1, rowCount - 1]; + } + + var col = frameIndex % colCount; + var row = Math.floor(frameIndex / colCount); // console.log(frameIndex, col, row); + + return [col, row]; + }; + + SpriteImage.VERSION = VERSION; + return SpriteImage; + }(Component); + + var DEFAULT_PAN_SCALE = 0.21; + /** + * @memberof eg.view360 + * @extends eg.Component + * SpinViewer + */ + + var SpinViewer = + /*#__PURE__*/ + function (_super) { + __extends(SpinViewer, _super); + /** + * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object. + * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다. + * + * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소 + * @param {Object} options The option object파라미터 객체 + * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url + * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수 + * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수 + * @param {Number|String} [options.width="auto"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비 + * @param {Number|String} [options.height="auto"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이 + * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부 + * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반) + * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임) + * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값 + * @param {String} [options.wrapperClass="view360-wrapper"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @param {String} [options.imageClass="view360-image"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다 + * @support {"ie": "9+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.3+ (except 3.x)"} + * @example + * ``` + * // Initialize SpinViewer + * var el = document.getElementById("product-360"); + * var viewer = new eg.view360.SpinViewer(el, { + * imageUrl: "/img/bag360.jpg", // required + * rowCount: 24 //required + * }); + * ``` + */ + + + function SpinViewer(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this._el = element; + + var opt = __assign({}, options); + + var colCount = opt.colCount || 1; + var rowCount = opt.rowCount || 1; + _this._scale = opt.scale || 1; + _this._panScale = _this._scale * DEFAULT_PAN_SCALE; + _this._frameCount = colCount * rowCount; // Init SpriteImage + + _this._sprites = new SpriteImage(element, opt).on({ + "load": function (evt) { + _this.trigger(new ComponentEvent$1("load", evt)); + }, + "imageError": function (evt) { + _this.trigger(new ComponentEvent$1("imageError", { + imageUrl: evt.imageUrl + })); + } + }); // Init Axes + + _this._panInput = new PanInput(_this._el, { + scale: [_this._panScale, _this._panScale] + }); + _this._axes = new Axes({ + angle: { + range: [0, 359], + circular: true + } + }).on({ + "change": function (evt) { + var curr = Math.floor(evt.pos.angle / (360 / _this._frameCount)); + var frameIndex = _this._frameCount - curr - 1; + + _this._sprites.setFrameIndex(frameIndex); + + _this.trigger(new ComponentEvent$1("change", { + frameIndex: frameIndex, + colRow: _this._sprites.getColRow(), + angle: evt.pos.angle + })); + }, + "animationEnd": function (evt) { + _this.trigger(new ComponentEvent$1("animationEnd", { + isTrusted: evt.isTrusted + })); + } + }); + + _this._axes.connect("angle", _this._panInput); + + return _this; + } + /** + * Set spin scale + * @ko scale 을 조정할 수 있는 함수 + * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.setScale(2);// It moves twice as much. + */ + + + var __proto = SpinViewer.prototype; + + __proto.setScale = function (scale) { + if (isNaN(scale) || scale < 0) { + return this; + } + + this._scale = scale; + this._panScale = scale * DEFAULT_PAN_SCALE; + this._panInput.options.scale = [this._panScale, this._panScale]; + return this; + }; + /** + * Get spin scale + * @ko scale 값을 반환한다. + * + * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전 + * + * @example + * viewer.getScale();// It returns number + */ + + + __proto.getScale = function () { + return this._scale; + }; + /** + * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle. + * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle상대적 회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinBy(720, {duration: 500}); + */ + + + __proto.spinBy = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setBy({ + angle: angle + }, param.duration); + + return this; + }; + /** + * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle). + * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다. + * @param {Number} [angle = 0] angle회전 각도 + * @param {Object} param The parameter object파라미터 객체 + * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위 + * + * @return {Object} Instance of SpinViewer SpinViewer 인스턴스 + * + * @example + * viewer.spinTo(30, {duration:100}); + */ + + + __proto.spinTo = function (angle, param) { + if (angle === void 0) { + angle = 0; + } + + if (param === void 0) { + param = { + duration: 0 + }; + } + + this._axes.setTo({ + angle: angle + }, param.duration); + + return this; + }; + /** + * Returns current angles + * @ko 현재 각도를 반환한다. + * + * @return {Number} Current angle 현재 각도 + */ + + + __proto.getAngle = function () { + return this._axes.get().angle || 0; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @static + * @example + * eg.view360.SpinViewer.VERSION; // ex) 3.0.1 + * @memberof eg.view360.SpinViewer + */ + + + SpinViewer.VERSION = VERSION; + return SpinViewer; + }(Component); + + var SpinViewer$1 = { + __proto__: null, + SpinViewer: SpinViewer, + SpriteImage: SpriteImage, + VERSION: VERSION, + SPINVIEWER_OPTIONS: SPINVIEWER_OPTIONS, + SPINVIEWER_EVENTS: SPINVIEWER_EVENTS, + DEFAULT_WRAPPER_CLASS: DEFAULT_WRAPPER_CLASS, + DEFAULT_IMAGE_CLASS: DEFAULT_IMAGE_CLASS + }; + + var withMethods = function (component, prototype, vanillaInstance) { + [Component.prototype, component.prototype].forEach(function (proto) { + Object.getOwnPropertyNames(proto).filter(function (name) { + return !prototype[name] && !name.startsWith("_") && name !== "constructor"; + }).forEach(function (name) { + var descriptor = Object.getOwnPropertyDescriptor(proto, name); + + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function () { + var _a; + + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + return (_a = descriptor.value).call.apply(_a, __spread([this[vanillaInstance]], args)); + } + }); + } else { + var getterDescriptor = {}; + + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + + return (_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[vanillaInstance]); + }; + } + + if (descriptor.set) { + getterDescriptor.set = function () { + var _a; + + var args = []; + + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call.apply(_a, __spread([this[vanillaInstance]], args)); + }; + } + + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); + }; + + var withPanoViewerMethods = function (prototype, name) { + withMethods(PanoViewer, prototype, name); + }; + + var withSpinViewerMethods = function (prototype, name) { + withMethods(SpinViewer, prototype, name); + }; + + var updatePanoViewer = (function (panoViewer, newProps, prevProps) { + if (isPropChanged(newProps.image, prevProps.image)) { + panoViewer.setImage(newProps.image, { + projectionType: newProps.projectionType, + cubemapConfig: newProps.cubemapConfig, + stereoFormat: newProps.stereoFormat, + isVideo: false + }); + } else if (isPropChanged(newProps.video, prevProps.video)) { + panoViewer.setVideo(newProps.video, { + projectionType: newProps.projectionType, + cubemapConfig: newProps.cubemapConfig, + stereoFormat: newProps.stereoFormat + }); + } + + var singleUpdateOptions = ["fovRange", "gyroMode", "pitchRange", "showPolePoint", "touchDirection", "useKeyboard", "useZoom", "yawRange"]; + singleUpdateOptions.forEach(function (optionName) { + updateOption(panoViewer, optionName, newProps, prevProps); + }); + }); + + var isPropChanged = function (val, prevVal) { + return val != null && val !== prevVal; + }; + + var updateOption = function (panoViewer, optionName, newProps, prevProps) { + if (isPropChanged(newProps[optionName], prevProps[optionName])) { + panoViewer["set" + optionName[0].toUpperCase() + optionName.slice(1)](newProps[optionName]); + } + }; + + var getValidProps = function (propsObj) { + return Object.keys(propsObj).reduce(function (props, propName) { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + + return props; + }, {}); + }; + var generateCanvasKey = function (oldKey) { + var newKey; + + do { + var array = new Uint32Array(1); + crypto.getRandomValues(array); + newKey = array[0]; + } while (newKey === oldKey); + + return newKey; + }; + + var CFC = { + __proto__: null, + withMethods: withMethods, + withPanoViewerMethods: withPanoViewerMethods, + withSpinViewerMethods: withSpinViewerMethods, + updatePanoViewer: updatePanoViewer, + getValidProps: getValidProps, + generateCanvasKey: generateCanvasKey + }; + + /* + * Copyright (c) 2017 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + var View360 = {}; + merge(View360, PanoViewer$1); + merge(View360, SpinViewer$1); + merge(View360, CFC); + + return View360; + +}))); +//# sourceMappingURL=view360.pkgd.js.map diff --git a/dist/view360.pkgd.js.map b/dist/view360.pkgd.js.map new file mode 100644 index 000000000..2b97373ee --- /dev/null +++ b/dist/view360.pkgd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.pkgd.js","sources":["../src/version.ts","../src/utils/browser.ts","../src/utils/browserFeature.ts","../src/utils/math-util.ts","../src/YawPitchControl/utils.ts","../src/YawPitchControl/consts.ts","../src/YawPitchControl/input/lib/webvr-polyfill/math-util.ts","../src/YawPitchControl/input/lib/webvr-polyfill/util.ts","../src/YawPitchControl/input/lib/webvr-polyfill/pose-predictor.ts","../src/YawPitchControl/input/DeviceMotion.ts","../src/YawPitchControl/input/lib/webvr-polyfill/sensor-sample.ts","../src/YawPitchControl/input/lib/webvr-polyfill/complementary-filter.ts","../src/YawPitchControl/input/ComplementaryFilter.ts","../src/YawPitchControl/input/FusionPoseSensor.ts","../src/YawPitchControl/input/TiltMotionInput.ts","../src/YawPitchControl/ScreenRotationAngle.ts","../src/YawPitchControl/input/RotationPanInput.ts","../src/YawPitchControl/DeviceQuaternion.ts","../src/YawPitchControl/YawPitchControl.ts","../src/PanoViewer/consts.ts","../src/utils/utils.ts","../src/PanoImageRenderer/WebGLUtils.ts","../src/PanoImageRenderer/renderer/Renderer.ts","../src/PanoImageRenderer/renderer/CubeRenderer.ts","../src/PanoImageRenderer/renderer/CubeStripRenderer.ts","../src/PanoImageRenderer/renderer/SphereRenderer.ts","../src/PanoImageRenderer/renderer/CylinderRenderer.ts","../src/PanoImageRenderer/vr/VRManager.ts","../src/PanoImageRenderer/vr/XRManager.ts","../src/PanoImageRenderer/WebGLAnimator.ts","../src/PanoImageRenderer/PanoImageRenderer.ts","../src/PanoViewer/PanoViewer.ts","../src/SpinViewer/consts.ts","../src/SpinViewer/SpriteImage.ts","../src/SpinViewer/SpinViewer.ts","../src/cfc/withMethods.ts","../src/cfc/withPanoViewerMethods.ts","../src/cfc/withSpinViewerMethods.ts","../src/cfc/updatePanoViewer.ts","../src/cfc/utils.ts","../src/index.umd.ts"],"sourcesContent":["const VERSION = \"#__VERSION__#\";\n\nexport {\n VERSION\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","/**\n * Original Code\n * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js\n * Math Util\n * modified by egjs\n */\n/**\n * @fileoverview gl-matrix - High performance matrix and vector operations\n * @author Brandon Jones\n * @author Colin MacKenzie IV\n * @version 2.3.2\n */\n\n/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE. */\n\n// Some minimal math functionality borrowed from gl-Matrix and stripped down\n// for the purposes of this library.\n\nimport { vec2, vec3, quat } from \"gl-matrix\";\n\nimport { ValueOf } from \"../types/internal\";\n\nconst quatToVec3 = (quaternion: quat) => {\n const baseV = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(baseV, baseV, quaternion);\n return baseV;\n};\n\nconst toDegree = (a: number) => a * 180 / Math.PI;\n\nconst util: any = {};\n\nutil.isPowerOfTwo = (n: number) => n && (n & (n - 1)) === 0;\n\nutil.extractPitchFromQuat = (quaternion: quat) => {\n const baseV = quatToVec3(quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n};\n\nutil.hypot = Math.hypot || ((x: number, y: number) => Math.sqrt(x * x + y * y));\n\n// implement reference\n// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식\n// calculating angle between two vectors : http://darkpgmr.tistory.com/121\nconst ROTATE_CONSTANT: {\n PITCH_DELTA: 1;\n YAW_DELTA_BY_ROLL: 2;\n YAW_DELTA_BY_YAW: 3;\n} = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n};\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nconst getRotationDelta = (prevQ: quat, curQ: quat, rotateKind: ValueOf) => {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n // const coefficientD = -1 * vec3.dot(vecN, meshPoint1);\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance =\n coefficientA * crossVec[0] +\n coefficientB * crossVec[1] +\n coefficientC * crossVec[2];\n\n let thetaDirection;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return toDegree(deltaRadian);\n};\n\nconst angleBetweenVec2 = (v1: vec2, v2: vec2) => {\n const det = v1[0] * v2[1] - v2[0] * v1[1];\n const theta = -Math.atan2(det, vec2.dot(v1, v2));\n return theta;\n};\n\nutil.yawOffsetBetween = (viewDir: number, targetDir: number) => {\n const viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]);\n const targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]);\n\n vec2.normalize(viewDirXZ, viewDirXZ);\n vec2.normalize(targetDirXZ, targetDirXZ);\n\n const theta = -angleBetweenVec2(viewDirXZ, targetDirXZ);\n\n return theta;\n};\n\nutil.sign = (x: number) => Math.sign\n ? Math.sign(x)\n : (Number(x > 0) - Number(x < 0)) || +x;\n\nutil.toDegree = toDegree;\nutil.getRotationDelta = getRotationDelta;\nutil.angleBetweenVec2 = angleBetweenVec2;\n\nexport {\n util,\n ROTATE_CONSTANT\n};\n","import { quat } from \"gl-matrix\";\n\nimport {\n util as mathUtil,\n ROTATE_CONSTANT\n} from \"../utils/math-util\";\n\nexport const toAxis = (source, offset) => offset.reduce((acc, v, i) => {\n if (source[i]) {\n acc[source[i]] = v;\n }\n return acc;\n}, {});\n\nexport const getDeltaYaw = (prvQ: quat, curQ: quat) => {\n const yawDeltaByYaw = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(mathUtil.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nexport const getDeltaPitch = (prvQ: quat, curQ: quat) => {\n const pitchDelta = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n","import { userAgent } from \"../utils/browserFeature\";\n/**\n * Returns a number value indiciating the version of Chrome being used,\n * or otherwise `null` if not on Chrome.\n *\n * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19\n */\n/**\n * In Chrome m65, `devicemotion` events are broken but subsequently fixed\n * in 65.0.3325.148. Since many browsers use Chromium, ensure that\n * we scope this detection by branch and build numbers to provide\n * a proper fallback.\n * https://github.com/immersive-web/webvr-polyfill/issues/307\n */\nlet version = -1; // It should not be null because it will be compared with number\nlet branch: string | null = null;\nlet build: string | null = null;\n\nconst match = /Chrome\\/([0-9]+)\\.(?:[0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(userAgent);\n\nif (match) {\n version = parseInt(match[1], 10);\n branch = match[2];\n build = match[3];\n}\n\nconst CHROME_VERSION = version;\nconst IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === \"3325\" && parseInt(build!, 10) < 148;\nconst IS_ANDROID = /Android/i.test(userAgent);\n\nconst CONTROL_MODE_VR = 1;\nconst CONTROL_MODE_YAWPITCH = 2;\n\nconst TOUCH_DIRECTION_NONE = 1;\nconst TOUCH_DIRECTION_YAW = 2;\nconst TOUCH_DIRECTION_PITCH = 4;\nconst TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH;\n\n/* Const for MovableCoord */\nconst MC_DECELERATION = 0.0014;\nconst MC_MAXIMUM_DURATION = 1000;\nconst MC_BIND_SCALE = [0.20, 0.20];\n\nconst MIN_FIELD_OF_VIEW = 20;\nconst MAX_FIELD_OF_VIEW = 110;\nconst PAN_SCALE = 320;\n\n// const DELTA_THRESHOLD = 0.015;\n// const DELTA_THRESHOLD = 0.09; // Note4\n// const DELTA_THRESHOLD = 0.0825;\n// const DELTA_THRESHOLD = 0.075;\n// const DELTA_THRESHOLD = 0.06;\n// const DELTA_THRESHOLD = 0.045;\nconst DELTA_THRESHOLD = 0.0375; // Note2\n\nconst YAW_RANGE_HALF = 180;\nconst PITCH_RANGE_HALF = 90;\nconst CIRCULAR_PITCH_RANGE_HALF = 180;\nconst PINCH_EVENTS = \"pinchstart pinchmove pinchend\";\n\nconst KEYMAP = {\n LEFT_ARROW: 37,\n A: 65,\n UP_ARROW: 38,\n W: 87,\n RIGHT_ARROW: 39,\n D: 68,\n DOWN_ARROW: 40,\n S: 83\n};\n\nconst GYRO_MODE: {\n NONE: \"none\";\n YAWPITCH: \"yawPitch\";\n VR: \"VR\";\n} = {\n NONE: \"none\",\n YAWPITCH: \"yawPitch\",\n VR: \"VR\"\n};\n\nexport {\n GYRO_MODE,\n\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n\n TOUCH_DIRECTION_NONE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MIN_FIELD_OF_VIEW,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n DELTA_THRESHOLD,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n PINCH_EVENTS,\n KEYMAP,\n\n CHROME_VERSION,\n IS_CHROME_WITHOUT_DEVICE_MOTION,\n IS_ANDROID\n};\n","/* eslint-disable */\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { window as win } from \"../../../../utils/browser\";\n\nconst MathUtil = win.MathUtil || {};\n\nMathUtil.degToRad = Math.PI / 180;\nMathUtil.radToDeg = 180 / Math.PI;\n\n// Some minimal math functionality borrowed from THREE.Math and stripped down\n// for the purposes of this library.\n\n\nMathUtil.Vector2 = function( x, y ) {\n this.x = x || 0;\n this.y = y || 0;\n};\n\nMathUtil.Vector2.prototype = {\n constructor: MathUtil.Vector2,\n\n set: function( x, y ) {\n this.x = x;\n this.y = y;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n },\n\n subVectors: function( a, b ) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n\n return this;\n }\n};\n\nMathUtil.Vector3 = function( x, y, z ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n};\n\nMathUtil.Vector3.prototype = {\n constructor: MathUtil.Vector3,\n\n set: function( x, y, z ) {\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n\n return this;\n },\n\n length: function() {\n return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n },\n\n normalize: function() {\n const scalar = this.length();\n\n if ( scalar !== 0 ) {\n const invScalar = 1 / scalar;\n\n this.multiplyScalar(invScalar);\n } else {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n }\n\n return this;\n },\n\n multiplyScalar: function( scalar ) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n },\n\n applyQuaternion: function( q ) {\n const x = this.x;\n const y = this.y;\n const z = this.z;\n\n const qx = q.x;\n const qy = q.y;\n const qz = q.z;\n const qw = q.w;\n\n // calculate quat * vector\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = - qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n return this;\n },\n\n dot: function( v ) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n },\n\n crossVectors: function( a, b ) {\n const ax = a.x;\n const ay = a.y;\n const az = a.z;\n const bx = b.x;\n const by = b.y;\n const bz = b.z;\n\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n\n return this;\n }\n};\n\nMathUtil.Quaternion = function( x, y, z, w ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n this.w = ( w !== undefined ) ? w : 1;\n};\n\nMathUtil.Quaternion.prototype = {\n constructor: MathUtil.Quaternion,\n\n set: function( x, y, z, w ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n\n return this;\n },\n\n copy: function( quaternion ) {\n this.x = quaternion.x;\n this.y = quaternion.y;\n this.z = quaternion.z;\n this.w = quaternion.w;\n\n return this;\n },\n\n setFromEulerXYZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 + s1 * s2 * c3;\n this.w = c1 * c2 * c3 - s1 * s2 * s3;\n\n return this;\n },\n\n setFromEulerYXZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 - s1 * s2 * c3;\n this.w = c1 * c2 * c3 + s1 * s2 * s3;\n\n return this;\n },\n\n setFromAxisAngle: function( axis, angle ) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n // assumes axis is normalized\n\n const halfAngle = angle / 2;\n const s = Math.sin( halfAngle );\n\n this.x = axis.x * s;\n this.y = axis.y * s;\n this.z = axis.z * s;\n this.w = Math.cos( halfAngle );\n\n return this;\n },\n\n multiply: function( q ) {\n return this.multiplyQuaternions( this, q );\n },\n\n multiplyQuaternions: function( a, b ) {\n // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n const qax = a.x;\n const qay = a.y;\n const qaz = a.z;\n const qaw = a.w;\n const qbx = b.x;\n const qby = b.y;\n const qbz = b.z;\n const qbw = b.w;\n\n this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n return this;\n },\n\n inverse: function() {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n\n this.normalize();\n\n return this;\n },\n\n normalize: function() {\n let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n if ( l === 0 ) {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n this.w = 1;\n } else {\n l = 1 / l;\n\n this.x = this.x * l;\n this.y = this.y * l;\n this.z = this.z * l;\n this.w = this.w * l;\n }\n\n return this;\n },\n\n slerp: function( qb, t ) {\n if ( t === 0 ) return this;\n if ( t === 1 ) return this.copy( qb );\n\n const x = this.x;\n const y = this.y;\n const z = this.z;\n const w = this.w;\n\n // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n let cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;\n\n if ( cosHalfTheta < 0 ) {\n this.w = - qb.w;\n this.x = - qb.x;\n this.y = - qb.y;\n this.z = - qb.z;\n\n cosHalfTheta = - cosHalfTheta;\n } else {\n this.copy( qb );\n }\n\n if ( cosHalfTheta >= 1.0 ) {\n this.w = w;\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n }\n\n const halfTheta = Math.acos( cosHalfTheta );\n const sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n if ( Math.abs( sinHalfTheta ) < 0.001 ) {\n this.w = 0.5 * ( w + this.w );\n this.x = 0.5 * ( x + this.x );\n this.y = 0.5 * ( y + this.y );\n this.z = 0.5 * ( z + this.z );\n\n return this;\n }\n\n const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;\n const ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n this.w = ( w * ratioA + this.w * ratioB );\n this.x = ( x * ratioA + this.x * ratioB );\n this.y = ( y * ratioA + this.y * ratioB );\n this.z = ( z * ratioA + this.z * ratioB );\n\n return this;\n },\n\n setFromUnitVectors: function() {\n // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n // assumes direction vectors vFrom and vTo are normalized\n\n let v1;\n let r;\n const EPS = 0.000001;\n\n return function( vFrom, vTo ) {\n if ( v1 === undefined ) v1 = new MathUtil.Vector3();\n\n r = vFrom.dot( vTo ) + 1;\n\n if ( r < EPS ) {\n r = 0;\n\n if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n v1.set( - vFrom.y, vFrom.x, 0 );\n } else {\n v1.set( 0, - vFrom.z, vFrom.y );\n }\n } else {\n v1.crossVectors( vFrom, vTo );\n }\n\n this.x = v1.x;\n this.y = v1.y;\n this.z = v1.z;\n this.w = r;\n\n this.normalize();\n\n return this;\n };\n }()\n};\n\nexport default MathUtil;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tslint:disable: only-arrow-functions\n\nimport { window as win, document as doc, navigator as nav } from \"../../../../utils/browser\";\n\nconst userAgent = nav?.userAgent ?? \"\";\nconst Util = (win ).Util || {};\n\nUtil.MIN_TIMESTEP = 0.001;\nUtil.MAX_TIMESTEP = 1;\n\nUtil.base64 = function(mimeType, base64) {\n return \"data:\" + mimeType + \";base64,\" + base64;\n};\n\nUtil.clamp = function(value, min, max) {\n return Math.min(Math.max(min, value), max);\n};\n\nUtil.lerp = function(a, b, t) {\n return a + ((b - a) * t);\n};\n\nUtil.isIOS = (function() {\n const isIOS = /iPad|iPhone|iPod/.test(nav?.platform);\n return function() {\n return isIOS;\n };\n})();\n\nUtil.isWebViewAndroid = (function() {\n const isWebViewAndroid = userAgent.indexOf(\"Version\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1 &&\n userAgent.indexOf(\"Chrome\") !== -1;\n return function() {\n return isWebViewAndroid;\n };\n})();\n\nUtil.isSafari = (function() {\n const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n return function() {\n return isSafari;\n };\n})();\n\nUtil.isFirefoxAndroid = (function() {\n const isFirefoxAndroid = userAgent.indexOf(\"Firefox\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1;\n return function() {\n return isFirefoxAndroid;\n };\n})();\n\nUtil.isR7 = (function() {\n const isR7 = userAgent.indexOf(\"R7 Build\") !== -1;\n return function() {\n return isR7;\n };\n})();\n\nUtil.isLandscapeMode = function() {\n const rtn = (win.orientation === 90 || win.orientation === -90);\n return Util.isR7() ? !rtn : rtn;\n};\n\n// Helper method to validate the time steps of sensor timestamps.\nUtil.isTimestampDeltaValid = function(timestampDeltaS) {\n if (isNaN(timestampDeltaS)) {\n return false;\n }\n if (timestampDeltaS <= Util.MIN_TIMESTEP) {\n return false;\n }\n if (timestampDeltaS > Util.MAX_TIMESTEP) {\n return false;\n }\n return true;\n};\n\nUtil.getScreenWidth = function() {\n return Math.max(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.getScreenHeight = function() {\n return Math.min(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.requestFullscreen = function(element) {\n if (Util.isWebViewAndroid()) {\n return false;\n }\n if (element.requestFullscreen) {\n element.requestFullscreen();\n } else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n } else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n } else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.exitFullscreen = function() {\n if (doc.exitFullscreen) {\n doc.exitFullscreen();\n } else if (doc.webkitExitFullscreen) {\n doc.webkitExitFullscreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.getFullscreenElement = function() {\n return doc.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n};\n\nUtil.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {\n // No error checking for brevity.\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n const program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n\n for (const attribName in attribLocationMap)\n gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);\n\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n};\n\nUtil.getProgramUniforms = function(gl, program) {\n const uniforms = {};\n const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n let uniformName = \"\";\n for (let i = 0; i < uniformCount; i++) {\n const uniformInfo = gl.getActiveUniform(program, i);\n uniformName = uniformInfo.name.replace(\"[0]\", \"\");\n uniforms[uniformName] = gl.getUniformLocation(program, uniformName);\n }\n return uniforms;\n};\n\nUtil.orthoMatrix = function(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right);\n const bt = 1 / (bottom - top);\n const nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n};\n\nUtil.copyArray = function(source, dest) {\n for (let i = 0, n = source.length; i < n; i++) {\n dest[i] = source[i];\n }\n};\n\nUtil.isMobile = function() {\n let check = false;\n (function(a) {\n if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))check = true;\n })(userAgent || nav?.vendor || win.opera);\n return check;\n};\n\nUtil.extend = function(dest, src) {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n dest[key] = src[key];\n }\n }\n\n return dest;\n};\n\nUtil.safariCssSizeWorkaround = function(canvas) {\n // TODO(smus): Remove this workaround when Safari for iOS is fixed.\n // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).\n //\n // \"To the last I grapple with thee;\n // from hell's heart I stab at thee;\n // for hate's sake I spit my last breath at thee.\"\n // -- Moby Dick, by Herman Melville\n if (Util.isIOS()) {\n const width = canvas.style.width;\n const height = canvas.style.height;\n canvas.style.width = (parseInt(width) + 1) + \"px\";\n canvas.style.height = (parseInt(height)) + \"px\";\n setTimeout(function() {\n canvas.style.width = width;\n canvas.style.height = height;\n }, 100);\n }\n\n // Debug only.\n win.Util = Util;\n win.canvas = canvas;\n};\n\nUtil.isDebug = function() {\n return Util.getQueryParameter(\"debug\");\n};\n\nUtil.getQueryParameter = function(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n const results = regex.exec(location.search);\n return results === null ? \"\" : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n};\n\nUtil.frameDataFromPose = (function() {\n const piOver180 = Math.PI / 180.0;\n const rad45 = Math.PI * 0.25;\n\n // Borrowed from glMatrix.\n function mat4_perspectiveFromFieldOfView(out, fov, near, far) {\n const upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45);\n const downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45);\n const leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45);\n const rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45);\n const xScale = 2.0 / (leftTan + rightTan);\n const yScale = 2.0 / (upTan + downTan);\n\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = ((upTan - downTan) * yScale * 0.5);\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = (far * near) / (near - far);\n out[15] = 0.0;\n return out;\n }\n\n function mat4_fromRotationTranslation(out, q, v) {\n // Quaternion math\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n\n return out;\n }\n\n function mat4_translate(out, a, v) {\n const x = v[0];\n const y = v[1];\n const z = v[2];\n let a00;\n let a01;\n let a02;\n let a03;\n let a10;\n let a11;\n let a12;\n let a13;\n let a20;\n let a21;\n let a22;\n let a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];\n a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];\n a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];\n\n out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;\n out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;\n out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;\n\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n }\n\n function mat4_invert(out, a) {\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n }\n\n const defaultOrientation = new Float32Array([0, 0, 0, 1]);\n const defaultPosition = new Float32Array([0, 0, 0]);\n\n function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {\n mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);\n\n const orientation = pose.orientation || defaultOrientation;\n const position = pose.position || defaultPosition;\n\n mat4_fromRotationTranslation(view, orientation, position);\n if (parameters)\n mat4_translate(view, view, parameters.offset);\n mat4_invert(view, view);\n }\n\n return function(frameData, pose, vrDisplay) {\n if (!frameData || !pose)\n return false;\n\n frameData.pose = pose;\n frameData.timestamp = pose.timestamp;\n\n updateEyeMatrices(\n frameData.leftProjectionMatrix, frameData.leftViewMatrix,\n pose, vrDisplay.getEyeParameters(\"left\"), vrDisplay);\n updateEyeMatrices(\n frameData.rightProjectionMatrix, frameData.rightViewMatrix,\n pose, vrDisplay.getEyeParameters(\"right\"), vrDisplay);\n\n return true;\n };\n})();\n\nUtil.isInsideCrossDomainIFrame = function() {\n const isFramed = (win.self !== win.top);\n const refDomain = Util.getDomainFromUrl(doc.referrer);\n const thisDomain = Util.getDomainFromUrl(win.location.href);\n\n return isFramed && (refDomain !== thisDomain);\n};\n\n// From http://stackoverflow.com/a/23945027.\nUtil.getDomainFromUrl = function(url) {\n let domain;\n // Find & remove protocol (http, ftp, etc.) and get domain.\n if (url.indexOf(\"://\") > -1) {\n domain = url.split(\"/\")[2];\n } else {\n domain = url.split(\"/\")[0];\n }\n\n // find & remove port number\n domain = domain.split(\":\")[0];\n\n return domain;\n};\n\nexport default Util;\n","/* eslint-disable */\n\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * Given an orientation and the gyroscope data, predicts the future orientation\n * of the head. This makes rendering appear faster.\n *\n * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf\n * @param {Number} predictionTimeS time from head movement to the appearance of\n * the corresponding image.\n */\nclass PosePredictor {\n public predictionTimeS;\n public previousQ;\n public previousTimestampS;\n public deltaQ;\n public outQ;\n\n public constructor(predictionTimeS) {\n this.predictionTimeS = predictionTimeS;\n\n // The quaternion corresponding to the previous state.\n this.previousQ = new MathUtil.Quaternion();\n // Previous time a prediction occurred.\n this.previousTimestampS = null;\n\n // The delta quaternion that adjusts the current pose.\n this.deltaQ = new MathUtil.Quaternion();\n // The output quaternion.\n this.outQ = new MathUtil.Quaternion();\n }\n\n public getPrediction(currentQ, gyro, timestampS) {\n if (!this.previousTimestampS) {\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n return currentQ;\n }\n\n // Calculate axis and angle based on gyroscope rotation rate data.\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n\n const angularSpeed = gyro.length();\n\n // If we're rotating slowly, don't do prediction.\n if (angularSpeed < MathUtil.degToRad * 20) {\n if (Util.isDebug()) {\n console.log(\"Moving slowly, at %s deg/s: no prediction\",\n (MathUtil.radToDeg * angularSpeed).toFixed(1));\n }\n this.outQ.copy(currentQ);\n this.previousQ.copy(currentQ);\n return this.outQ;\n }\n\n // Get the predicted angle based on the time delta and latency.\n const deltaT = timestampS - this.previousTimestampS;\n const predictAngle = angularSpeed * this.predictionTimeS;\n\n this.deltaQ.setFromAxisAngle(axis, predictAngle);\n this.outQ.copy(this.previousQ);\n this.outQ.multiply(this.deltaQ);\n\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n\n return this.outQ;\n }\n}\n\nexport default PosePredictor;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3 } from \"gl-matrix\";\n\nimport { Mutable } from \"../../types/internal\";\nimport { window } from \"../../utils/browser\";\nimport { IS_CHROME_WITHOUT_DEVICE_MOTION, IS_ANDROID } from \"../consts\";\n\nconst STILLNESS_THRESHOLD = 200; // millisecond\n\nexport default class DeviceMotion extends Component<{\n devicemotion: {\n inputEvent: DeviceMotionEvent | {\n deviceorientation: {\n alpha: number;\n beta: number;\n gamma: number;\n };\n };\n };\n}> {\n public readonly isWithoutDeviceMotion: boolean;\n public readonly isAndroid: boolean;\n\n public stillGyroVec: vec3;\n public rawGyroVec: vec3;\n public adjustedGyroVec: vec3;\n public lastDevicemotionTimestamp: number;\n\n private _timer: number;\n private _isEnabled: boolean;\n\n public constructor() {\n super();\n this._onDeviceMotion = this._onDeviceMotion.bind(this);\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onChromeWithoutDeviceMotion = this._onChromeWithoutDeviceMotion.bind(this);\n\n this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION;\n this.isAndroid = IS_ANDROID;\n\n this.stillGyroVec = vec3.create();\n this.rawGyroVec = vec3.create();\n this.adjustedGyroVec = vec3.create();\n\n this._timer = -1;\n\n this.lastDevicemotionTimestamp = 0;\n this._isEnabled = false;\n this.enable();\n }\n\n public enable() {\n if (this.isAndroid) {\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n }\n if (this.isWithoutDeviceMotion) {\n window.addEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n } else {\n window.addEventListener(\"devicemotion\", this._onDeviceMotion);\n }\n this._isEnabled = true;\n }\n\n public disable() {\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n window.removeEventListener(\"devicemotion\", this._onDeviceMotion);\n this._isEnabled = false;\n }\n\n private _onChromeWithoutDeviceMotion(e: DeviceOrientationEvent) {\n let {alpha, beta, gamma} = e;\n\n // There is deviceorientation event trigged with empty values\n // on Headless Chrome.\n if (alpha === null) {\n return;\n }\n\n // convert to radian\n alpha = (alpha || 0) * Math.PI / 180;\n beta = (beta || 0) * Math.PI / 180;\n gamma = (gamma || 0) * Math.PI / 180;\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: {\n deviceorientation: {\n alpha,\n beta,\n gamma: -gamma\n }\n }\n }));\n }\n\n private _onDeviceOrientation() {\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timer = window.setTimeout(() => {\n if ((new Date().getTime() - this.lastDevicemotionTimestamp) < STILLNESS_THRESHOLD) {\n vec3.copy(this.stillGyroVec, this.rawGyroVec);\n }\n }, STILLNESS_THRESHOLD);\n }\n\n private _onDeviceMotion(e: DeviceMotionEvent) {\n // desktop chrome triggers devicemotion event with empthy sensor values.\n // Those events should ignored.\n const isGyroSensorAvailable = !(e.rotationRate!.alpha == null);\n const isGravitySensorAvailable = !(e.accelerationIncludingGravity!.x == null);\n\n if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) {\n return;\n }\n\n const devicemotionEvent = {...e} as Mutable;\n\n devicemotionEvent.interval = e.interval;\n devicemotionEvent.timeStamp = e.timeStamp;\n devicemotionEvent.type = e.type;\n devicemotionEvent.rotationRate = {\n alpha: e.rotationRate!.alpha,\n beta: e.rotationRate!.beta,\n gamma: e.rotationRate!.gamma\n };\n devicemotionEvent.accelerationIncludingGravity = {\n x: e.accelerationIncludingGravity!.x,\n y: e.accelerationIncludingGravity!.y,\n z: e.accelerationIncludingGravity!.z\n };\n devicemotionEvent.acceleration = {\n x: e.acceleration!.x,\n y: e.acceleration!.y,\n z: e.acceleration!.z\n };\n\n if (this.isAndroid) {\n vec3.set(\n this.rawGyroVec,\n e.rotationRate!.alpha || 0,\n e.rotationRate!.beta || 0,\n e.rotationRate!.gamma || 0);\n vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec);\n this.lastDevicemotionTimestamp = new Date().getTime();\n\n (devicemotionEvent as any).adjustedRotationRate = {\n alpha: this.adjustedGyroVec[0],\n beta: this.adjustedGyroVec[1],\n gamma: this.adjustedGyroVec[2]};\n }\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: devicemotionEvent\n }));\n }\n}\n","class SensorSample {\n public sample;\n public timestampS;\n\n public constructor(sample?, timestampS?) {\n this.set(sample, timestampS);\n }\n\n public set(sample, timestampS) {\n this.sample = sample;\n this.timestampS = timestampS;\n }\n\n public copy(sensorSample) {\n this.set(sensorSample.sample, sensorSample.timestampS);\n }\n}\n\nexport default SensorSample;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SensorSample from \"./sensor-sample\";\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * An implementation of a simple complementary filter, which fuses gyroscope and\n * accelerometer data from the 'devicemotion' event.\n *\n * Accelerometer data is very noisy, but stable over the long term.\n * Gyroscope data is smooth, but tends to drift over the long term.\n *\n * This fusion is relatively simple:\n * 1. Get orientation estimates from accelerometer by applying a low-pass filter\n * on that data.\n * 2. Get orientation estimates from gyroscope by integrating over time.\n * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the\n * short term.\n */\nclass ComplementaryFilter {\n public kFilter;\n public currentAccelMeasurement;\n public currentGyroMeasurement;\n public previousGyroMeasurement;\n public filterQ;\n public previousFilterQ;\n public accelQ;\n public isOrientationInitialized;\n public estimatedGravity;\n public measuredGravity;\n public gyroIntegralQ;\n\n constructor(kFilter) {\n this.kFilter = kFilter;\n\n // Raw sensor measurements.\n this.currentAccelMeasurement = new SensorSample();\n this.currentGyroMeasurement = new SensorSample();\n this.previousGyroMeasurement = new SensorSample();\n\n // Set default look direction to be in the correct direction.\n if (Util.isIOS()) {\n this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);\n } else {\n this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);\n }\n this.previousFilterQ = new MathUtil.Quaternion();\n this.previousFilterQ.copy(this.filterQ);\n\n // Orientation based on the accelerometer.\n this.accelQ = new MathUtil.Quaternion();\n // Whether or not the orientation has been initialized.\n this.isOrientationInitialized = false;\n // Running estimate of gravity based on the current orientation.\n this.estimatedGravity = new MathUtil.Vector3();\n // Measured gravity based on accelerometer.\n this.measuredGravity = new MathUtil.Vector3();\n\n // Debug only quaternion of gyro-based orientation.\n this.gyroIntegralQ = new MathUtil.Quaternion();\n }\n\n public addAccelMeasurement(vector, timestampS) {\n this.currentAccelMeasurement.set(vector, timestampS);\n }\n\n public addGyroMeasurement = function(vector, timestampS) {\n this.currentGyroMeasurement.set(vector, timestampS);\n\n const deltaT = timestampS - this.previousGyroMeasurement.timestampS;\n if (Util.isTimestampDeltaValid(deltaT)) {\n this.run_();\n }\n\n this.previousGyroMeasurement.copy(this.currentGyroMeasurement);\n };\n\n public getOrientation() {\n return this.filterQ;\n }\n\n public run_() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n if (Util.isDebug()) {\n console.log(\"Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)\",\n MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),\n (this.estimatedGravity.x).toFixed(1),\n (this.estimatedGravity.y).toFixed(1),\n (this.estimatedGravity.z).toFixed(1),\n (this.measuredGravity.x).toFixed(1),\n (this.measuredGravity.y).toFixed(1),\n (this.measuredGravity.z).toFixed(1));\n }\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n }\n\n private accelToQuaternion_(accel) {\n const normAccel = new MathUtil.Vector3();\n normAccel.copy(accel);\n normAccel.normalize();\n const quat = new MathUtil.Quaternion();\n quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);\n quat.inverse();\n return quat;\n }\n\n private gyroToQuaternionDelta_(gyro, dt) {\n // Extract axis and angle from the gyroscope data.\n const quat = new MathUtil.Quaternion();\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n quat.setFromAxisAngle(axis, gyro.length() * dt);\n return quat;\n }\n}\n\nexport default ComplementaryFilter;\n","import MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport ComplementaryFilter from \"./lib/webvr-polyfill/complementary-filter\";\n\nComplementaryFilter.prototype.run_ = function() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n\n if (!this.isFilterQuaternionInitialized) {\n this.isFilterQuaternionInitialized = true;\n }\n};\n\nComplementaryFilter.prototype.getOrientation = function() {\n if (this.isFilterQuaternionInitialized) {\n return this.filterQ;\n } else {\n return null;\n }\n};\n\nexport default ComplementaryFilter;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\n\nimport { window, IS_IOS, IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { CHROME_VERSION } from \"../consts\";\n\nimport PosePredictor from \"./lib/webvr-polyfill/pose-predictor\";\nimport MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport Util from \"./lib/webvr-polyfill/util\";\nimport DeviceMotion from \"./DeviceMotion\";\nimport ComplementaryFilter from \"./ComplementaryFilter\";\n\n\nconst K_FILTER = 0.98;\nconst PREDICTION_TIME_S = 0.040;\n\nexport default class FusionPoseSensor extends Component<{\n change: {\n quaternion: quat;\n };\n}> {\n public deviceMotion: DeviceMotion | null;\n public accelerometer: any;\n public gyroscope: any;\n public filter: ComplementaryFilter;\n public posePredictor: PosePredictor;\n public filterToWorldQ: any;\n public isFirefoxAndroid: boolean;\n public isIOS: boolean;\n public isChromeUsingDegrees: boolean;\n public inverseWorldToScreenQ: any;\n public worldToScreenQ: any;\n public originalPoseAdjustQ: any;\n public resetQ: any;\n public deviceOrientationFixQ: any;\n public predictedQ: any;\n public previousTimestampS: number;\n\n private _isEnabled: boolean;\n private _deviceOrientationQ: any;\n private _prevOrientation: quat;\n private _alpha: number;\n\n public constructor() {\n super();\n\n this.deviceMotion = new DeviceMotion();\n\n this.accelerometer = new MathUtil.Vector3();\n this.gyroscope = new MathUtil.Vector3();\n\n this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);\n this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);\n\n this.filter = new ComplementaryFilter(K_FILTER);\n this.posePredictor = new PosePredictor(PREDICTION_TIME_S);\n\n this.filterToWorldQ = new MathUtil.Quaternion();\n\n this.isFirefoxAndroid = Util.isFirefoxAndroid();\n // This includes iPhone & iPad(both desktop and mobile mode) ref #326\n this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP;\n\n // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18\n this.isChromeUsingDegrees = CHROME_VERSION >= 66;\n\n this._isEnabled = false;\n\n // Set the filter to world transform, depending on OS.\n if (this.isIOS) {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);\n } else {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n this.inverseWorldToScreenQ = new MathUtil.Quaternion();\n this.worldToScreenQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),\n -window.orientation * Math.PI / 180);\n\n this._setScreenTransform();\n // Adjust this filter for being in landscape mode.\n if (Util.isLandscapeMode()) {\n this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);\n }\n\n // Keep track of a reset transform for resetSensor.\n this.resetQ = new MathUtil.Quaternion();\n\n this.deviceMotion.on(\"devicemotion\", this._onDeviceMotionChange);\n this.enable();\n }\n\n public enable() {\n if (this.isEnabled()) {\n return;\n }\n this.deviceMotion!.enable();\n this._isEnabled = true;\n window.addEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public disable() {\n if (!this.isEnabled()) {\n return;\n }\n this.deviceMotion!.disable();\n this._isEnabled = false;\n window.removeEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public isEnabled() {\n return this._isEnabled;\n }\n\n public destroy() {\n this.disable();\n this.deviceMotion = null;\n }\n\n public getOrientation() {\n let orientation;\n\n // Hack around using deviceorientation instead of devicemotion\n if (this.deviceMotion!.isWithoutDeviceMotion && this._deviceOrientationQ) {\n this.deviceOrientationFixQ = this.deviceOrientationFixQ || (() => {\n const y = new MathUtil.Quaternion()\n .setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -this._alpha);\n\n return y;\n })();\n\n orientation = this._deviceOrientationQ;\n const out = new MathUtil.Quaternion();\n\n out.copy(orientation);\n out.multiply(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.worldToScreenQ);\n out.multiplyQuaternions(this.deviceOrientationFixQ, out);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n } else {\n // Convert from filter space to the the same system used by the\n // deviceorientation event.\n orientation = this.filter.getOrientation();\n\n if (!orientation) {\n return null;\n }\n\n const out = this._convertFusionToPredicted(orientation);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n }\n }\n\n private _triggerChange() {\n const orientation = this.getOrientation();\n\n // if orientation is not prepared. don't trigger change event\n if (!orientation) {\n return;\n }\n\n if (!this._prevOrientation) {\n this._prevOrientation = orientation;\n return;\n }\n\n if (quat.equals(this._prevOrientation, orientation)) {\n return;\n }\n\n this.trigger(new ComponentEvent(\"change\", { quaternion: orientation }));\n }\n\n private _convertFusionToPredicted(orientation: quat) {\n // Predict orientation.\n this.predictedQ =\n this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);\n\n // Convert to THREE coordinate system: -Z forward, Y up, X right.\n const out = new MathUtil.Quaternion();\n\n out.copy(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.predictedQ);\n out.multiply(this.worldToScreenQ);\n\n return out;\n }\n\n private _onDeviceMotionChange({ inputEvent }) {\n const deviceorientation = inputEvent.deviceorientation;\n const deviceMotion = inputEvent;\n const accGravity = deviceMotion.accelerationIncludingGravity;\n const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;\n let timestampS = deviceMotion.timeStamp / 1000;\n\n if (deviceorientation) {\n if (!this._alpha) {\n this._alpha = deviceorientation.alpha;\n }\n this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();\n this._deviceOrientationQ.setFromEulerYXZ(\n deviceorientation.beta,\n deviceorientation.alpha,\n deviceorientation.gamma\n );\n\n this._triggerChange();\n } else {\n // Firefox Android timeStamp returns one thousandth of a millisecond.\n if (this.isFirefoxAndroid) {\n timestampS /= 1000;\n }\n\n this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);\n this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);\n\n // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate`\n // is reported in degrees, so we first convert to radians.\n if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) {\n this.gyroscope.multiplyScalar(Math.PI / 180);\n }\n\n this.filter.addAccelMeasurement(this.accelerometer, timestampS);\n this.filter.addGyroMeasurement(this.gyroscope, timestampS);\n\n this._triggerChange();\n\n this.previousTimestampS = timestampS;\n }\n }\n\n private _onScreenOrientationChange() {\n this._setScreenTransform();\n }\n\n private _setScreenTransform() {\n this.worldToScreenQ.set(0, 0, 0, 1);\n\n const orientation = window.orientation;\n\n switch (orientation) {\n case 0:\n break;\n case 90:\n case -90:\n case 180:\n this.worldToScreenQ\n .setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI);\n break;\n default:\n break;\n }\n this.inverseWorldToScreenQ.copy(this.worldToScreenQ);\n this.inverseWorldToScreenQ.inverse();\n }\n}\n","import Component from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\n\nimport { toAxis } from \"../utils\";\nimport { util, ROTATE_CONSTANT } from \"../../utils/math-util\";\n\nimport FusionPoseSensor from \"./FusionPoseSensor\";\n\nconst getDeltaYaw = (prvQ: quat, curQ: quat): number => {\n const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(util.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nconst getDeltaPitch = (prvQ: quat, curQ: quat): number => {\n const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport default class TiltMotionInput extends Component<{}> {\n public element: HTMLElement;\n public options: { scale: number; threshold: number };\n public fusionPoseSensor: FusionPoseSensor | null;\n public axes: string[];\n public observer: InputTypeObserver | null;\n\n private _prevQuaternion: quat | null;\n private _quaternion: quat | null;\n\n public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {\n super();\n this.element = el;\n\n this._prevQuaternion = null;\n this._quaternion = null;\n\n this.fusionPoseSensor = null;\n\n this.options = {\n ...{\n scale: 1,\n threshold: 0\n }, ...options\n };\n\n this._onPoseChange = this._onPoseChange.bind(this);\n }\n\n public mapAxes(axes: string[]) {\n this.axes = axes;\n }\n\n public connect(observer: InputTypeObserver) {\n if (this.observer) {\n return this;\n }\n this.observer = observer;\n this.fusionPoseSensor = new FusionPoseSensor();\n this.fusionPoseSensor.enable();\n this._attachEvent();\n return this;\n }\n\n public disconnect() {\n if (!this.observer) {\n return this;\n }\n\n this._dettachEvent();\n this.fusionPoseSensor!.disable();\n this.fusionPoseSensor!.destroy();\n this.fusionPoseSensor = null;\n this.observer = null;\n return this;\n }\n\n public destroy() {\n this.disconnect();\n (this.element as any) = null;\n (this.options as any) = null;\n (this.axes as any) = null;\n this._prevQuaternion = null;\n this._quaternion = null;\n }\n\n private _onPoseChange(event) {\n if (!this._prevQuaternion) {\n this._prevQuaternion = quat.clone(event.quaternion);\n this._quaternion = quat.clone(event.quaternion);\n return;\n }\n\n quat.copy(this._prevQuaternion, this._quaternion!);\n quat.copy(this._quaternion!, event.quaternion);\n\n this.observer!.change(this, event, toAxis(this.axes, [\n getDeltaYaw(this._prevQuaternion, this._quaternion as quat),\n getDeltaPitch(this._prevQuaternion, this._quaternion as quat)\n ]));\n }\n\n private _attachEvent() {\n this.fusionPoseSensor!.on(\"change\", this._onPoseChange);\n }\n\n private _dettachEvent() {\n this.fusionPoseSensor!.off(\"change\", this._onPoseChange);\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport { window } from \"../utils/browser\";\n\n// Singleton\nlet screenRotationAngleInst: ScreenRotationAngle | null = null;\nlet refCount = 0;\n\nexport default class ScreenRotationAngle {\n private _spinR: number;\n private _screenOrientationAngle: number;\n\n public constructor() {\n refCount++;\n\n if (screenRotationAngleInst) {\n return screenRotationAngleInst;\n }\n /* eslint-disable */\n screenRotationAngleInst = this;\n /* eslint-enable */\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n\n this._spinR = 0;\n\n this._screenOrientationAngle = 0;\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.addEventListener(\"orientationchange\", this._onOrientationChange);\n }\n\n public getRadian() {\n // Join with screen orientation\n // this._testVal = this._spinR + \", \" + this._screenOrientationAngle + \", \" + window.orientation;\n return this._spinR + glMatrix.toRadian(this._screenOrientationAngle);\n }\n\n public unref() {\n if (--refCount > 0) {\n return;\n }\n\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"orientationchange\", this._onOrientationChange);\n\n this._spinR = 0;\n this._screenOrientationAngle = 0;\n /* eslint-disable */\n screenRotationAngleInst = null;\n /* eslint-enable */\n refCount = 0;\n }\n\n private _onDeviceOrientation(e: DeviceOrientationEvent) {\n if (e.beta === null || e.gamma === null) {\n // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it.\n return;\n }\n\n // Radian\n const betaR = glMatrix.toRadian(e.beta);\n const gammaR = glMatrix.toRadian(e.gamma);\n\n /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */\n this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR));\n }\n\n private _onOrientationChange() {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientationAngle = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n /* iOS */\n this._screenOrientationAngle = window.orientation >= 0 ?\n window.orientation : 360 + (window.orientation as number);\n }\n }\n}\n","import Axes, { PanInput } from \"@egjs/axes\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\nimport { PanInputOption } from \"@egjs/axes/declaration/inputType/PanInput\";\n\nimport ScreenRotationAngle from \"../ScreenRotationAngle\";\n\n/**\n * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle.\n *\n * The reason for using this function is that in VR mode,\n * the roll angle is adjusted in the direction opposite to the screen rotation angle.\n *\n * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move.\n * @extends PanInput\n */\nexport default class RotationPanInput extends PanInput {\n private _useRotation: boolean;\n private _screenRotationAngle: ScreenRotationAngle | null;\n private _userDirection: number;\n\n /**\n * Constructor\n * @private\n * @param {HTMLElement} el target element\n * @param {Object} [options] The option object\n * @param {Boolean} [options.useRotation] Whether to use rotation(or VR)\n */\n public constructor(el: HTMLElement, options: Partial<{ useRotation: boolean } & PanInputOption> = {}) {\n super(el, options);\n\n this._useRotation = false;\n this._screenRotationAngle = null;\n\n this.setUseRotation(!!(options && options.useRotation));\n\n this._userDirection = Axes.DIRECTION_ALL;\n }\n\n public setUseRotation(useRotation: boolean) {\n this._useRotation = useRotation;\n\n if (this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n this._screenRotationAngle = null;\n }\n\n if (this._useRotation) {\n this._screenRotationAngle = new ScreenRotationAngle();\n }\n }\n\n public connect(observer: InputTypeObserver) {\n // User intetened direction\n this._userDirection = this._direction;\n\n // In VR Mode, Use ALL direction if direction is not none\n // Because horizontal and vertical is changed dynamically by screen rotation.\n // this._direction is used to initialize hammerjs\n if (this._useRotation && (this._direction & Axes.DIRECTION_ALL)) {\n this._direction = Axes.DIRECTION_HORIZONTAL;\n }\n\n return super.connect(observer);\n }\n\n public destroy() {\n if (this._useRotation && this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n }\n\n super.destroy();\n }\n\n protected _getOffset(properties: number[], useDirection: boolean[]) {\n if (this._useRotation === false) {\n return super._getOffset(properties, useDirection);\n }\n\n const offset = super._getOffset(properties, [true, true]);\n const newOffset = [0, 0];\n\n const theta = this._screenRotationAngle!.getRadian();\n\n const cosTheta = Math.cos(theta);\n const sinTheta = Math.sin(theta);\n\n // RotateZ\n newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta;\n newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta;\n\n // Use only user allowed direction.\n if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) {\n newOffset[0] = 0;\n } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) {\n newOffset[1] = 0;\n }\n\n return newOffset;\n }\n}\n\n/**\n * Override getDirectionByAngle to return DIRECTION_ALL\n * Ref: https://github.com/naver/egjs-axes/issues/99\n *\n * But we obey axes's rule. If axes's rule is problem, let's apply following code.\n */\n// PanInput.getDirectionByAngle = function (angle, thresholdAngle) {\n// \treturn DIRECTION_ALL;\n// };\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3, glMatrix, quat } from \"gl-matrix\";\n\nimport FusionPoseSensor from \"./input/FusionPoseSensor\";\n\nconst Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0);\n\nexport default class DeviceQuaternion extends Component<{\n change: {\n isTrusted: boolean;\n };\n}> {\n private _fusionPoseSensor: FusionPoseSensor | null;\n private _quaternion: quat;\n\n public constructor() {\n super();\n\n this._fusionPoseSensor = new FusionPoseSensor();\n this._quaternion = quat.create();\n\n this._fusionPoseSensor.enable();\n this._fusionPoseSensor.on(\"change\", e => {\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(\"change\", { isTrusted: true }));\n });\n }\n\n public getCombinedQuaternion(yaw: number) {\n const yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw));\n const conj = quat.conjugate(quat.create(), this._quaternion);\n // Multiply pitch quaternion -> device quaternion -> yaw quaternion\n const outQ = quat.multiply(quat.create(), conj, yawQ);\n\n return outQ;\n }\n\n public destroy() {\n // detach all event handler\n this.off();\n\n if (this._fusionPoseSensor) {\n this._fusionPoseSensor.off();\n this._fusionPoseSensor.destroy();\n this._fusionPoseSensor = null;\n }\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PinchInput, MoveKeyInput, WheelInput } from \"@egjs/axes\";\nimport { vec2, quat, glMatrix } from \"gl-matrix\";\n\nimport { SUPPORT_TOUCH, SUPPORT_DEVICEMOTION } from \"../utils/browserFeature\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { ValueOf } from \"../types/internal\";\n\nimport TiltMotionInput from \"./input/TiltMotionInput\";\nimport RotationPanInput from \"./input/RotationPanInput\";\nimport DeviceQuaternion from \"./DeviceQuaternion\";\nimport {\n GYRO_MODE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n TOUCH_DIRECTION_NONE\n} from \"./consts\";\n\n\nconst DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF];\nconst DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF];\nconst CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF];\n\nexport interface YawPitchControlOptions {\n element: HTMLElement | null;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n touchDirection: number;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n aspectRatio: number;\n}\ninterface YawPitchControlEvents {\n change: ComponentEvent<{\n yaw: number;\n pitch: number;\n fov: number;\n quaternion: quat | null;\n targetElement: HTMLElement;\n isTrusted: boolean;\n }>;\n hold: ComponentEvent<{\n isTrusted: boolean;\n }>;\n animationEnd: ComponentEvent<{\n isTrusted: boolean;\n }>;\n}\n\n/**\n * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates.\n * @alias eg.YawPitchControl\n * @extends eg.Component\n *\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass YawPitchControl extends Component {\n public static VERSION = VERSION;\n // Expose DeviceOrientationControls sub module for test purpose\n public static CONTROL_MODE_VR = CONTROL_MODE_VR;\n public static CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH;\n public static TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL;\n public static TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW;\n public static TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH;\n public static TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE;\n\n public options: YawPitchControlOptions;\n\n private _element: HTMLElement | null;\n private _initialFov: number;\n private _enabled: boolean;\n private _isAnimating: boolean;\n private _deviceQuaternion: DeviceQuaternion | null;\n\n private _axes: Axes;\n private _axesPanInput: RotationPanInput;\n private _axesWheelInput: WheelInput;\n private _axesTiltMotionInput: TiltMotionInput | null;\n private _axesPinchInput: PinchInput | null;\n private _axesMoveKeyInput: MoveKeyInput;\n\n /**\n * @param {object} options The option object of the eg.YawPitch module\n * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module\n * @param {number} [options.yaw=0] initial yaw (degree)\n * @param {number} [options.pitch=0] initial pitch (degree)\n * @param {number} [options.fov=65] initial field of view (degree)\n * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown\n * @param {boolean} [options.useZoom=true] Indicates whether zoom is available\n * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled\n * @param {string} [config.gyroMode=yawPitch] Enables control through device motion.\n * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move)\n * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw\n * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch\n * @param {number[]} [options.fovRange=[30, 110] Range of FOV\n * @param {number} [options.aspectRatio=1] Aspect Ratio\n */\n public constructor(options: Partial) {\n super();\n this.options = {} as any;\n\n const opt = {\n ...{\n element: null,\n yaw: 0,\n pitch: 0,\n fov: 65,\n showPolePoint: false,\n useZoom: true,\n useKeyboard: true,\n gyroMode: GYRO_MODE.YAWPITCH,\n touchDirection: TOUCH_DIRECTION_ALL,\n yawRange: DEFAULT_YAW_RANGE,\n pitchRange: DEFAULT_PITCH_RANGE,\n fovRange: [30, 110],\n aspectRatio: 1 /* TODO: Need Mandatory? */\n }, ...options\n };\n\n this._element = opt.element;\n this._initialFov = opt.fov;\n this._enabled = false;\n this._isAnimating = false;\n this._deviceQuaternion = null;\n\n this._initAxes(opt);\n this.option(opt);\n }\n\n /**\n * Update Pan Scale\n *\n * Scale(Sensitivity) values of panning is related with fov and height.\n * If at least one of them is changed, this function need to be called.\n * @param {*} param\n */\n public updatePanScale(param: Partial<{\n height: number;\n }> = {}) {\n const fov = this._axes.get().fov;\n const areaHeight = param.height || parseInt(window.getComputedStyle(this._element!).height, 10);\n const scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight;\n\n this._axesPanInput.options.scale = [scale, scale];\n this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW;\n\n return this;\n }\n\n public option(): YawPitchControlOptions;\n public option(key: K): YawPitchControlOptions[K];\n public option(key: K, newValue: YawPitchControlOptions[K]): YawPitchControl;\n public option(newOptions: Partial): YawPitchControl;\n /*\n * Override component's option method\n * to call method for updating values which is affected by option change.\n *\n * @param {*} args\n */\n public option(key?: K | Partial, newValue?: YawPitchControlOptions[K]) {\n // Getter\n if (!key) {\n return this._getOptions();\n } else if (key && typeof key === \"string\" && typeof newValue === \"undefined\") {\n return this._getOptions(key);\n }\n\n // Setter\n let newOptions: Partial = {};\n let changedKeyList: string[] = []; // TODO: if value is not changed, then do not push on changedKeyList.\n\n if (typeof key === \"string\") {\n changedKeyList.push(key);\n newOptions[key] = newValue;\n } else {\n const options = key; // Retrieving object here\n changedKeyList = Object.keys(options);\n newOptions = {...options};\n }\n\n this._setOptions(this._getValidatedOptions(newOptions));\n this._applyOptions(changedKeyList);\n return this;\n }\n\n /**\n * Enable YawPitch functionality\n * @method eg.YawPitch#enable\n */\n public enable() {\n if (this._enabled) {\n return this;\n }\n\n this._enabled = true;\n\n // touchDirection is decided by parameter is valid string (Ref. Axes.connect)\n this._applyOptions(Object.keys(this.options));\n\n // TODO: Is this code is needed? Check later.\n this.updatePanScale();\n\n return this;\n }\n\n /**\n * Disable YawPitch functionality\n * @method eg.YawPitch#disable\n */\n public disable(persistOrientation: boolean = false) {\n if (!this._enabled) {\n return this;\n }\n\n // TODO: Check peristOrientation is needed!\n if (!persistOrientation) {\n this._resetOrientation();\n }\n this._axes.disconnect();\n this._enabled = false;\n return this;\n }\n\n /**\n * Set one or more of yaw, pitch, fov\n * @param {Object} coordinate yaw, pitch, fov\n * @param {Number} duration Animation duration. if it is above 0 then it's animated.\n */\n public lookAt({yaw, pitch, fov}, duration) {\n const pos = this._axes.get();\n\n const y = yaw === undefined ? 0 : yaw - pos.yaw;\n const p = pitch === undefined ? 0 : pitch - pos.pitch;\n const f = fov === undefined ? 0 : fov - pos.fov;\n\n // Allow duration of animation to have more than MC_MAXIMUM_DURATION.\n this._axes.options.maximumDuration = Infinity;\n\n this._axes.setBy({\n yaw: y,\n pitch: p,\n fov: f\n }, duration);\n }\n\n public getYawPitch() {\n const yawPitch = this._axes.get();\n\n return {\n yaw: yawPitch.yaw,\n pitch: yawPitch.pitch\n };\n }\n\n public getFov() {\n return this._axes.get().fov;\n }\n\n public getQuaternion() {\n const pos = this._axes.get();\n\n return this._deviceQuaternion!.getCombinedQuaternion(pos.yaw);\n }\n\n public shouldRenderWithQuaternion() {\n return this.options.gyroMode === GYRO_MODE.VR;\n }\n\n /**\n * Destroys objects\n */\n public destroy() {\n /* eslint-disable @typescript-eslint/no-unused-expressions */\n this._axes && this._axes.destroy();\n this._axesPanInput && this._axesPanInput.destroy();\n this._axesWheelInput && this._axesWheelInput.destroy();\n this._axesTiltMotionInput && this._axesTiltMotionInput.destroy();\n this._axesPinchInput && this._axesPinchInput.destroy();\n this._axesMoveKeyInput && this._axesMoveKeyInput.destroy();\n this._deviceQuaternion && this._deviceQuaternion.destroy();\n /* eslint-enable @typescript-eslint/no-unused-expressions */\n }\n\n private _initAxes(opt: YawPitchControlOptions) {\n const yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio);\n const pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint);\n const useRotation = opt.gyroMode === GYRO_MODE.VR;\n\n this._axesPanInput = new RotationPanInput(this._element!, {useRotation});\n this._axesWheelInput = new WheelInput(this._element, {scale: -4});\n this._axesTiltMotionInput = null;\n this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, {scale: -1}) : null;\n this._axesMoveKeyInput = new MoveKeyInput(this._element, {scale: [-6, 6]});\n\n this._axes = new Axes({\n yaw: {\n range: yRange,\n circular: this._isCircular(yRange),\n bounce: [0, 0]\n },\n pitch: {\n range: pRange,\n circular: this._isCircular(pRange),\n bounce: [0, 0]\n },\n fov: {\n range: opt.fovRange,\n circular: [false, false],\n bounce: [0, 0]\n }\n }, {\n deceleration: MC_DECELERATION,\n maximumDuration: MC_MAXIMUM_DURATION\n }, {\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }).on({\n // TODO: change event type after Axes event type inference update\n hold: (evt: any) => {\n // Restore maximumDuration not to be spin too mush.\n this._axes.options.maximumDuration = MC_MAXIMUM_DURATION;\n\n this.trigger(new ComponentEvent(\"hold\", { isTrusted: evt.isTrusted }));\n },\n change: (evt: any) => {\n if (evt.delta.fov !== 0) {\n this._updateControlScale(evt);\n this.updatePanScale();\n }\n this._triggerChange(evt);\n },\n release: evt => {\n this._triggerChange(evt);\n },\n animationEnd: (evt: any) => {\n this.trigger(new ComponentEvent(\"animationEnd\", { isTrusted: evt.isTrusted }));\n }\n });\n }\n\n private _getValidatedOptions(newOptions: Partial) {\n if (newOptions.yawRange) {\n newOptions.yawRange =\n this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio);\n }\n if (newOptions.pitchRange) {\n newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov);\n }\n return newOptions;\n }\n\n private _getOptions(): YawPitchControlOptions;\n private _getOptions(key: K): YawPitchControlOptions[K];\n private _getOptions(key?: K) {\n let value;\n\n if (typeof key === \"string\") {\n value = this.options[key];\n } else if (arguments.length === 0) {\n value = this.options;\n }\n return value;\n }\n\n private _setOptions(options: Partial): void {\n for (const key in options) {\n this.options[key] = options[key];\n }\n }\n\n private _applyOptions(keys: string[]) {\n const options = this.options;\n const axes = this._axes;\n const isVR = options.gyroMode === GYRO_MODE.VR;\n const isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH;\n // If it's VR mode, restrict user interaction to yaw direction only\n const touchDirection = isVR ?\n (TOUCH_DIRECTION_YAW & options.touchDirection) :\n options.touchDirection;\n\n // If one of below is changed, call updateControlScale()\n if (keys.some(key =>\n key === \"showPolePoint\" || key === \"fov\" || key === \"aspectRatio\" ||\n key === \"yawRange\" || key === \"pitchRange\"\n )) {\n // If fov is changed, update pan scale\n if (keys.indexOf(\"fov\") >= 0) {\n axes.setTo({\"fov\": options.fov});\n this.updatePanScale();\n }\n\n this._updateControlScale();\n }\n\n if (keys.some(key => key === \"fovRange\")) {\n const fovRange = options.fovRange;\n const prevFov = axes.get().fov;\n let nextFov = axes.get().fov;\n\n vec2.copy(axes.axis.fov.range as vec2, fovRange as vec2);\n\n if (nextFov < fovRange[0]) {\n nextFov = fovRange[0];\n } else if (prevFov > fovRange[1]) {\n nextFov = fovRange[1];\n }\n\n if (prevFov !== nextFov) {\n axes.setTo({\n fov: nextFov\n }, 0);\n this._updateControlScale();\n this.updatePanScale();\n }\n }\n\n if (keys.some(key => key === \"gyroMode\") && SUPPORT_DEVICEMOTION) {\n // Disconnect first\n if (this._axesTiltMotionInput) {\n this._axes.disconnect(this._axesTiltMotionInput);\n this._axesTiltMotionInput.destroy();\n this._axesTiltMotionInput = null;\n }\n\n if (this._deviceQuaternion) {\n this._deviceQuaternion.destroy();\n this._deviceQuaternion = null;\n }\n\n if (isVR) {\n this._initDeviceQuaternion();\n } else if (isYawPitch) {\n this._axesTiltMotionInput = new TiltMotionInput(this._element!);\n this._axes.connect([\"yaw\", \"pitch\"], this._axesTiltMotionInput);\n }\n\n this._axesPanInput.setUseRotation(isVR);\n }\n\n if (keys.some(key => key === \"useKeyboard\")) {\n const useKeyboard = options.useKeyboard;\n\n if (useKeyboard) {\n axes.connect([\"yaw\", \"pitch\"], this._axesMoveKeyInput);\n } else {\n axes.disconnect(this._axesMoveKeyInput);\n }\n }\n\n if (keys.some(key => key === \"useZoom\")) {\n const useZoom = options.useZoom;\n\n // Disconnect first\n axes.disconnect(this._axesWheelInput);\n if (useZoom) {\n axes.connect([\"fov\"], this._axesWheelInput);\n }\n }\n\n this._togglePinchInputByOption(options.touchDirection, options.useZoom);\n\n if (keys.some(key => key === \"touchDirection\") && this._enabled) {\n this._enableTouch(touchDirection);\n }\n }\n\n private _togglePinchInputByOption(touchDirection: YawPitchControlOptions[\"touchDirection\"], useZoom: boolean) {\n if (this._axesPinchInput) {\n // disconnect first\n this._axes.disconnect(this._axesPinchInput);\n\n // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll.\n if (\n useZoom &&\n touchDirection === TOUCH_DIRECTION_ALL &&\n // TODO: Get rid of using private property of axes instance.\n (this._axes as any)._inputs.indexOf(this._axesPinchInput) === -1\n ) {\n this._axes.connect([\"fov\"], this._axesPinchInput);\n }\n }\n }\n\n private _enableTouch(direction: YawPitchControlOptions[\"touchDirection\"]) {\n // Disconnect first\n if (this._axesPanInput) {\n this._axes.disconnect(this._axesPanInput);\n }\n\n const yawEnabled = direction & TOUCH_DIRECTION_YAW ? \"yaw\" : null;\n const pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? \"pitch\" : null;\n\n this._axes.connect([yawEnabled, pitchEnabled] as string[], this._axesPanInput);\n }\n\n private _initDeviceQuaternion() {\n this._deviceQuaternion = new DeviceQuaternion();\n this._deviceQuaternion.on(\"change\", e => {\n this._triggerChange(e);\n });\n }\n\n private _getValidYawRange(newYawRange: number[], newFov?: number, newAspectRatio?: number) {\n const ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1);\n const fov = newFov || this._axes.get().fov;\n const horizontalFov = fov * ratio;\n const isValid = newYawRange[1] - newYawRange[0] >= horizontalFov;\n\n if (isValid) {\n return newYawRange;\n } else {\n return this.options.yawRange || DEFAULT_YAW_RANGE;\n }\n }\n\n private _getValidPitchRange(newPitchRange: number[], newFov?: number) {\n const fov = newFov || this._axes.get().fov;\n const isValid = newPitchRange[1] - newPitchRange[0] >= fov;\n\n if (isValid) {\n return newPitchRange;\n } else {\n return this.options.pitchRange || DEFAULT_PITCH_RANGE;\n }\n }\n\n private _isCircular(range: number[]) {\n return range[1] - range[0] < 360 ? [false, false] : [true, true];\n }\n\n /**\n * Update yaw/pitch min/max by 5 factor\n *\n * 1. showPolePoint\n * 2. fov\n * 3. yawRange\n * 4. pitchRange\n * 5. aspectRatio\n *\n * If one of above is changed, call this function\n */\n private _updateControlScale(changeEvt?: any) { // TODO: Change type after Axes type inference update\n const opt = this.options;\n const fov = this._axes.get().fov;\n\n const pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint);\n const yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio);\n\n // TODO: If not changed!?\n const pos = this._axes.get();\n let y = pos.yaw;\n let p = pos.pitch;\n\n vec2.copy(this._axes.axis.yaw.range as any, yRange as any);\n vec2.copy(this._axes.axis.pitch.range as any, pRange as any);\n this._axes.axis.yaw.circular = this._isCircular(yRange);\n this._axes.axis.pitch.circular = this._isCircular(pRange);\n\n /**\n * update yaw/pitch by it's range.\n */\n if (y < yRange[0]) {\n y = yRange[0];\n } else if (y > yRange[1]) {\n y = yRange[1];\n }\n\n if (p < pRange[0]) {\n p = pRange[0];\n } else if (p > pRange[1]) {\n p = pRange[1];\n }\n\n if (changeEvt) {\n changeEvt.set({\n yaw: y,\n pitch: p\n });\n }\n\n this._axes.setTo({\n yaw: y,\n pitch: p\n }, 0);\n\n return this;\n }\n\n private _updatePitchRange(pitchRange: number[], fov: number, showPolePoint: boolean) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n // Circular pitch on VR\n return CIRCULAR_PITCH_RANGE;\n }\n\n const verticalAngle = pitchRange[1] - pitchRange[0];\n const halfFov = fov / 2;\n const isPanorama = verticalAngle < 180;\n\n if (showPolePoint && !isPanorama) {\n // Use full pinch range\n return pitchRange.concat();\n }\n\n // Round value as movableCood do.\n return [pitchRange[0] + halfFov, pitchRange[1] - halfFov];\n }\n\n private _updateYawRange(yawRange: number[], fov: number, aspectRatio: number) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n return DEFAULT_YAW_RANGE;\n }\n\n const horizontalAngle = yawRange[1] - yawRange[0];\n\n /**\n * Full 360 Mode\n */\n if (horizontalAngle >= 360) {\n // Don't limit yaw range on Full 360 mode.\n return yawRange.concat();\n }\n\n /**\n * Panorama mode\n */\n // Ref : https://github.com/naver/egjs-view360/issues/290\n const halfHorizontalFov =\n mathUtil.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))) as number;\n\n // Round value as movableCood do.\n return [\n yawRange[0] + halfHorizontalFov,\n yawRange[1] - halfHorizontalFov\n ];\n }\n\n // TODO: update param type after Axes event type inference update\n private _triggerChange(evt: any) {\n const pos = this._axes.get();\n const opt = this.options;\n const event: YawPitchControlEvents[\"change\"] extends ComponentEvent ? T : never = {\n targetElement: opt.element as HTMLElement,\n isTrusted: evt.isTrusted,\n yaw: pos.yaw,\n pitch: pos.pitch,\n fov: pos.fov,\n quaternion: null\n };\n\n if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) {\n event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw);\n }\n\n this.trigger(new ComponentEvent(\"change\", event));\n }\n\n // TODO: makes constant to be logic\n private _adjustAspectRatio(input: number) {\n const inputRange = [\n 0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670,\n 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19,\n 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26,\n 2.30, 2.60, 3.00, 5.00, 6.00\n ];\n const outputRange = [\n 0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710,\n 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15,\n 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72,\n 1.82, 1.92, 2.00, 2.24, 2.30\n ];\n\n let rangeIdx = -1;\n\n for (let i = 0; i < inputRange.length - 1; i++) {\n if (inputRange[i] <= input && inputRange[i + 1] >= input) {\n rangeIdx = i;\n break;\n }\n }\n\n if (rangeIdx === -1) {\n if (inputRange[0] > input) {\n return outputRange[0];\n } else {\n // FIXME: this looks definitely wrong\n return outputRange[(outputRange[0] as any).length - 1];\n }\n }\n\n const inputA = inputRange[rangeIdx];\n const inputB = inputRange[rangeIdx + 1];\n const outputA = outputRange[rangeIdx];\n const outputB = outputRange[rangeIdx + 1];\n\n return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA));\n }\n\n private _lerp(a: number, b: number, fraction: number) {\n return a + fraction * (b - a);\n }\n\n private _resetOrientation() {\n const opt = this.options;\n\n this._axes.setTo({\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }, 0);\n\n return this;\n }\n}\n\nexport default YawPitchControl;\n","/**\n * Constant value for gyro mode.
(Reference {@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide})\n * @ko gyro 모드 대한 상수 값.
({@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide} 참고)\n * @namespace\n * @name GYRO_MODE\n * @memberof eg.view360.PanoViewer\n */\n/**\n * Disable gyro\n * @ko gyro 비활성화\n * @name NONE\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"none\"\n */\n/**\n * YawPitch Mode\n * @ko YawPitch Mode\n * @name YAWPITCH\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"yawPitch\"\n */\n/**\n * VR Mode\n * @ko VR Mode\n * @name VR\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"VR\"\n */\nimport { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\nimport { GYRO_MODE } from \"../YawPitchControl/consts\";\n\n/**\n * Constant value for errors\n * @ko 에러에 대한 상수 값\n * @namespace\n * @name ERROR_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst ERROR_TYPE = {\n /**\n * Unsupported device\n * @ko 미지원 기기\n * @name INVALID_DEVICE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 10\n */\n INVALID_DEVICE: 10,\n /**\n * Webgl not support\n * @ko WEBGL 미지원\n * @name NO_WEBGL\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 11\n */\n NO_WEBGL: 11,\n /**\n * Failed to load image\n * @ko 이미지 로드 실패\n * @name FAIL_IMAGE_LOAD\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 12\n */\n FAIL_IMAGE_LOAD: 12,\n /**\n * Failed to bind texture\n * @ko 텍스쳐 바인딩 실패\n * @name FAIL_BIND_TEXTURE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 13\n */\n FAIL_BIND_TEXTURE: 13,\n /**\n * Only one resource(image or video) should be specified\n * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함)\n * @name INVALID_RESOURCE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 14\n */\n INVALID_RESOURCE: 14,\n /**\n * WebGL context lost occurred\n * @ko WebGL context lost 발생\n * @name RENDERING_CONTEXT_LOST\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 15\n */\n RENDERING_CONTEXT_LOST: 15\n};\n\n/**\n * Constant value for events\n * @ko 이벤트에 대한 상수 값\n * @namespace\n * @name EVENTS\n * @memberof eg.view360.PanoViewer\n */\nconst PANOVIEWER_EVENTS: {\n READY: \"ready\";\n VIEW_CHANGE: \"viewChange\";\n ANIMATION_END: \"animationEnd\";\n ERROR: \"error\";\n} = {\n /**\n * Events that is fired when PanoViewer is ready to show image and handle user interaction.\n * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트\n * @name READY\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default ready\n */\n READY: \"ready\",\n /**\n * Events that is fired when direction or fov is changed.\n * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트\n * @name VIEW_CHANGE\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default viewChange\n */\n VIEW_CHANGE: \"viewChange\",\n /**\n * Events that is fired when animation which is triggered by inertia is ended.\n * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트\n * @name ANIMATION_END\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default animationEnd\n */\n ANIMATION_END: \"animationEnd\",\n /**\n * Events that is fired when error occurs\n * @ko 에러 발생 시 발생하는 이벤트\n * @name ERROR\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default error\n */\n ERROR: \"error\"\n};\n\n/**\n * Constant value for projection type\n * @ko 프로젝션 타입 대한 상수 값\n * @namespace\n * @name PROJECTION_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst PROJECTION_TYPE: {\n EQUIRECTANGULAR: \"equirectangular\";\n CUBEMAP: \"cubemap\";\n CUBESTRIP: \"cubestrip\";\n PANORAMA: \"panorama\";\n STEREOSCOPIC_EQUI: \"stereoequi\";\n} = {\n /**\n * Constant value for equirectangular type.\n * @ko equirectangular 에 대한 상수 값.\n * @name EQUIRECTANGULAR\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default equirectangular\n */\n EQUIRECTANGULAR: \"equirectangular\",\n /**\n * Constant value for cubemap type.\n * @ko cubemap 에 대한 상수 값.\n * @name CUBEMAP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubemap\n */\n CUBEMAP: \"cubemap\",\n /**\n * Constant value for cubestrip type.\n * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC.\n * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다.\n * @name CUBESTRIP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubestrip\n */\n CUBESTRIP: \"cubestrip\",\n /**\n * Constant value for PANORAMA type.\n *\n * PANORAMA is a format for a panorma image which is taken from smartphone.\n * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다.\n *\n * @name PANORAMA\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default panorama\n */\n PANORAMA: \"panorama\",\n /**\n * Constant value for EQUI_STEREOSCOPY type.\n *\n * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present.\n * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다.\n *\n * @name STEREOSCOPIC_EQUI\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default stereoequi\n */\n STEREOSCOPIC_EQUI: \"stereoequi\"\n};\n\n/**\n * A constant value for the format of the stereoscopic equirectangular projection type.\n * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값\n * @namespace\n * @name STEREO_FORMAT\n * @memberof eg.view360.PanoViewer\n */\nconst STEREO_FORMAT: {\n TOP_BOTTOM: \"3dv\";\n LEFT_RIGHT: \"3dh\";\n NONE: \"\";\n} = {\n /**\n * A constant value for format of top bottom stereoscopic 360 equirectangular projection.\n * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name TOP_BOTTOM\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dv\"\n */\n TOP_BOTTOM: \"3dv\",\n /**\n * A constant value for format of left right stereoscopic 360 equirectangular projection.\n * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name LEFT_RIGHT\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dh\"\n */\n LEFT_RIGHT: \"3dh\",\n /**\n * A constant value specifying media is not in stereoscopic format.\n * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"\"\n */\n NONE: \"\"\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst PANOVIEWER_OPTIONS: { [key in keyof PanoViewerOptions]: true } = {\n image: true,\n video: true,\n projectionType: true,\n cubemapConfig: true,\n stereoFormat: true,\n width: true,\n height: true,\n yaw: true,\n pitch: true,\n fov: true,\n showPolePoint: true,\n useZoom: true,\n useKeyboard: true,\n gyroMode: true,\n yawRange: true,\n pitchRange: true,\n fovRange: true,\n touchDirection: true,\n canvasClass: true\n};\n\nconst DEFAULT_CANVAS_CLASS = \"view360-canvas\";\n\nexport {\n GYRO_MODE,\n PANOVIEWER_EVENTS,\n ERROR_TYPE,\n PROJECTION_TYPE,\n STEREO_FORMAT,\n PANOVIEWER_OPTIONS,\n DEFAULT_CANVAS_CLASS\n};\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","import agent from \"@egjs/agent\";\n\nimport { TypedArray } from \"../types/internal\";\n\nconst WEBGL_ERROR_CODE = {\n \"0\": \"NO_ERROR\",\n \"1280\": \"INVALID_ENUM\",\n \"1281\": \"INVALID_VALUE\",\n \"1282\": \"INVALID_OPERATION\",\n \"1285\": \"OUT_OF_MEMORY\",\n \"1286\": \"INVALID_FRAMEBUFFER_OPERATION\",\n \"37442\": \"CONTEXT_LOST_WEBGL\"\n};\n\nlet webglAvailability: boolean | null = null;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet MAX_TEXTURE_SIZE_FOR_TEST: number | null = null;\n\nexport default class WebGLUtils {\n public static createShader(gl: WebGLRenderingContext, type: number, source: string) {\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (success) {\n return shader;\n }\n\n // eslint-disable-next-line\n console.error(gl.getShaderInfoLog(shader));\n\n return null;\n }\n\n public static createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = gl.createProgram()!;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (success) {\n return program;\n }\n\n gl.deleteProgram(program);\n return null;\n }\n\n public static initBuffer(gl: WebGLRenderingContext, target: number /* bind point */, data: TypedArray, itemSize: number, attr?: number) {\n const buffer = gl.createBuffer()!;\n\n gl.bindBuffer(target, buffer);\n gl.bufferData(target, data, gl.STATIC_DRAW);\n\n if (buffer) {\n (buffer as any).itemSize = itemSize;\n (buffer as any).numItems = data.length / itemSize;\n }\n\n if (attr !== undefined) {\n gl.enableVertexAttribArray(attr);\n gl.vertexAttribPointer(attr, (buffer as any).itemSize, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n }\n\n public static getWebglContext(canvas: HTMLCanvasElement, userContextAttributes?: WebGLContextAttributes) {\n const webglIdentifiers = [\"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n const contextAttributes = {\n ...{\n preserveDrawingBuffer: false,\n antialias: false\n }, ...userContextAttributes\n };\n\n const onWebglcontextcreationerror = e => e.statusMessage;\n\n canvas.addEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n return context;\n }\n\n public static createTexture(gl: WebGLRenderingContext, textureTarget: number) {\n const texture = gl.createTexture();\n\n gl.bindTexture(textureTarget, texture);\n gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(textureTarget, null);\n\n return texture;\n }\n\n /**\n * Returns the webgl availability of the current browser.\n * @method WebGLUtils#isWebGLAvailable\n * @retuen {Boolean} isWebGLAvailable\n */\n public static isWebGLAvailable(): boolean {\n if (webglAvailability === null) {\n const canvas = document.createElement(\"canvas\");\n const webglContext = WebGLUtils.getWebglContext(canvas);\n\n webglAvailability = !!webglContext;\n\n // webglContext Resource forced collection\n if (webglContext) {\n const loseContextExtension = webglContext.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n return !!webglAvailability;\n }\n\n /**\n * Returns whether webgl is stable in the current browser.\n * @method WebGLUtils#isStableWebGL\n * @retuen {Boolean} isStableWebGL\n */\n public static isStableWebGL() {\n const agentInfo = agent();\n let isStableWebgl = true;\n\n if (agentInfo.os.name === \"android\") {\n const version = parseFloat(agentInfo.os.version);\n\n if (version <= 4.3 && version >= 1) {\n isStableWebgl = false;\n } else if (version === 4.4) {\n if (agentInfo.browser.name !== \"chrome\") {\n isStableWebgl = false;\n }\n }\n }\n return isStableWebgl;\n }\n\n public static getErrorNameFromWebGLErrorCode(code: number | string) {\n if (!(code in WEBGL_ERROR_CODE)) {\n return \"UNKNOWN_ERROR\";\n }\n\n return WEBGL_ERROR_CODE[code];\n }\n\n\n /**\n * This function is wrapper for texImage2D to handle exceptions on texImage2D.\n * Purpose is to prevent service from being stopped by script error.\n */\n public static texImage2D(gl: WebGLRenderingContext, target: number, pixels: TexImageSource) {\n try {\n gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n } catch (error) {\n /* eslint-disable no-console */\n console.error(\"WebGLUtils.texImage2D error:\", error);\n /* eslint-enable no-console */\n }\n }\n\n public static getMaxTextureSize(gl: WebGLRenderingContext) {\n // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test\n return MAX_TEXTURE_SIZE_FOR_TEST || gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n}\n\n/**\n * This function should not be used in service code. It's provided only for test purpose.\n * It should be set to null or 0 when test is done.\n * @param {Number} size\n */\nconst setMaxTextureSizeForTestOnlyPurpose = (size: number) => {\n MAX_TEXTURE_SIZE_FOR_TEST = size;\n};\n\nexport {\n setMaxTextureSizeForTestOnlyPurpose\n};\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport agent from \"@egjs/agent\";\nimport { mat4 } from \"gl-matrix\";\n\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nconst agentInfo = agent();\nconst isIE11 = agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11;\n\nconst EVENTS: {\n ERROR: \"error\";\n} = {\n ERROR: \"error\"\n};\n\n/**\n *\n * Extends Component for firing errors occurs internally.\n */\nabstract class Renderer extends Component<{\n [EVENTS.ERROR]: {\n message: string;\n };\n}> {\n public static EVENTS = EVENTS;\n\n private _forceDimension: { width: number; height: number } | null;\n private _pixelCanvas: HTMLCanvasElement | null;\n private _pixelContext: CanvasRenderingContext2D | null;\n\n public constructor() {\n super();\n\n this._forceDimension = null;\n this._pixelCanvas = null;\n this._pixelContext = null;\n }\n\n public abstract getVertexPositionData(): number[];\n public abstract getIndexData(): number[];\n public abstract getTextureCoordData(textureData: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }): number[];\n\n public abstract getVertexShaderSource(): string;\n public abstract getFragmentShaderSource(): string;\n public abstract bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n public abstract updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n\n public render({ gl, shaderProgram, indexBuffer, mvMatrix, pMatrix }: {\n gl: WebGLRenderingContext;\n shaderProgram: WebGLProgram;\n indexBuffer: WebGLBuffer;\n mvMatrix: mat4;\n pMatrix: mat4;\n }) {\n gl.uniformMatrix4fv((shaderProgram as any).pMatrixUniform, false, pMatrix);\n gl.uniformMatrix4fv((shaderProgram as any).mvMatrixUniform, false, mvMatrix);\n\n if (indexBuffer) {\n gl.drawElements(gl.TRIANGLES, (indexBuffer as any).numItems, gl.UNSIGNED_SHORT, 0);\n }\n }\n\n // Define interface for Renderers\n /**\n * Following MUST BE DEFINED on Child of Renderer\n *\n * DATA\n *\n * - getVertexPositionData\n * - getIndexData\n * - getTextureCoordData\n *\n * SOURCE\n *\n * - getVertexShaderSource\n * - getFragmentShaderSource\n *\n * TEXTURE\n *\n * - bindTexture\n */\n public getDimension(pixelSource: HTMLImageElement | HTMLVideoElement) {\n const width = (pixelSource as HTMLImageElement).naturalWidth\n || (pixelSource as HTMLVideoElement).videoWidth;\n const height = (pixelSource as HTMLImageElement).naturalHeight\n || (pixelSource as HTMLVideoElement).videoHeight;\n\n return { width, height };\n }\n\n /**\n * Update data used by shader\n */\n public updateShaderData(param) { // eslint-disable-line @typescript-eslint/no-unused-vars\n /*\n * Update following data in implementation layer.\n * If the data is not changed, it does not need to implement this function.\n *\n * - _VERTEX_POSITION_DATA\n * - _TEXTURE_COORD_DATA\n * - _INDEX_DATA\n */\n }\n\n /**\n *\n * @param {HTMLImageElement | HTMLVideoElement} image\n * @param {Object = {width, height}} forceDimension Forced dimension to resize\n */\n protected _initPixelSource(image: HTMLImageElement | HTMLVideoElement, forceDimension: Renderer[\"_forceDimension\"] = null) {\n const isIE11Video = isIE11 && (image instanceof HTMLVideoElement);\n\n if (isIE11Video || forceDimension) {\n const {width, height} = forceDimension || this.getDimension(image);\n\n this._pixelCanvas = document.createElement(\"canvas\");\n this._pixelCanvas.width = width;\n this._pixelCanvas.height = height;\n this._pixelContext = this._pixelCanvas.getContext(\"2d\");\n }\n this._forceDimension = forceDimension;\n }\n\n protected _getPixelSource(image: HTMLImageElement | HTMLVideoElement) {\n if (!this._pixelCanvas) {\n return image;\n }\n\n /**\n * IE11 && Video\n * or\n * Dimension is forced (Image is larger than texture size.)\n */\n const contentDimension = this.getDimension(image);\n const textureDimension = this._forceDimension || contentDimension;\n\n if (this._pixelCanvas.width !== textureDimension.width) {\n this._pixelCanvas.width = textureDimension.width;\n }\n\n if (this._pixelCanvas.height !== textureDimension.height) {\n this._pixelCanvas.height = textureDimension.height;\n }\n\n if (this._forceDimension) {\n this._pixelContext!.drawImage(image,\n 0, 0, contentDimension.width, contentDimension.height,\n 0, 0, textureDimension.width, textureDimension.height);\n } else {\n this._pixelContext!.drawImage(image, 0, 0);\n }\n\n return this._pixelCanvas;\n }\n\n protected _extractTileConfig(imageConfig: CubemapConfig) {\n let tileConfig: TileConfig[] =\n Array.isArray(imageConfig.tileConfig) ?\n imageConfig.tileConfig : Array(...Array(6)).map(() => imageConfig.tileConfig) as TileConfig[];\n\n tileConfig = tileConfig.map(\n config => ({\n ...{\n flipHorizontal: false,\n rotation: 0\n }, ...config\n })\n );\n\n return tileConfig;\n }\n\n protected _triggerError(error) {\n /* eslint-disable no-console */\n console.error(\"Renderer Error:\", error);\n /* eslint-enable no-console */\n\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n message: typeof error === \"string\" ? error : error.message\n }));\n }\n}\n\nexport default Renderer;\n","import agent from \"@egjs/agent\";\n\nimport WebGLUtils from \"../WebGLUtils\";\nimport { util as mathUtil } from \"../../utils/math-util\";\nimport { CubemapConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nclass CubeRenderer extends Renderer {\n public static extractOrder(imageConfig: CubemapConfig) {\n return imageConfig.order || \"RLUDBF\";\n }\n\n private static _VERTEX_POSITION_DATA: number[] | null = null;\n private static _INDEX_DATA: number[] | null = null;\n\n public getVertexPositionData() {\n CubeRenderer._VERTEX_POSITION_DATA =\n CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // top\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // bottom\n 1, -1, -1,\n -1, -1, -1,\n -1, -1, 1,\n 1, -1, 1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n return CubeRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n if (CubeRenderer._INDEX_DATA) {\n return CubeRenderer._INDEX_DATA;\n }\n\n const indexData: number[] = [];\n const vertexPositionData = this.getVertexPositionData();\n\n for (let i = 0; i < (vertexPositionData.length / 3); i += 4) {\n indexData.push(\n i,\n i + 2,\n i + 1,\n i,\n i + 3,\n i + 2\n );\n }\n\n CubeRenderer._INDEX_DATA = indexData;\n return indexData;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n const vertexOrder = \"BFUDRL\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const base = this.getVertexPositionData();\n const tileConfig = this._extractTileConfig(imageConfig);\n const elemSize = 3;\n const vertexPerTile = 4;\n const { trim } = imageConfig;\n\n const texCoords = vertexOrder.split(\"\")\n .map(face => tileConfig[order.indexOf(face)])\n .map((config, i) => {\n const rotation = Math.floor(config.rotation / 90);\n const ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2];\n\n for (let r = 0; r < Math.abs(rotation); r++) {\n if ((config.flipHorizontal && rotation > 0) ||\n (!config.flipHorizontal && rotation < 0)) {\n ordermap.push(ordermap.shift()!);\n } else {\n ordermap.unshift(ordermap.pop()!);\n }\n }\n\n const elemPerTile = elemSize * vertexPerTile;\n const tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile);\n const tileTemp: number[][] = [];\n\n for (let j = 0; j < vertexPerTile; j++) {\n tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize);\n }\n return tileTemp;\n })\n .map(coord => this._shrinkCoord({ image, faceCoords: coord, trim }))\n .reduce((acc: number[], val: number[][]) => [\n ...acc,\n ...val.reduce((coords, coord) => [...coords, ...coord], [])\n ], []);\n\n return texCoords;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n const baseOrder = \"RLUDBF\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const orderMap = {};\n\n order.split(\"\").forEach((v, i) => {\n orderMap[v] = i;\n });\n\n try {\n if (image instanceof Array) {\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]);\n }\n } else {\n const maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image);\n\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n const tile = this.extractTileFromImage(\n image, tileIdx, maxCubeMapTextureSize\n );\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile);\n }\n }\n } catch (e) {\n this._triggerError(e);\n }\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n this.updateTexture(gl, image, imageConfig);\n }\n\n public getSourceTileSize(image: HTMLImageElement | HTMLVideoElement) {\n const {width, height} = this.getDimension(image);\n const aspectRatio = width / height;\n let inputTextureSize;\n\n if (aspectRatio === 1 / 6) {\n inputTextureSize = width;\n } else if (aspectRatio === 6) {\n inputTextureSize = height;\n } else if (aspectRatio === 2 / 3) {\n inputTextureSize = width / 2;\n } else {\n inputTextureSize = width / 3;\n }\n return inputTextureSize;\n }\n\n public extractTileFromImage(image: HTMLImageElement | HTMLVideoElement, tileIdx: number, outputTextureSize: number) {\n const {width} = this.getDimension(image);\n const inputTextureSize = this.getSourceTileSize(image);\n\n const canvas = document.createElement(\"canvas\");\n\n canvas.width = outputTextureSize;\n canvas.height = outputTextureSize;\n const context = canvas.getContext(\"2d\");\n const tilePerRow = width / inputTextureSize;\n\n const x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow);\n const y = Math.floor(tileIdx / tilePerRow) * (inputTextureSize);\n\n context!.drawImage(\n image, x, y,\n inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize\n );\n return canvas;\n }\n\n public getMaxCubeMapTextureSize(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n const agentInfo = agent();\n const maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n let imageWidth = this.getSourceTileSize(image);\n\n if (agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11) {\n if (!mathUtil.isPowerOfTwo(imageWidth)) {\n for (let i = 1; i < maxCubeMapTextureSize; i *= 2) {\n if (i < imageWidth) {\n continue;\n } else {\n imageWidth = i;\n break;\n }\n }\n }\n }\n if (agentInfo.os.name === \"ios\") {\n const majorVersion = agentInfo.os.majorVersion;\n\n // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다.\n if (majorVersion === 9) {\n imageWidth = 1024;\n }\n // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다.\n if (majorVersion === 8) {\n imageWidth = 512;\n }\n }\n // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수\n return Math.min(maxCubeMapTextureSize, imageWidth);\n }\n\n private _shrinkCoord(coordData: {\n image: HTMLImageElement | HTMLVideoElement;\n faceCoords: number[][];\n trim: number;\n }) {\n const { image, faceCoords, trim } = coordData;\n\n const inputTextureSize = Array.isArray(image)\n ? this.getDimension(image[0]).width\n : this.getSourceTileSize(image);\n\n // Shrink by \"trim\" px\n const SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize);\n\n const axisMultipliers = [0, 1, 2].map(axisIndex => {\n const axisDir = mathUtil.sign(faceCoords[0][axisIndex]);\n const notSameDir = faceCoords.some(coord => mathUtil.sign(coord[axisIndex]) !== axisDir);\n\n return notSameDir;\n }).map(notSameDir => notSameDir ? SHRINK_MULTIPLIER : 1);\n\n return faceCoords.map(coords => coords.map((coord, axisIndex) => coord * axisMultipliers[axisIndex]));\n }\n}\n\nexport default CubeRenderer;\n","\nimport WebGLUtils from \"../WebGLUtils\";\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nexport default class CubeStripRenderer extends Renderer {\n private _vertices: number[];\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}`;\n }\n\n public getVertexPositionData() {\n if (!this._vertices) {\n this._vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n }\n\n return this._vertices;\n }\n\n public getIndexData() {\n // TODO: 한번만 계산하도록 수정하기\n const indices = (() => {\n const indexData: number[] = [];\n\n for (let i = 0; i < (this._vertices.length / 3); i += 4) {\n indexData.push(\n i,\n i + 1,\n i + 2,\n i,\n i + 2,\n i + 3\n );\n }\n return indexData;\n })();\n\n return indices;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n // TODO: make it cols, rows as config.\n const cols = 3;\n const rows = 2;\n\n const textureSize = this.getDimension(image);\n const { trim } = imageConfig;\n\n const order = imageConfig.order || \"RLUDFB\";\n let coords: number[][] = [];\n\n // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다.\n for (let r = rows - 1; r >= 0; r--) {\n for (let c = 0; c < cols; c++) {\n const coord = [\n c / cols, r / rows,\n (c + 1) / cols, r / rows,\n (c + 1) / cols, (r + 1) / rows,\n c / cols, (r + 1) / rows\n ];\n\n coords.push(coord);\n }\n }\n\n const tileConfigs = this._extractTileConfig(imageConfig);\n\n // Transform Coord By Flip & Rotation\n coords = coords\n // shrink coord to avoid pixel bleeding\n .map(coord => this._shrinkCoord(coord, textureSize, trim))\n .map((coord, i) => this._transformCoord(coord, tileConfigs[i]));\n\n // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치\n return \"BFUDRL\".split(\"\")\n .map(face => order.indexOf(face))\n .map(index => coords[index])\n .reduce((acc, val) => acc.concat(val), []);\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n private _transformCoord(coord: number[], tileConfig: TileConfig) {\n let newCoord = coord.slice();\n\n if (tileConfig.flipHorizontal) {\n newCoord = this._flipHorizontalCoord(newCoord);\n }\n\n if (tileConfig.rotation) {\n newCoord = this._rotateCoord(newCoord, tileConfig.rotation);\n }\n\n return newCoord;\n }\n\n private _shrinkCoord(coord: number[], textureSize: { width: number; height: number }, trim: number) {\n const { width, height } = textureSize;\n\n // Shrink by \"trim\" px\n const SHRINK_Y = trim * (1 / height);\n const SHRINK_X = trim * (1 / width);\n\n return [\n coord[0] + SHRINK_X, coord[1] + SHRINK_Y,\n coord[2] - SHRINK_X, coord[3] + SHRINK_Y,\n coord[4] - SHRINK_X, coord[5] - SHRINK_Y,\n coord[6] + SHRINK_X, coord[7] - SHRINK_Y\n ];\n }\n\n private _rotateCoord(coord: number[], rotationAngle: number) {\n const SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord.\n const shiftCount = Math.floor(rotationAngle / 90) % 4;\n\n if (shiftCount === 0) {\n return coord;\n }\n\n let moved;\n let rotatedCoord: number[] = [];\n\n if (shiftCount > 0) {\n moved = coord.splice(0, shiftCount * SIZE);\n rotatedCoord = coord.concat(moved);\n } else {\n moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE);\n rotatedCoord = moved.concat(coord);\n }\n\n return rotatedCoord;\n }\n\n private _flipHorizontalCoord(coord: number[]) {\n return [\n coord[2], coord[3],\n coord[0], coord[1],\n coord[6], coord[7],\n coord[4], coord[5]\n ];\n }\n}\n","import WebGLUtils from \"../WebGLUtils\";\nimport { STEREO_FORMAT } from \"../../PanoViewer/consts\";\nimport { ValueOf } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nconst latitudeBands = 60;\nconst longitudeBands = 60;\nconst radius = 2;\nconst ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\nlet latIdx: number;\nlet lngIdx: number;\n\nfor (latIdx = 0; latIdx <= latitudeBands; latIdx++) {\n const theta = (latIdx / latitudeBands - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / longitudeBands;\n const v = latIdx / latitudeBands;\n\n textureCoordData.push(u, v);\n vertexPositionData.push(radius * x, radius * y, radius * z);\n\n if (lngIdx !== longitudeBands && latIdx !== latitudeBands) {\n const a = latIdx * (longitudeBands + 1) + lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n}\n\nclass SphereRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n private _stereoFormat: ValueOf;\n\n public constructor(format: SphereRenderer[\"_stereoFormat\"]) {\n super();\n\n this._stereoFormat = format;\n }\n\n public render(ctx: Parameters[0]) {\n const {gl, shaderProgram} = ctx;\n\n let leftEyeScaleOffset: number[];\n let rightEyeScaleOffset: number[];\n\n switch (this._stereoFormat) {\n case STEREO_FORMAT.TOP_BOTTOM:\n leftEyeScaleOffset = [1, 0.5, 0, 0];\n rightEyeScaleOffset = [1, 0.5, 0, 0.5];\n break;\n case STEREO_FORMAT.LEFT_RIGHT:\n leftEyeScaleOffset = [0.5, 1, 0, 0];\n rightEyeScaleOffset = [0.5, 1, 0.5, 0];\n break;\n default:\n leftEyeScaleOffset = [1, 1, 0, 0];\n rightEyeScaleOffset = [1, 1, 0, 0];\n }\n\n const uTexScaleOffset = gl.getUniformLocation(shaderProgram, \"uTexScaleOffset\");\n\n gl.uniform4fv(uTexScaleOffset, [...leftEyeScaleOffset, ...rightEyeScaleOffset]);\n\n super.render(ctx);\n }\n\n public getVertexPositionData() {\n return SphereRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return SphereRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return SphereRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const { width, height } = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n}\n\nexport default SphereRenderer;\n","import { glMatrix } from \"gl-matrix\";\n\nimport WebGLUtils from \"../WebGLUtils\";\n\nimport Renderer from \"./Renderer\";\n\n// const latitudeBands = 60;\nconst MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6;\nconst longitudeBands = 60;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\n\nclass CylinderRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n public getVertexPositionData() {\n return CylinderRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return CylinderRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return CylinderRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n let resizeDimension: { width: number; height: number } | undefined;\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device texture limit(${maxSize}))`);\n\n // Request resizing texture.\n /**\n * TODO: Is it need to apply on another projection type?\n */\n resizeDimension = width > height ?\n {width: maxSize, height: maxSize * height / width} :\n {width: maxSize * width / height, height: maxSize};\n }\n\n // Pixel Source for IE11 & Video or resizing needed\n this._initPixelSource(image, resizeDimension);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n public updateShaderData({ imageAspectRatio = MIN_ASPECT_RATIO_FOR_FULL_PANORAMA }) {\n let lngIdx: number;\n let cylinderMaxRadian: number;\n let halfCylinderY: number;\n let rotated: boolean;\n let aspectRatio: number;\n\n // Exception case: orientation is rotated.\n if (imageAspectRatio < 1) {\n /**\n * If rotated is true, we assume that image is rotated counter clockwise.\n * TODO: If there's other rotation, it is need to implement by each rotation.\n */\n rotated = true;\n aspectRatio = 1 / imageAspectRatio;\n } else {\n rotated = false;\n aspectRatio = imageAspectRatio;\n }\n\n if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) {\n const fov = 360 / aspectRatio;\n\n cylinderMaxRadian = 2 * Math.PI; // 360 deg\n halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2));\n } else {\n cylinderMaxRadian = aspectRatio;\n halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1.\n }\n\n // initialize shader data before update\n textureCoordData.length = 0;\n vertexPositionData.length = 0;\n indexData.length = 0;\n\n const CYLIDER_Y = [-halfCylinderY, halfCylinderY];\n const startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360)\n\n // console.log(\"cylinderMaxRadian:\", glMatrix.toDegree(cylinderMaxRadian), \"CYLIDER_Y\", CYLIDER_Y, \"start angle\", glMatrix.toDegree(startAngleForCenterAlign));\n for (let yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength/* bottom & top */; yIdx++) {\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const angle = startAngleForCenterAlign + (lngIdx / longitudeBands * cylinderMaxRadian);\n const x = Math.cos(angle);\n const y = CYLIDER_Y[yIdx];\n const z = Math.sin(angle);\n let u: number;\n let v: number;\n\n if (rotated) {\n // Rotated 90 degree (counter clock wise)\n u = 1 - yIdx; // yLength - yIdx;\n v = lngIdx / longitudeBands;\n } else {\n // \t// Normal case (Not rotated)\n u = lngIdx / longitudeBands;\n v = yIdx;\n }\n\n textureCoordData.push(u, v);\n vertexPositionData.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < longitudeBands) {\n const a = lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n }\n}\n\nexport default CylinderRenderer;\n","import Promise from \"promise-polyfill\";\nimport { mat4 } from \"gl-matrix\";\n\nconst VR_DISPLAY_PRESENT_CHANGE = \"vrdisplaypresentchange\";\nconst DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1];\nconst DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1];\nconst EYES = {\n LEFT: \"left\",\n RIGHT: \"right\"\n} as const;\n\nclass VRManager {\n private _vrDisplay: VRDisplay | null;\n private _frameData: VRFrameData;\n private _yawOffset: number;\n private _leftBounds: number[];\n private _rightBounds: number[];\n\n public constructor() {\n this._frameData = new window.VRFrameData();\n this._clear();\n }\n\n public get context() { return this._vrDisplay; }\n\n public destroy = () => {\n const vrDisplay = this._vrDisplay;\n\n this.removeEndCallback(this.destroy);\n\n if (vrDisplay && vrDisplay.isPresenting) {\n void vrDisplay.exitPresent();\n }\n\n this._clear();\n };\n\n public canRender() {\n return Boolean(this._vrDisplay);\n }\n\n public beforeRender(gl: WebGLRenderingContext) {\n // Render to the default backbuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public afterRender() {\n this._vrDisplay!.submitFrame();\n }\n\n public getEyeParams(gl: WebGLRenderingContext) {\n const display = this._vrDisplay!;\n const halfWidth = gl.drawingBufferWidth * 0.5;\n const height = gl.drawingBufferHeight;\n const frameData = this._frameData;\n\n display.getFrameData(frameData);\n\n const leftMVMatrix = frameData.leftViewMatrix;\n const rightMVMatrix = frameData.rightViewMatrix;\n\n mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset);\n mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset);\n\n return [\n {\n viewport: [0, 0, halfWidth, height],\n mvMatrix: leftMVMatrix,\n pMatrix: frameData.leftProjectionMatrix\n },\n {\n viewport: [halfWidth, 0, halfWidth, height],\n mvMatrix: rightMVMatrix,\n pMatrix: frameData.rightProjectionMatrix\n }\n ];\n }\n\n public isPresenting() {\n return Boolean(this._vrDisplay && this._vrDisplay.isPresenting);\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public requestPresent(canvas: HTMLCanvasElement) {\n return navigator.getVRDisplays().then(displays => {\n const vrDisplay = displays.length && displays[0];\n\n if (!vrDisplay) {\n return Promise.reject(new Error(\"No displays available.\"));\n }\n if (!vrDisplay.capabilities.canPresent) {\n return Promise.reject(new Error(\"Display lacking capability to present.\"));\n }\n\n return vrDisplay.requestPresent([{source: canvas}]).then(() => {\n const leftEye = vrDisplay.getEyeParameters(EYES.LEFT);\n const rightEye = vrDisplay.getEyeParameters(EYES.RIGHT);\n\n canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;\n canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);\n\n this._setDisplay(vrDisplay);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setDisplay(vrDisplay: VRDisplay) {\n this._vrDisplay = vrDisplay;\n\n const layers = vrDisplay.getLayers();\n\n if (layers.length) {\n const layer = layers[0];\n\n this._leftBounds = layer.leftBounds as number[];\n this._rightBounds = layer.rightBounds as number[];\n }\n\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._vrDisplay = null;\n this._leftBounds = DEFAULT_LEFT_BOUNDS;\n this._rightBounds = DEFAULT_RIGHT_BOUNDS;\n this._yawOffset = 0;\n }\n}\n\nexport default VRManager;\n","import { mat4, glMatrix } from \"gl-matrix\";\nimport { XRFrame, XRLayer, XRReferenceSpace, XRSession, XRSessionInit } from \"webxr\";\n\nimport { IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { merge } from \"../../utils/utils\";\n\nconst XR_REFERENCE_SPACE = \"local\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\nclass XRManager {\n private _xrSession: XRSession | null;\n private _xrLayer: XRLayer | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n private _yawOffset: number;\n private _presenting: boolean;\n\n public constructor(options: XRSessionOptions = {}) {\n this._clear();\n this._options = options;\n }\n\n public get context() { return this._xrSession; }\n\n public destroy = () => {\n const xrSession = this._xrSession;\n\n this.removeEndCallback(this.destroy);\n\n if (xrSession) {\n // Capture to avoid errors\n xrSession.end().then(() => void 0, () => void 0);\n }\n this._clear();\n };\n\n public canRender(frame: XRFrame) {\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n return Boolean(pose);\n }\n\n public beforeRender(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer!.framebuffer);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n public afterRender() {}\n\n public getEyeParams(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) {\n // Can't render\n return null;\n }\n\n const glLayer = session.renderState.baseLayer;\n\n return pose.views.map(view => {\n const viewport = glLayer!.getViewport(view);\n const mvMatrix = view.transform.inverse.matrix;\n\n if (IS_SAFARI_ON_DESKTOP) {\n mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180));\n }\n\n mat4.rotateY(mvMatrix, mvMatrix, this._yawOffset);\n\n return {\n viewport: [viewport.x, viewport.y, viewport.width, viewport.height],\n mvMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n public isPresenting() {\n return this._presenting;\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.addEventListener(\"end\", callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.removeEventListener(\"end\", callback);\n }\n\n public async requestPresent(canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {\n const options = merge({\n requiredFeatures: [XR_REFERENCE_SPACE]\n }, this._options);\n\n const attributes = gl.getContextAttributes();\n if (attributes && (attributes as any).xrCompatible !== true) {\n await (gl as any).makeXRCompatible();\n }\n\n return (navigator as any).xr.requestSession(\"immersive-vr\", options).then(session => {\n const xrLayer = new (window as any).XRWebGLLayer(session, gl);\n\n session.updateRenderState({baseLayer: xrLayer});\n return session.requestReferenceSpace(XR_REFERENCE_SPACE)\n .then(refSpace => {\n this._setSession(session, xrLayer, refSpace);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setSession(session: XRSession, xrLayer: XRLayer, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrLayer = xrLayer;\n this._xrRefSpace = refSpace;\n this._presenting = true;\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._xrSession = null;\n this._xrLayer = null;\n this._xrRefSpace = null;\n this._presenting = false;\n this._yawOffset = 0;\n this._options = {};\n }\n}\n\nexport default XRManager;\n","import { IS_SAFARI_ON_DESKTOP } from \"../utils/browser\";\n\nclass WebGLAnimator {\n private _callback: ((...args: any[]) => any) | null;\n private _context: any;\n private _rafId: number;\n private _rafTimer: number;\n\n public constructor() {\n this._callback = null;\n this._context = window;\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public setCallback(callback: (...args: any[]) => any) {\n this._callback = callback;\n }\n\n public setContext(context: any) {\n this._context = context;\n }\n\n public start() {\n const context = this._context;\n const callback = this._callback;\n\n // No context / callback set\n if (!context || !callback) return;\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n if (IS_SAFARI_ON_DESKTOP) {\n this._rafId = context.requestAnimationFrame(this._onLoopNextTick);\n } else {\n this._rafId = context.requestAnimationFrame(this._onLoop);\n }\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n /**\n * There can be more than 1 argument when we use XRSession's raf\n */\n private _onLoop = (...args: any[]) => {\n this._callback!(...args);\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n };\n\n /**\n * MacOS X Safari Bug Fix\n * This code guarantees that rendering should be occurred.\n *\n * In MacOS X(10.14.2), Safari (12.0.2)\n * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term\n * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms)\n * So browser cannot render the frame and may be freezing.\n */\n private _onLoopNextTick = (...args: any[]) => {\n const before = performance.now();\n\n this._callback!(...args);\n\n const diff = performance.now() - before;\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n this._rafTimer = -1;\n }\n\n /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */\n if (diff < 16) {\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n } else {\n /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */\n this._rafTimer = window.setTimeout(this._onLoop, 0);\n }\n };\n}\n\nexport default WebGLAnimator;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { XRFrame } from \"webxr\";\nimport Promise from \"promise-polyfill\";\nimport { glMatrix, vec3, mat3, mat4, quat } from \"gl-matrix\";\nimport ImReady, { OnReady } from \"@egjs/imready\";\n\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { devicePixelRatio, WEBXR_SUPPORTED } from \"../utils/browserFeature\";\nimport { PROJECTION_TYPE, STEREO_FORMAT } from \"../PanoViewer/consts\";\nimport { IS_IOS } from \"../utils/browser\";\nimport { CubemapConfig, ImageCandidate, ValueOf, VideoCandidate } from \"../types/internal\";\nimport YawPitchControl from \"../YawPitchControl/YawPitchControl\";\nimport { toImageElement, toVideoElement } from \"../utils/utils\";\n\nimport WebGLUtils from \"./WebGLUtils\";\nimport Renderer from \"./renderer/Renderer\";\nimport CubeRenderer from \"./renderer/CubeRenderer\";\nimport CubeStripRenderer from \"./renderer/CubeStripRenderer\";\nimport SphereRenderer from \"./renderer/SphereRenderer\";\nimport CylinderRenderer from \"./renderer/CylinderRenderer\";\nimport VRManager from \"./vr/VRManager\";\nimport XRManager from \"./vr/XRManager\";\nimport WebGLAnimator from \"./WebGLAnimator\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ImageType = PROJECTION_TYPE;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet DEVICE_PIXEL_RATIO = devicePixelRatio || 1;\n\n// DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다.\nif (DEVICE_PIXEL_RATIO > 2) {\n DEVICE_PIXEL_RATIO = 2;\n}\n\n// define custom events name\n/**\n * TODO: how to manage events/errortype with PanoViewer\n *\n * I think renderer events should be seperated from viewer events although it has same name.\n */\nconst EVENTS: {\n BIND_TEXTURE: \"bindTexture\";\n IMAGE_LOADED: \"imageLoaded\";\n ERROR: \"error\";\n RENDERING_CONTEXT_LOST: \"renderingContextLost\";\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\";\n} = {\n BIND_TEXTURE: \"bindTexture\",\n IMAGE_LOADED: \"imageLoaded\",\n ERROR: \"error\",\n RENDERING_CONTEXT_LOST: \"renderingContextLost\",\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\"\n};\n\nconst ERROR_TYPE = {\n INVALID_DEVICE: 10,\n NO_WEBGL: 11,\n FAIL_IMAGE_LOAD: 12,\n RENDERER_ERROR: 13\n};\n\nclass PanoImageRenderer extends Component<{\n [EVENTS.ERROR]: {\n type: number;\n message: string;\n };\n [EVENTS.IMAGE_LOADED]: {\n content: HTMLElement;\n isVideo: boolean;\n projectionType: ValueOf;\n };\n [EVENTS.BIND_TEXTURE]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_LOST]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_RESTORE]: ComponentEvent;\n}> {\n public static EVENTS = EVENTS;\n public static ERROR_TYPE = ERROR_TYPE;\n\n public sphericalConfig: {\n initialYaw: number;\n initialPitch: number;\n fieldOfView: number;\n imageType: ValueOf;\n stereoFormat: ValueOf;\n cubemapConfig: Partial;\n };\n\n public fieldOfView: number;\n public width: number;\n public height: number;\n\n public canvas: HTMLCanvasElement;\n public context: WebGLRenderingContext;\n public shaderProgram: WebGLProgram | null;\n public texture: WebGLTexture;\n\n public pMatrix: mat4;\n public mvMatrix: mat4;\n\n public textureCoordBuffer: WebGLBuffer | null = null;\n public vertexBuffer: WebGLBuffer | null = null;\n public indexBuffer: WebGLBuffer | null = null;\n\n private _wrapper: HTMLElement | null;\n private _wrapperOrigStyle: string | null;\n private _lastQuaternion: quat | null;\n private _lastYaw: number | null;\n private _lastPitch: number | null;\n private _lastFieldOfView: number | null;\n private _renderingContextAttributes?: WebGLContextAttributes;\n\n private _renderer: Renderer;\n private _contentLoader: ImReady | null;\n private _image: HTMLImageElement | HTMLImageElement[] | HTMLVideoElement | null;\n private _imageConfig: CubemapConfig | null;\n private _imageType: ValueOf;\n private _imageIsReady: boolean;\n private _isVideo: boolean;\n private _isCubeMap: boolean;\n private _shouldForceDraw: boolean;\n private _keepUpdate: boolean;\n private _hasExternalCanvas: boolean;\n\n private _yawPitchControl: YawPitchControl;\n private _animator: WebGLAnimator;\n private _vr: VRManager | XRManager | null;\n\n public constructor(\n image: ImageCandidate | VideoCandidate,\n width: number,\n height: number,\n isVideo: boolean,\n container: HTMLElement,\n canvasClass: string,\n sphericalConfig: PanoImageRenderer[\"sphericalConfig\"],\n renderingContextAttributes?: WebGLContextAttributes\n ) {\n // Super constructor\n super();\n\n this.sphericalConfig = sphericalConfig;\n this.fieldOfView = sphericalConfig.fieldOfView;\n\n this.width = width;\n this.height = height;\n\n this._lastQuaternion = null;\n this._lastYaw = null;\n this._lastPitch = null;\n this._lastFieldOfView = null;\n\n this.pMatrix = mat4.create();\n this.mvMatrix = mat4.create();\n\n // initialzie pMatrix\n mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), width / height, 0.1, 100);\n\n this.textureCoordBuffer = null;\n this.vertexBuffer = null;\n this.indexBuffer = null;\n\n this.canvas = this._initCanvas(container, canvasClass, width, height);\n\n this._setDefaultCanvasStyle();\n this._wrapper = null; // canvas wrapper\n this._wrapperOrigStyle = null;\n\n this._renderingContextAttributes = renderingContextAttributes;\n this._image = null;\n this._imageConfig = null;\n this._imageIsReady = false;\n this._shouldForceDraw = false;\n this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still.\n\n this._onContentLoad = this._onContentLoad.bind(this);\n this._onContentError = \tthis._onContentError.bind(this);\n\n this._animator = new WebGLAnimator();\n\n // VR/XR manager\n this._vr = null;\n\n if (image) {\n this.setImage({\n image,\n imageType: sphericalConfig.imageType,\n isVideo,\n cubemapConfig: sphericalConfig.cubemapConfig\n });\n }\n }\n\n // FIXME: Please refactor me to have more loose connection to yawpitchcontrol\n public setYawPitchControl(yawPitchControl: YawPitchControl) {\n this._yawPitchControl = yawPitchControl;\n }\n\n public getContent() {\n return this._image;\n }\n\n public setImage({\n image,\n imageType,\n isVideo = false,\n cubemapConfig\n }: {\n image: ImageCandidate | VideoCandidate;\n imageType: PanoImageRenderer[\"_imageType\"];\n isVideo: boolean;\n cubemapConfig: Partial;\n }) {\n this._imageIsReady = false;\n this._isVideo = isVideo;\n this._imageConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only */\n order: (imageType === ImageType.CUBEMAP) ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n },\n ...cubemapConfig\n };\n this._setImageType(imageType);\n\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._contentLoader = new ImReady()\n .on(\"ready\", this._onContentLoad)\n .on(\"error\", this._onContentError);\n\n if (isVideo) {\n this._image = toVideoElement(image as VideoCandidate);\n this._contentLoader.check([this._image]);\n this._keepUpdate = true;\n } else {\n this._image = toImageElement(image as ImageCandidate);\n this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n this._keepUpdate = false;\n }\n }\n\n public isImageLoaded() {\n return !!this._image && this._imageIsReady &&\n (!this._isVideo || (this._image as HTMLVideoElement).readyState >= 2 /* HAVE_CURRENT_DATA */);\n }\n\n public bindTexture() {\n return new Promise((res, rej) => {\n const contentLoader = this._contentLoader;\n\n if (!this._image) {\n return rej(\"Image is not defined\");\n }\n\n if (!contentLoader) {\n return rej(\"ImageLoader is not initialized\");\n }\n\n if (contentLoader.isReady()) {\n this._bindTexture();\n res();\n } else {\n contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n contentLoader.once(\"ready\", e => {\n if (e.errorCount > 0) {\n rej(\"Failed to load images.\");\n } else {\n this._bindTexture();\n res();\n }\n });\n }\n });\n }\n\n // 부모 엘리먼트에 canvas 를 붙임\n public attachTo(parentElement) {\n if (!this._hasExternalCanvas) {\n this.detach();\n parentElement.appendChild(this.canvas);\n }\n this._wrapper = parentElement;\n }\n\n public forceContextLoss() {\n if (this.hasRenderingContext()) {\n const loseContextExtension = this.context.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n\n // 부모 엘리먼트에서 canvas 를 제거\n public detach() {\n if (!this._hasExternalCanvas && this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n\n public destroy() {\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._animator.stop();\n this.detach();\n this.forceContextLoss();\n\n this.off();\n\n this.canvas.removeEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n this.canvas.removeEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n }\n\n public hasRenderingContext() {\n const ctx = this.context;\n if (\n !ctx\n || ctx.isContextLost()\n || !ctx.getProgramParameter(this.shaderProgram!, ctx.LINK_STATUS)) {\n return false;\n }\n return true;\n }\n\n public updateFieldOfView(fieldOfView) {\n this.fieldOfView = fieldOfView;\n this._updateViewport();\n }\n\n public updateViewportDimensions(width, height) {\n let viewPortChanged = false;\n\n this.width = width;\n this.height = height;\n\n const w = width * DEVICE_PIXEL_RATIO;\n const h = height * DEVICE_PIXEL_RATIO;\n\n if (w !== this.canvas.width) {\n this.canvas.width = w;\n viewPortChanged = true;\n }\n\n if (h !== this.canvas.height) {\n this.canvas.height = h;\n viewPortChanged = true;\n }\n\n if (!viewPortChanged) {\n return;\n }\n\n this._updateViewport();\n this._shouldForceDraw = true;\n }\n\n public keepUpdate(doUpdate) {\n if (doUpdate && this.isImageLoaded() === false) {\n // Force to draw a frame after image is loaded on render()\n this._shouldForceDraw = true;\n }\n\n this._keepUpdate = doUpdate;\n }\n\n public startRender() {\n this._animator.setCallback(this._render.bind(this));\n this._animator.start();\n }\n\n public stopRender() {\n this._animator.stop();\n }\n\n public renderWithQuaternion(quaternion, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // updatefieldOfView only if fieldOfView is changed.\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion);\n\n this._draw();\n\n this._lastQuaternion = quat.clone(quaternion);\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n public renderWithYawPitch(yaw, pitch, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastYaw !== null && this._lastYaw === yaw &&\n this._lastPitch !== null && this._lastPitch === pitch &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n mat4.identity(this.mvMatrix);\n mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch));\n mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw));\n\n this._draw();\n\n this._lastYaw = yaw;\n this._lastPitch = pitch;\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n /**\n * Returns projection renderer by each type\n */\n public getProjectionRenderer() {\n return this._renderer;\n }\n\n /**\n * @return Promise\n */\n public enterVR(options) {\n const vr = this._vr;\n\n if (!WEBXR_SUPPORTED && !(navigator as any).getVRDisplays) {\n return Promise.reject(\"VR is not available on this browser.\");\n }\n if (vr && vr.isPresenting()) {\n return Promise.resolve(\"VR already enabled.\");\n }\n\n return this._requestPresent(options);\n }\n\n public exitVR = () => {\n const vr = this._vr;\n const gl = this.context;\n const animator = this._animator;\n\n if (!vr) return;\n\n vr.removeEndCallback(this.exitVR);\n vr.destroy();\n this._vr = null;\n\n // Restore canvas & context on iOS\n if (IS_IOS) {\n this._restoreStyle();\n }\n this.updateViewportDimensions(this.width, this.height);\n this._updateViewport();\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._bindBuffers();\n this._shouldForceDraw = true;\n\n animator.stop();\n animator.setContext(window);\n animator.setCallback(this._render.bind(this));\n animator.start();\n };\n\n private _setImageType(imageType) {\n if (!imageType || this._imageType === imageType) {\n return;\n }\n\n this._imageType = imageType;\n this._isCubeMap = imageType === ImageType.CUBEMAP;\n\n if (this._renderer) {\n this._renderer.off();\n }\n\n switch (imageType) {\n case ImageType.CUBEMAP:\n this._renderer = new CubeRenderer();\n break;\n case ImageType.CUBESTRIP:\n this._renderer = new CubeStripRenderer();\n break;\n case ImageType.PANORAMA:\n this._renderer = new CylinderRenderer();\n break;\n case ImageType.STEREOSCOPIC_EQUI:\n this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat);\n break;\n default:\n this._renderer = new SphereRenderer(STEREO_FORMAT.NONE);\n break;\n }\n\n this._renderer.on(Renderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERER_ERROR,\n message: e.message\n }));\n });\n\n this._initWebGL();\n }\n\n private _initCanvas(container: HTMLElement, canvasClass: string, width: number, height: number) {\n const canvasInContainer = container.querySelector(`.${canvasClass}`);\n const canvas = canvasInContainer || this._createCanvas(canvasClass);\n\n this._hasExternalCanvas = !!canvasInContainer;\n\n canvas.width = width;\n canvas.height = height;\n\n this._onWebglcontextlost = this._onWebglcontextlost.bind(this);\n this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this);\n\n canvas.addEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n canvas.addEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n\n return canvas;\n }\n\n private _createCanvas(className: string) {\n const canvas = document.createElement(\"canvas\");\n\n canvas.className = className;\n\n return canvas;\n }\n\n private _setDefaultCanvasStyle() {\n const canvas = this.canvas;\n\n canvas.style.bottom = \"0\";\n canvas.style.left = \"0\";\n canvas.style.right = \"0\";\n canvas.style.top = \"0\";\n canvas.style.margin = \"auto\";\n canvas.style.maxHeight = \"100%\";\n canvas.style.maxWidth = \"100%\";\n canvas.style.outline = \"none\";\n canvas.style.position = \"absolute\";\n }\n\n private _onContentError() {\n this._imageIsReady = false;\n this._image = null;\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_IMAGE_LOAD,\n message: \"failed to load image\"\n }));\n\n return false;\n }\n\n private _triggerContentLoad() {\n this.trigger(new ComponentEvent(EVENTS.IMAGE_LOADED, {\n content: this._image as HTMLElement,\n isVideo: this._isVideo,\n projectionType: this._imageType\n }));\n }\n\n private _onContentLoad(e: OnReady) {\n if (e.errorCount > 0) return;\n\n this._imageIsReady = true;\n\n this._triggerContentLoad();\n }\n\n private _initShaderProgram() {\n const gl = this.context;\n\n if (this.shaderProgram) {\n gl.deleteProgram(this.shaderProgram);\n this.shaderProgram = null;\n }\n\n const renderer = this._renderer;\n\n const vsSource = renderer.getVertexShaderSource();\n const fsSource = renderer.getFragmentShaderSource();\n\n const vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource)!;\n const fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource)!;\n\n const shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader);\n\n if (!shaderProgram) {\n throw new Error(`Failed to initialize shaders: ${WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())}`);\n }\n\n gl.useProgram(shaderProgram);\n (shaderProgram as any).vertexPositionAttribute = gl.getAttribLocation(shaderProgram, \"aVertexPosition\");\n (shaderProgram as any).pMatrixUniform = gl.getUniformLocation(shaderProgram, \"uPMatrix\");\n (shaderProgram as any).mvMatrixUniform = gl.getUniformLocation(shaderProgram, \"uMVMatrix\");\n (shaderProgram as any).samplerUniform = gl.getUniformLocation(shaderProgram, \"uSampler\");\n (shaderProgram as any).textureCoordAttribute = gl.getAttribLocation(shaderProgram, \"aTextureCoord\");\n (shaderProgram as any).uEye = gl.getUniformLocation(shaderProgram, \"uEye\");\n\n gl.enableVertexAttribArray((shaderProgram as any).vertexPositionAttribute);\n gl.enableVertexAttribArray((shaderProgram as any).textureCoordAttribute);\n\n // clear buffer\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\n // Use TEXTURE0\n gl.uniform1i((shaderProgram as any).samplerUniform, 0);\n\n this.shaderProgram = shaderProgram;\n }\n\n private _onWebglcontextlost(e) {\n e.preventDefault();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_LOST));\n }\n\n private _onWebglcontextrestored() {\n this._initWebGL();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_RESTORE));\n }\n\n private _updateViewport() {\n mat4.perspective(\n this.pMatrix,\n glMatrix.toRadian(this.fieldOfView),\n this.canvas.width / this.canvas.height,\n 0.1,\n 100);\n\n this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight);\n }\n\n private _initWebGL() {\n let gl: WebGLRenderingContext;\n\n // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed.\n try {\n this._initRenderingContext();\n gl = this.context;\n\n this.updateViewportDimensions(this.width, this.height);\n this._initShaderProgram();\n } catch (e) {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n this.destroy();\n console.error(e); // eslint-disable-line no-console\n return;\n }\n // 캔버스를 투명으로 채운다.\n gl.clearColor(0, 0, 0, 0);\n const textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\n\n if (this.texture) {\n gl.deleteTexture(this.texture);\n }\n\n this.texture = WebGLUtils.createTexture(gl, textureTarget)!;\n\n if (this._imageType === ImageType.CUBESTRIP) {\n // TODO: Apply following options on other projection type.\n gl.enable(gl.CULL_FACE);\n // gl.enable(gl.DEPTH_TEST);\n }\n }\n\n private _initRenderingContext() {\n if (this.hasRenderingContext()) {\n return;\n }\n\n if (!window.WebGLRenderingContext) {\n throw new Error(\"WebGLRenderingContext not available.\");\n }\n\n this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes)!;\n\n if (!this.context) {\n throw new Error(\"Failed to acquire 3D rendering context\");\n }\n }\n\n private _initBuffers() {\n const image = this._image as HTMLImageElement | HTMLVideoElement;\n\n const vertexPositionData = this._renderer.getVertexPositionData();\n const indexData = this._renderer.getIndexData();\n const textureCoordData = this._renderer.getTextureCoordData({\n image,\n imageConfig: this._imageConfig!\n });\n const gl = this.context;\n\n this.vertexBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3,\n (this.shaderProgram as any).vertexPositionAttribute);\n\n this.indexBuffer = WebGLUtils.initBuffer(\n gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1);\n\n this.textureCoordBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2,\n (this.shaderProgram as any).textureCoordAttribute);\n\n this._bindBuffers();\n }\n\n private _bindTexture() {\n // Detect if it is EAC Format while CUBESTRIP mode.\n // We assume it is EAC if image is not 3/2 ratio.\n if (this._imageType === ImageType.CUBESTRIP) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const isEAC = width && height && width / height !== 1.5 ? 1 : 0;\n\n this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram!, \"uIsEAC\"), isEAC);\n } else if (this._imageType === ImageType.PANORAMA) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const imageAspectRatio = width && height && width / height;\n\n this._renderer.updateShaderData({imageAspectRatio});\n }\n\n // initialize shader buffers after image is loaded.(by updateShaderData)\n // because buffer may be differ by image size.(eg. CylinderRenderer)\n this._initBuffers();\n\n this._renderer.bindTexture(\n this.context,\n this.texture,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n this._shouldForceDraw = true;\n\n this.trigger(new ComponentEvent(EVENTS.BIND_TEXTURE));\n }\n\n private _updateTexture() {\n this._renderer.updateTexture(\n this.context,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n }\n\n private _render() {\n const yawPitchControl = this._yawPitchControl;\n const fov = yawPitchControl.getFov();\n\n if (yawPitchControl.shouldRenderWithQuaternion()) {\n const quaternion = yawPitchControl.getQuaternion();\n\n this.renderWithQuaternion(quaternion, fov);\n } else {\n const yawPitch = yawPitchControl.getYawPitch();\n\n this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov);\n }\n }\n\n private _renderStereo = (time: number, frame: XRFrame) => {\n const vr = this._vr;\n const gl = this.context;\n\n const eyeParams = vr!.getEyeParams(gl, frame);\n\n if (!eyeParams) return;\n\n vr!.beforeRender(gl, frame);\n\n // Render both eyes\n for (const eyeIndex of [0, 1]) {\n const eyeParam = eyeParams[eyeIndex];\n\n this.mvMatrix = eyeParam.mvMatrix;\n this.pMatrix = eyeParam.pMatrix;\n\n gl.viewport(...eyeParam.viewport as [number, number, number, number]);\n gl.uniform1f((this.shaderProgram as any).uEye, eyeIndex);\n\n this._bindBuffers();\n this._draw();\n }\n\n vr!.afterRender();\n };\n\n private _bindBuffers() {\n const gl = this.context;\n const program = this.shaderProgram;\n\n const vertexBuffer = this.vertexBuffer;\n const textureCoordBuffer = this.textureCoordBuffer;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray((program as any).vertexPositionAttribute);\n gl.vertexAttribPointer(\n (program as any).vertexPositionAttribute, (vertexBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);\n gl.enableVertexAttribArray((program as any).textureCoordAttribute);\n gl.vertexAttribPointer(\n (program as any).textureCoordAttribute, (textureCoordBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n }\n\n private _draw() {\n if (this._isVideo && this._keepUpdate) {\n this._updateTexture();\n }\n\n this._renderer.render({\n gl: this.context,\n shaderProgram: this.shaderProgram!,\n indexBuffer: this.indexBuffer!,\n mvMatrix: this.mvMatrix,\n pMatrix: this.pMatrix\n });\n }\n\n private _requestPresent(options) {\n const gl = this.context;\n const canvas = this.canvas;\n const animator = this._animator;\n\n this._vr = WEBXR_SUPPORTED ?\n new XRManager(options) :\n new VRManager();\n\n const vr = this._vr;\n\n animator.stop();\n return new Promise((resolve, reject) => {\n vr.requestPresent(canvas, gl)\n .then(() => {\n vr.addEndCallback(this.exitVR);\n animator.setContext(vr.context);\n animator.setCallback(this._onFirstVRFrame);\n\n if (IS_IOS) {\n this._setWrapperFullscreen();\n }\n\n this._shouldForceDraw = true;\n animator.start();\n\n resolve(\"success\");\n })\n .catch(e => {\n vr.destroy();\n this._vr = null;\n animator.start();\n\n reject(e);\n });\n });\n }\n\n private _onFirstVRFrame = (time, frame) => {\n const vr = this._vr!;\n const gl = this.context;\n const animator = this._animator;\n\n // If rendering is not ready, wait for next frame\n if (!vr.canRender(frame)) return;\n\n const minusZDir = vec3.fromValues(0, 0, -1);\n const eyeParam = vr.getEyeParams(gl, frame)![0];\n // Extract only rotation\n const mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix);\n const pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix);\n\n const mvInv = mat3.invert(mat3.create(), mvMatrix);\n const pInv = mat3.invert(mat3.create(), pMatrix);\n const viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv);\n\n vec3.transformMat3(viewDir, viewDir, mvInv);\n\n const yawOffset = mathUtil.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1));\n\n if (yawOffset === 0) {\n // If the yawOffset is exactly 0, then device sensor is not ready\n // So read it again until it has any value in it\n return;\n }\n\n vr.setYawOffset(yawOffset);\n animator.setCallback(this._renderStereo);\n };\n\n private _setWrapperFullscreen() {\n const wrapper = this._wrapper;\n\n if (!wrapper) return;\n\n this._wrapperOrigStyle = wrapper.getAttribute(\"style\");\n const wrapperStyle = wrapper.style;\n\n wrapperStyle.width = \"100vw\";\n wrapperStyle.height = \"100vh\";\n wrapperStyle.position = \"fixed\";\n wrapperStyle.left = \"0\";\n wrapperStyle.top = \"0\";\n wrapperStyle.zIndex = \"9999\";\n }\n\n private _restoreStyle() {\n const wrapper = this._wrapper;\n const canvas = this.canvas;\n\n if (!wrapper) return;\n\n if (this._wrapperOrigStyle) {\n wrapper.setAttribute(\"style\", this._wrapperOrigStyle);\n } else {\n wrapper.removeAttribute(\"style\");\n }\n\n this._wrapperOrigStyle = null;\n\n // Restore canvas style\n canvas.removeAttribute(\"style\");\n this._setDefaultCanvasStyle();\n }\n}\n\nexport default PanoImageRenderer;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Promise from \"promise-polyfill\";\nimport { quat } from \"gl-matrix\";\n\nimport { DeviceMotionEvent, checkXRSupport } from \"../utils/browserFeature\";\nimport YawPitchControl, { YawPitchControlOptions } from \"../YawPitchControl/YawPitchControl\";\nimport PanoImageRenderer from \"../PanoImageRenderer/PanoImageRenderer\";\nimport WebGLUtils from \"../PanoImageRenderer/WebGLUtils\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { CubemapConfig, ValueOf } from \"../types/internal\";\nimport { AnimationEndEvent, ReadyEvent, ViewChangeEvent, ErrorEvent } from \"../types/event\";\n\nimport { ERROR_TYPE, PANOVIEWER_EVENTS as EVENTS, GYRO_MODE, PROJECTION_TYPE, STEREO_FORMAT, DEFAULT_CANVAS_CLASS } from \"./consts\";\n\nexport interface PanoViewerOptions {\n image: string | HTMLElement;\n video: string | HTMLElement;\n projectionType: ValueOf;\n cubemapConfig: Partial;\n stereoFormat: ValueOf;\n width: number;\n height: number;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n touchDirection: ValueOf;\n canvasClass: string;\n}\n\nexport interface PanoViewerEvent {\n ready: ReadyEvent;\n viewChange: ViewChangeEvent;\n animationEnd: AnimationEndEvent;\n error: ErrorEvent;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * PanoViewer\n */\nclass PanoViewer extends Component {\n /**\n * Check whether the current environment can execute PanoViewer\n * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다.\n * @return PanoViewer executable PanoViewer 실행가능 여부\n */\n public static isSupported(): boolean {\n return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL();\n }\n\n /**\n * Check whether the current environment supports the WebGL\n * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다.\n * @return WebGL support WebGL 지원여부\n */\n public static isWebGLAvailable(): boolean {\n return WebGLUtils.isWebGLAvailable();\n }\n\n /**\n * Check whether the current environment supports the gyro sensor.\n * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다.\n * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수\n */\n public static isGyroSensorAvailable(callback: (isAvailable: boolean) => any) {\n if (!DeviceMotionEvent && callback) {\n callback(false);\n return;\n }\n\n let onDeviceMotionChange;\n\n const checkGyro = () => new Promise(res => {\n onDeviceMotionChange = deviceMotion => {\n const isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null);\n\n res(isGyroSensorAvailable);\n };\n\n window.addEventListener(\"devicemotion\", onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n Promise.race([checkGyro(), timeout()]).then((isGyroSensorAvailable: boolean) => {\n window.removeEventListener(\"devicemotion\", onDeviceMotionChange);\n\n if (callback) {\n callback(isGyroSensorAvailable);\n }\n\n PanoViewer.isGyroSensorAvailable = fb => {\n if (fb) {\n fb(isGyroSensorAvailable);\n }\n return isGyroSensorAvailable;\n };\n });\n }\n\n private static _isValidTouchDirection(direction) {\n return direction === PanoViewer.TOUCH_DIRECTION.NONE ||\n direction === PanoViewer.TOUCH_DIRECTION.YAW ||\n direction === PanoViewer.TOUCH_DIRECTION.PITCH ||\n direction === PanoViewer.TOUCH_DIRECTION.ALL;\n }\n\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @name VERSION\n * @static\n * @type {String}\n * @example\n * eg.view360.PanoViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.PanoViewer\n */\n public static VERSION = VERSION;\n public static ERROR_TYPE = ERROR_TYPE;\n public static EVENTS = EVENTS;\n public static PROJECTION_TYPE = PROJECTION_TYPE;\n public static GYRO_MODE = GYRO_MODE;\n // This should be deprecated!\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static ProjectionType = PROJECTION_TYPE;\n public static STEREO_FORMAT = STEREO_FORMAT;\n\n /**\n * Constant value for touch directions\n * @ko 터치 방향에 대한 상수 값.\n * @namespace\n * @name TOUCH_DIRECTION\n */\n public static TOUCH_DIRECTION = {\n /**\n * Constant value for none direction.\n * @ko none 방향에 대한 상수 값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 1\n */\n NONE: YawPitchControl.TOUCH_DIRECTION_NONE,\n /**\n * Constant value for horizontal(yaw) direction.\n * @ko horizontal(yaw) 방향에 대한 상수 값.\n * @name YAW\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 6\n */\n YAW: YawPitchControl.TOUCH_DIRECTION_YAW,\n /**\n * Constant value for vertical direction.\n * @ko vertical(pitch) 방향에 대한 상수 값.\n * @name PITCH\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 24\n */\n PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH,\n /**\n * Constant value for all direction.\n * @ko all 방향에 대한 상수 값.\n * @name ALL\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 30\n */\n ALL: YawPitchControl.TOUCH_DIRECTION_ALL\n };\n\n private _container: HTMLElement;\n // Options\n private _image: ConstructorParameters[0];\n private _isVideo: boolean;\n private _projectionType: ValueOf;\n private _cubemapConfig: Partial;\n private _stereoFormat: ValueOf;\n private _width: number;\n private _height: number;\n private _yaw: number;\n private _pitch: number;\n private _fov: number;\n private _gyroMode: ValueOf;\n private _quaternion: quat | null;\n private _aspectRatio: number;\n private _isReady: boolean;\n private _canvasClass: string;\n\n // Internal Values\n private _photoSphereRenderer: PanoImageRenderer | null;\n private _yawPitchControl: YawPitchControl | null;\n\n /**\n * @classdesc 360 media viewer\n * @ko 360 미디어 뷰어\n *\n * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트\n * @param options\n *\n * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
\n * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다.\n * @param {Object} [options.cubemapConfig.order = \"RLUDBF\"(ProjectionType === CUBEMAP) | \"RLUDFB\" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서\n * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다.\n * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다.\n * @param {String} [options.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
\n * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위)\n * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위)\n * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위)\n * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위)\n * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위)\n * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다\n * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다.\n * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키\n * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE}
\n * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위\n * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위\n * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위\n * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
\n * @param {String} [options.canvasClass=\"view360-canvas\"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n *\n * @example\n * ```\n * // PanoViewer Creation\n * // create PanoViewer with option\n * var PanoViewer = eg.view360.PanoViewer;\n * // Area where the image will be displayed(HTMLElement)\n * var container = document.getElementById(\"myPanoViewer\");\n *\n * var panoViewer = new PanoViewer(container, {\n * // If projectionType is not specified, the default is \"equirectangular\".\n * // Specifies an image of the \"equirectangular\" type.\n * image: \"/path/to/image/image.jpg\"\n * });\n * ```\n *\n * @example\n * ```\n * // Cubemap Config Setting Example\n * // For support Youtube EAC projection, You should set cubemapConfig as follows.\n * cubemapConfig: {\n * order: \"LFRDBU\",\n * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}]\n * }\n * ```\n */\n public constructor(container: HTMLElement, options: Partial = {}) {\n super();\n\n // Raises the error event if webgl is not supported.\n if (!WebGLUtils.isWebGLAvailable()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n }, 0);\n return this;\n }\n\n if (!WebGLUtils.isStableWebGL()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_DEVICE,\n message: \"blacklisted browser\"\n }));\n }, 0);\n\n return this;\n }\n\n if (!!options.image && !!options.video) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_RESOURCE,\n message: \"Specifying multi resouces(both image and video) is not valid.\"\n }));\n }, 0);\n return this;\n }\n\n // Check XR support at not when imported, but when created.\n // This is intended to make polyfills easier to use.\n checkXRSupport();\n\n this._container = container;\n this._image = options.image! as HTMLImageElement || options.video! as HTMLVideoElement;\n this._isVideo = !!options.video;\n this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/\n order: this._projectionType === PROJECTION_TYPE.CUBEMAP ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...options.cubemapConfig\n };\n this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n\n // If the width and height are not provided, will use the size of the container.\n this._width = options.width || parseInt(window.getComputedStyle(container).width, 10);\n this._height = options.height || parseInt(window.getComputedStyle(container).height, 10);\n\n /**\n * Cache the direction for the performance in renderLoop\n *\n * This value should be updated by \"change\" event of YawPitchControl.\n */\n this._yaw = options.yaw || 0;\n this._pitch = options.pitch || 0;\n this._fov = options.fov || 65;\n\n this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH;\n this._quaternion = null;\n\n this._aspectRatio = this._height !== 0 ? this._width / this._height : 1;\n\n this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS;\n\n const fovRange = options.fovRange || [30, 110];\n const touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ?\n options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL;\n const yawPitchConfig = {\n ...options,\n ...{\n element: container,\n yaw: this._yaw,\n pitch: this._pitch,\n fov: this._fov,\n gyroMode: this._gyroMode,\n fovRange,\n aspectRatio: this._aspectRatio,\n touchDirection\n }\n };\n\n this._isReady = false;\n\n this._initYawPitchControl(yawPitchConfig);\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n /**\n * Get the video element that the viewer is currently playing. You can use this for playback.\n * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다.\n * @return HTMLVideoElementHTMLVideoElement\n * @example\n * ```\n * var videoTag = panoViewer.getVideo();\n * videoTag.play(); // play the video!\n * ```\n */\n public getVideo() {\n if (!this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent() as HTMLVideoElement;\n }\n\n /**\n * Set the video information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정)\n * @param {object} param\n * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}(\"equirectangular\")] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setVideo(\"/path/to/video/video.mp4\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR\n * });\n * ```\n */\n public setVideo(video: string | HTMLElement | { type: string; src: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n }> = {}) {\n if (video) {\n this.setImage(video, {\n projectionType: param.projectionType,\n isVideo: true,\n cubemapConfig: param.cubemapConfig,\n stereoFormat: param.stereoFormat\n });\n }\n\n return this;\n }\n\n /**\n * Get the image information that the viewer is currently using.\n * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다.\n * @return Image Object이미지 객체\n * @example\n * var imageObj = panoViewer.getImage();\n */\n public getImage() {\n if (this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent();\n }\n\n /**\n * Set the image information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.)\n * @param {object} param Additional information이미지 추가 정보\n * @param {string} [param.projectionType=\"equirectangular\"] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setImage(\"/path/to/image/image.png\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP\n * });\n * ```\n */\n public setImage(image: string | HTMLElement | { src: string; type: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n isVideo: boolean;\n }> = {}) {\n const cubemapConfig = {\n ...{\n order: \"RLUDBF\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...param.cubemapConfig\n };\n const stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n const isVideo = !!(param.isVideo);\n\n if (this._image && this._isVideo !== isVideo) {\n /* eslint-disable no-console */\n console.warn(\"PanoViewer is not currently supporting content type changes. (Image <--> Video)\");\n /* eslint-enable no-console */\n return this;\n }\n\n if (image) {\n this._deactivate();\n\n this._image = image as HTMLImageElement;\n this._isVideo = isVideo;\n this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = cubemapConfig;\n this._stereoFormat = stereoFormat;\n\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n return this;\n }\n\n /**\n * Set whether the renderer always updates the texture and renders.\n * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다.\n * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public keepUpdate(doUpdate: boolean) {\n this._photoSphereRenderer!.keepUpdate(doUpdate);\n return this;\n }\n\n /**\n * Get the current projection type (equirectangular/cube)\n * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다.\n * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE}\n */\n public getProjectionType() {\n return this._projectionType;\n }\n\n /**\n * Activate the device's motion sensor, and return the Promise whether the sensor is enabled\n * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element.\n * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다.\n * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다.\n */\n public enableSensor() {\n return new Promise((resolve, reject) => {\n if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\") {\n DeviceMotionEvent.requestPermission().then(permissionState => {\n if (permissionState === \"granted\") {\n resolve();\n } else {\n reject(new Error(\"permission denied\"));\n }\n }).catch(e => {\n // This can happen when this method wasn't triggered by user interaction\n reject(e);\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Disable the device's motion sensor.\n * @ko 디바이스의 모션 센서를 비활성화합니다.\n * @deprecated\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public disableSensor() {\n return this;\n }\n\n /**\n * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred).\n * This method must be used in the context of user interaction, like onclick callback on the button element.\n * It can be rejected when an enabling device sensor fails or image/video is still loading(\"ready\" event not triggered).\n * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다)\n * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우(\"ready\"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다.\n * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요.\n * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error)\n */\n public enterVR(options: {\n requiredFeatures?: any[];\n optionalFeatures?: any[];\n [key: string]: any;\n } = {}): globalThis.Promise {\n if (!this._isReady) {\n return Promise.reject(new Error(\"PanoViewer is not ready to show image.\")) as any;\n }\n\n return new Promise((resolve, reject) => {\n this.enableSensor()\n .then(() => this._photoSphereRenderer!.enterVR(options))\n .then((res: string) => resolve(res))\n .catch(e => reject(e));\n }) as any;\n }\n\n /**\n * Exit VR stereo rendering mode.\n * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public exitVR() {\n this._photoSphereRenderer!.exitVR();\n return this;\n }\n\n /**\n * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}.\n * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다.\n * @param useZoom\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseZoom(useZoom: boolean): this {\n if (typeof useZoom === \"boolean\") {\n this._yawPitchControl!.option(\"useZoom\", useZoom);\n }\n\n return this;\n }\n\n /**\n * When true, enables the keyboard move key control: awsd, arrow keys\n * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키)\n * @param useKeyboard\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseKeyboard(useKeyboard: boolean): this {\n this._yawPitchControl!.option(\"useKeyboard\", useKeyboard);\n return this;\n }\n\n /**\n * Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")\n * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")\n * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE}\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setGyroMode(\"yawPitch\");\n * //equivalent\n * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH);\n * ```\n */\n public setGyroMode(gyroMode: PanoViewer[\"_gyroMode\"]) {\n this._yawPitchControl!.option(\"gyroMode\", gyroMode);\n return this;\n }\n\n /**\n * Set the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 설정합니다.\n * @param range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setFovRange([50, 90]);\n */\n public setFovRange(range: number[]) {\n this._yawPitchControl!.option(\"fovRange\", range);\n return this;\n }\n\n /**\n * Get the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 반환합니다.\n * @return FOV range\n * @example\n * var range = panoViewer.getFovRange(); // [50, 90]\n */\n public getFovRange(): [number, number] {\n return this._yawPitchControl!.option(\"fovRange\") as [number, number];\n }\n\n /**\n * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size.\n * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다.\n * @param {object} [size]\n * @param {number} [size.width=width of the container]\n * @param {number} [size.height=height of the container]\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public updateViewportDimensions(size: Partial<{\n width: number;\n height: number;\n }> = {}): this {\n if (!this._isReady) {\n return this;\n }\n\n let containerSize;\n\n if (size.width === undefined || size.height === undefined) {\n containerSize = window.getComputedStyle(this._container);\n }\n\n const width = size.width || parseInt(containerSize.width, 10);\n const height = size.height || parseInt(containerSize.height, 10);\n\n // Skip if viewport is not changed.\n if (width === this._width && height === this._height) {\n return this;\n }\n\n this._width = width;\n this._height = height;\n\n this._aspectRatio = width / height;\n this._photoSphereRenderer!.updateViewportDimensions(width, height);\n this._yawPitchControl!.option(\"aspectRatio\", this._aspectRatio);\n this._yawPitchControl!.updatePanScale({height});\n\n this.lookAt({}, 0);\n return this;\n }\n\n /**\n * Get the current field of view(FOV)\n * @ko 현재 field of view(FOV) 값을 반환합니다.\n */\n public getFov(): number {\n return this._fov;\n }\n\n /**\n * Get current yaw value\n * @ko 현재 yaw 값을 반환합니다.\n */\n public getYaw() {\n return this._yaw;\n }\n\n /**\n * Get current pitch value\n * @ko 현재 pitch 값을 반환합니다.\n */\n public getPitch() {\n return this._pitch;\n }\n\n /**\n * Get the range of controllable Yaw values\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n */\n public getYawRange(): [number, number] {\n return this._yawPitchControl!.option(\"yawRange\") as [number, number];\n }\n\n /**\n * Get the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다.\n */\n public getPitchRange(): [number, number] {\n return this._yawPitchControl!.option(\"pitchRange\") as [number, number];\n }\n\n /**\n * Set the range of controllable yaw\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setYawRange([-90, 90]);\n */\n public setYawRange(yawRange: number[]) {\n this._yawPitchControl!.option(\"yawRange\", yawRange);\n return this;\n }\n\n /**\n * Set the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 설정합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setPitchRange([-40, 40]);\n */\n public setPitchRange(pitchRange: number[]) {\n this._yawPitchControl!.option(\"pitchRange\", pitchRange);\n return this;\n }\n\n /**\n * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed.\n * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다.\n * @param showPolePoint\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setShowPolePoint(showPolePoint: boolean) {\n this._yawPitchControl!.option(\"showPolePoint\", showPolePoint);\n return this;\n }\n\n /**\n * Set a new view by setting camera configuration. Any parameters not specified remain the same.\n * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다.\n * @param {object} orientation\n * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위)\n * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위)\n * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위)\n * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초)\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * // Change the yaw angle (absolute angle) to 30 degrees for one second.\n * panoViewer.lookAt({yaw: 30}, 1000);\n * ```\n */\n public lookAt(orientation: Partial<{\n yaw: number;\n pitch: number;\n fov: number;\n }>, duration: number = 0) {\n if (!this._isReady) {\n return this;\n }\n\n const yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw;\n const pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch;\n const pitchRange = this._yawPitchControl!.option(\"pitchRange\");\n const verticalAngleOfImage = pitchRange[1] - pitchRange[0];\n let fov = orientation.fov !== undefined ? orientation.fov : this._fov;\n\n if (verticalAngleOfImage < fov) {\n fov = verticalAngleOfImage;\n }\n\n this._yawPitchControl!.lookAt({yaw, pitch, fov}, duration);\n\n if (duration === 0) {\n this._photoSphereRenderer!.renderWithYawPitch(yaw, pitch, fov);\n }\n return this;\n }\n\n /**\n * Set touch direction by which user can control.\n * @ko 사용자가 조작가능한 터치 방향을 지정합니다.\n * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @return PanoViewer instance\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Limit the touch direction to the yaw direction only.\n * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW);\n * ```\n */\n public setTouchDirection(direction: number): this {\n if (PanoViewer._isValidTouchDirection(direction)) {\n this._yawPitchControl!.option(\"touchDirection\", direction);\n }\n\n return this;\n }\n\n /**\n * Returns touch direction by which user can control\n * @ko 사용자가 조작가능한 터치 방향을 반환한다.\n * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Returns the current touch direction.\n * var dir = panoViewer.getTouchDirection();\n * ```\n */\n public getTouchDirection(): number {\n return this._yawPitchControl!.option(\"touchDirection\") ;\n }\n\n /**\n * Destroy viewer. Remove all registered event listeners and remove viewer canvas.\n * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public destroy(): this {\n this._deactivate();\n\n if (this._yawPitchControl) {\n this._yawPitchControl.destroy();\n this._yawPitchControl = null;\n }\n\n return this;\n }\n\n // TODO: Remove parameters as they're just using private values\n private _initRenderer(\n yaw: number,\n pitch: number,\n fov: number,\n projectionType: PanoViewer[\"_projectionType\"],\n cubemapConfig: PanoViewer[\"_cubemapConfig\"]\n ) {\n this._photoSphereRenderer = new PanoImageRenderer(\n this._image,\n this._width,\n this._height,\n this._isVideo,\n this._container,\n this._canvasClass,\n {\n initialYaw: yaw,\n initialPitch: pitch,\n fieldOfView: fov,\n imageType: projectionType,\n cubemapConfig,\n stereoFormat: this._stereoFormat\n },\n );\n this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl!);\n\n this._bindRendererHandler();\n\n this._photoSphereRenderer\n .bindTexture()\n .then(() => this._activate())\n .catch(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_BIND_TEXTURE,\n message: \"failed to bind texture\"\n }));\n });\n }\n\n /**\n * @private\n * update values of YawPitchControl if needed.\n * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image.\n *\n * This function should be called after isReady status is true.\n */\n private _updateYawPitchIfNeeded() {\n if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) {\n // update fov by aspect ratio\n const image = this._photoSphereRenderer!.getContent()! as HTMLImageElement;\n let imageAspectRatio = image.naturalWidth / image.naturalHeight;\n let yawSize;\n let maxFov;\n\n // If height is larger than width, then we assume it's rotated by 90 degree.\n if (imageAspectRatio < 1) {\n // So inverse the aspect ratio.\n imageAspectRatio = 1 / imageAspectRatio;\n }\n\n if (imageAspectRatio < 6) {\n yawSize = mathUtil.toDegree(imageAspectRatio);\n // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5\n maxFov = mathUtil.toDegree(Math.atan(0.5)) * 2;\n } else {\n yawSize = 360;\n maxFov = (360 / imageAspectRatio); // Make it 5 fixed as axes does.\n }\n\n // console.log(\"_updateYawPitchIfNeeded\", maxFov, \"aspectRatio\", image.naturalWidth, image.naturalHeight, \"yawSize\", yawSize);\n const minFov = (this._yawPitchControl!.option(\"fovRange\"))[0];\n\n // this option should be called after fov is set.\n this._yawPitchControl!.option({\n \"fov\": maxFov, /* parameter for internal validation for pitchrange */\n \"yawRange\": [-yawSize / 2, yawSize / 2],\n \"pitchRange\": [-maxFov / 2, maxFov / 2],\n \"fovRange\": [minFov, maxFov]\n });\n this.lookAt({fov: maxFov});\n }\n }\n\n private\t_bindRendererHandler() {\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, e));\n });\n\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, () => {\n this._deactivate();\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERING_CONTEXT_LOST,\n message: \"webgl rendering context lost\"\n }));\n });\n }\n\n private _initYawPitchControl(yawPitchConfig: Partial) {\n this._yawPitchControl = new YawPitchControl(yawPitchConfig);\n\n this._yawPitchControl.on(EVENTS.ANIMATION_END, e => {\n this.trigger(new ComponentEvent(EVENTS.ANIMATION_END, e));\n });\n\n this._yawPitchControl.on(\"change\", e => {\n this._yaw = e.yaw;\n this._pitch = e.pitch;\n this._fov = e.fov;\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(EVENTS.VIEW_CHANGE, {\n yaw: e.yaw,\n pitch: e.pitch,\n fov: e.fov,\n quaternion: e.quaternion,\n isTrusted: e.isTrusted\n }));\n });\n }\n\n private _activate() {\n this._photoSphereRenderer!.attachTo(this._container);\n this._yawPitchControl!.enable();\n\n this.updateViewportDimensions();\n\n this._isReady = true;\n\n // update yawPitchControl after isReady status is true.\n this._updateYawPitchIfNeeded();\n\n this.trigger(new ComponentEvent(EVENTS.READY));\n this._photoSphereRenderer!.startRender();\n }\n\n /**\n * Destroy webgl context and block user interaction and stop rendering\n */\n private _deactivate() {\n // Turn off the video if it has one\n const video = this.getVideo();\n if (video) {\n video.pause();\n }\n\n if (this._isReady) {\n this._photoSphereRenderer!.stopRender();\n this._yawPitchControl!.disable();\n this._isReady = false;\n }\n\n if (this._photoSphereRenderer) {\n this._photoSphereRenderer.destroy();\n this._photoSphereRenderer = null;\n }\n }\n}\n\nexport default PanoViewer;\n\n","import { SpinViewerOptions, SpinViewerEvent } from \"./SpinViewer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const SPINVIEWER_OPTIONS: { [key in keyof SpinViewerOptions]: true } = {\n imageUrl: true,\n rowCount: true,\n colCount: true,\n width: true,\n height: true,\n autoHeight: true,\n colRow: true,\n scale: true,\n frameIndex: true,\n wrapperClass: true,\n imageClass: true\n};\n\nexport const SPINVIEWER_EVENTS: {\n [key: string]: keyof SpinViewerEvent;\n} = {\n LOAD: \"load\",\n IMAGE_ERROR: \"imageError\",\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n};\n\nexport const DEFAULT_WRAPPER_CLASS = \"view360-wrapper\";\nexport const DEFAULT_IMAGE_CLASS = \"view360-image\";\n","import Component, { ComponentEvent } from \"@egjs/component\";\n\nimport { TRANSFORM, SUPPORT_WILLCHANGE } from \"../utils/browserFeature\";\nimport { VERSION } from \"../version\";\n\nimport { SpinViewerOptions } from \"./SpinViewer\";\nimport { DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS } from \"./consts\";\n\nexport interface SpriteImageEvent {\n /**\n * Events that occur when component loading is complete\n * @ko 컴포넌트 로딩이 완료되면 발생하는 이벤트\n * @name eg.view360.SpriteImage#load\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {HTMLElement} param.target The target element for which to display the image 이미지를 보여줄 대상 엘리먼트\n * @param {HTMLElement} param.bgElement Generated background image element 생성된 background 이미지 엘리먼트\n *\n * @example\n *\n * sprites.on({\n * \"load\" : function(evt) {\n * console.log(\"load event fired - e.target\", e.target, \"e.bgElement\", e.bgElement);\n * }\n * });\n */\n load: {\n target: HTMLElement;\n bgElement: HTMLDivElement;\n };\n /**\n * An event that occurs when the image index is changed by the user's left / right panning\n * @ko 사용자의 좌우 Panning 에 의해 이미지 인덱스가 변경되었을때 발생하는 이벤트\n * @name eg.view360.SpriteImage#imageError\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {String} param.imageUrl User-specified image URL 사용자가 지정한 이미지 URL\n *\n * @example\n *\n * sprites.on({\n * \"imageError\" : function(evt) {\n * // Error handling\n * console.log(e.imageUrl);\n * }\n * });\n */\n imageError: {\n imageUrl?: string;\n };\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpriteImage\n */\nclass SpriteImage extends Component {\n private static _createBgDiv(wrapperInContainer: HTMLDivElement | null, img: HTMLImageElement, rowCount: number, colCount: number, autoHeight: boolean) {\n const el = wrapperInContainer || document.createElement(\"div\");\n\n el.style.position = \"relative\";\n el.style.overflow = \"hidden\";\n\n img.style.position = \"absolute\";\n img.style.width = `${colCount * 100}%`;\n img.style.height = `${rowCount * 100}%`;\n\n /** Prevent image from being dragged on IE10, IE11, Safari especially */\n img.ondragstart = () => (false); // img.style.pointerEvents = \"none\";\n // Use hardware accelerator if available\n if (SUPPORT_WILLCHANGE) {\n (img.style.willChange = \"transform\");\n }\n\n el.appendChild(img);\n\n const unitWidth = img.naturalWidth / colCount;\n const unitHeight = img.naturalHeight / rowCount;\n\n if (autoHeight) {\n const r = unitHeight / unitWidth;\n\n el.style.paddingBottom = `${r * 100}%`;\n } else {\n el.style.height = \"100%\";\n }\n\n return el;\n }\n\n private static _getSizeString(size) {\n if (typeof size === \"number\") {\n return `${size}px`;\n }\n\n return size;\n }\n\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _rowCount: number;\n private _colCount: number;\n private _totalCount: number;\n private _width: number | string;\n private _height: number | string;\n private _autoHeight: boolean;\n private _colRow: number[];\n private _image: HTMLImageElement;\n private _bg: HTMLDivElement;\n private _autoPlayReservedInfo: { interval: number; playCount: number } | null;\n private _autoPlayTimer: number;\n\n /**\n * @class eg.view360.SpriteImage\n * @classdesc A module that displays a single or continuous image of any one of the \"sprite images\". SpinViewer internally uses SpriteImage to show each frame of the sprite image.\n * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다.\n * @extends eg.Component\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the \"Sprite image\". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n *\n * // Initialize SpriteImage\n *\n * var el = document.getElementById(\"image-div\");\n * var sprites = new eg.view360.SpriteImage(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24\n * });\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n const opt = options || {};\n\n this._el = element;\n this._rowCount = opt.rowCount || 1;\n this._colCount = opt.colCount || 1;\n this._totalCount = this._rowCount * this._colCount; // total frames\n this._width = opt.width || \"auto\";\n this._height = opt.height || \"auto\";\n this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten.\n this._colRow = [0, 0];\n\n if (opt.colRow) {\n this._colRow = opt.colRow;\n } else if (opt.frameIndex) {\n this.setFrameIndex(opt.frameIndex);\n }\n\n this._el.style.width = SpriteImage._getSizeString(this._width);\n this._el.style.height = SpriteImage._getSizeString(this._height);\n\n const wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS;\n const imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS;\n\n if (!opt.imageUrl) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n }, 0);\n return;\n }\n\n const imageInContainer = element.querySelector(`.${imageClass}`);\n const wrapperInContainer = element.querySelector(`.${wrapperClass}`);\n\n if (wrapperInContainer && imageInContainer) {\n // Set it to invisible to prevent wrapper being resized\n imageInContainer.style.display = \"none\";\n }\n\n this._image = imageInContainer || new Image();\n /**\n * Event\n */\n\n const image = this._image;\n\n image.onload = () => {\n if (wrapperInContainer && imageInContainer) {\n imageInContainer.style.display = \"\";\n }\n\n this._bg = SpriteImage._createBgDiv(\n wrapperInContainer,\n image,\n this._rowCount,\n this._colCount,\n this._autoHeight\n );\n this._el.appendChild(this._bg);\n this.setColRow(this._colRow[0], this._colRow[1]);\n\n this.trigger(new ComponentEvent(\"load\", {\n target: this._el,\n bgElement: this._bg\n }));\n\n if (this._autoPlayReservedInfo) {\n this.play(this._autoPlayReservedInfo);\n this._autoPlayReservedInfo = null;\n }\n };\n\n image.onerror = () => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n };\n\n image.src = opt.imageUrl;\n }\n\n /**\n * Specifies the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정\n * @method eg.view360.SpriteImage#setFrameIndex\n * @param {Number} frameIndex frame index of a frame프레임의 인덱스\n *\n * @example\n *\n * sprites.setFrameIndex(0, 1);// col = 0, row = 1\n */\n public setFrameIndex(index: number) {\n const colRow = this.toColRow(index);\n\n this.setColRow(colRow[0], colRow[1]);\n }\n\n /**\n * Returns the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환\n * @method eg.view360.SpriteImage#getFrameIndex\n * @return {Number} frame index frame 인덱스\n *\n * @example\n *\n * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1\n *\n */\n public getFrameIndex() {\n return this._colRow[1] * this._colCount + this._colRow[0];\n }\n\n /**\n * Specifies the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정\n * @method eg.view360.SpriteImage#setColRow\n * @param {Number} col Column number of a frame프레임의 행값\n * @param {Number} row Row number of a frame프레임의 열값\n *\n * @example\n *\n * sprites.setlColRow(1, 2); // col = 1, row = 2\n */\n public setColRow(col: number, row: number) {\n if (row > this._rowCount - 1 || col > this._colCount - 1) {\n return;\n }\n\n if (this._image && TRANSFORM) {\n // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser?\n this._image.style[TRANSFORM] = `translate(${-(col / this._colCount * 100)}%, ${-(row / this._rowCount * 100)}%)`;\n }\n\n this._colRow = [col, row];\n }\n\n /**\n * Returns the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환\n * @method eg.view360.SpriteImage#gelColRow\n * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열\n *\n * @example\n *\n * var colRow = sprites.getlColRow();\n * // colRow = [1, 2] - index of col is 1, index of row is 2\n *\n */\n public getColRow() {\n return this._colRow;\n }\n\n /**\n * Stop playing\n * @ko play 되고 있던 프레임 재생을 중지합니다.\n * @method eg.view360.SpriteImage#stop\n *\n * @example\n *\n * viewer.stop();\n *\n */\n public stop() {\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n }\n\n /**\n * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'.\n * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다.\n * @method eg.view360.SpriteImage#play\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위\n * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복\n *\n * @example\n *\n * viewer.play({angle: 16, playCount: 1});\n *\n */\n public play({ interval, playCount } = { interval: 1000 / this._totalCount, playCount: 0 }) {\n if (!this._bg) {\n this._autoPlayReservedInfo = {interval, playCount};\n return;\n }\n\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n\n let frameIndex = this.getFrameIndex();\n let count = 0;\n let frameCount = 0; // for checking 1 cycle\n\n this._autoPlayTimer = window.setInterval(() => {\n frameIndex %= this._totalCount;\n const colRow = this.toColRow(frameIndex);\n\n this.setColRow(colRow[0], colRow[1]);\n frameIndex++;\n\n // Done 1 Cycle?\n if (++frameCount === this._totalCount) {\n frameCount = 0;\n count++;\n }\n\n if (playCount > 0 && count === playCount) {\n clearInterval(this._autoPlayTimer);\n }\n }, interval);\n }\n\n public toColRow(frameIndex: number) {\n const colCount = this._colCount;\n const rowCount = this._rowCount;\n\n if (frameIndex < 0) {\n return [0, 0];\n } else if (frameIndex >= this._totalCount) {\n return [colCount - 1, rowCount - 1];\n }\n\n const col = frameIndex % colCount;\n const row = Math.floor(frameIndex / colCount);\n\n // console.log(frameIndex, col, row);\n return [col, row];\n }\n}\n\nexport default SpriteImage;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport { VERSION } from \"../version\";\nimport { AnimationEndEvent, ChangeEvent, ImageErrorEvent, LoadEvent } from \"../types/event\";\n\nimport SpriteImage from \"./SpriteImage\";\n\nconst DEFAULT_PAN_SCALE = 0.21;\n\nexport interface SpinViewerEvent {\n load: LoadEvent;\n imageError: ImageErrorEvent;\n change: ChangeEvent;\n animationEnd: AnimationEndEvent;\n}\n\nexport interface SpinViewerOptions {\n imageUrl: string;\n rowCount: number;\n colCount: number;\n width: number | string;\n height: number | string;\n autoHeight: boolean;\n colRow: number[];\n scale: number;\n frameIndex: number;\n wrapperClass: string;\n imageClass: string;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpinViewer\n */\nclass SpinViewer extends Component {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @static\n * @example\n * eg.view360.SpinViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.SpinViewer\n */\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _sprites: SpriteImage;\n private _axes: Axes;\n private _panInput: PanInput;\n\n private _scale: number;\n private _panScale: number;\n private _frameCount: number;\n\n /**\n * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object.\n * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다.\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값\n * @param {String} [options.wrapperClass=\"view360-wrapper\"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @param {String} [options.imageClass=\"view360-image\"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n * ```\n * // Initialize SpinViewer\n * var el = document.getElementById(\"product-360\");\n * var viewer = new eg.view360.SpinViewer(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24 //required\n * });\n * ```\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n\n this._el = element;\n\n const opt = {...options};\n const colCount = opt.colCount || 1;\n const rowCount = opt.rowCount || 1;\n\n this._scale = (opt.scale || 1);\n this._panScale = this._scale * DEFAULT_PAN_SCALE;\n\n this._frameCount = colCount * rowCount;\n\n // Init SpriteImage\n this._sprites = new SpriteImage(element, opt).on({\n \"load\": evt => {\n this.trigger(new ComponentEvent(\"load\", evt));\n },\n \"imageError\": evt => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: evt.imageUrl\n }));\n }\n });\n\n // Init Axes\n this._panInput = new PanInput(this._el, {\n scale: [this._panScale, this._panScale]\n });\n this._axes = new Axes({\n angle: {\n range: [0, 359],\n circular: true\n }\n }).on({\n \"change\": evt => {\n const curr = Math.floor(evt.pos.angle / (360 / this._frameCount));\n const frameIndex = this._frameCount - curr - 1;\n\n this._sprites.setFrameIndex(frameIndex);\n\n this.trigger(new ComponentEvent(\"change\", {\n frameIndex,\n colRow: this._sprites.getColRow(),\n angle: evt.pos.angle\n }));\n },\n \"animationEnd\": evt => {\n this.trigger(new ComponentEvent(\"animationEnd\", {\n isTrusted: evt.isTrusted\n }));\n }\n });\n\n this._axes.connect(\"angle\", this._panInput);\n }\n\n /**\n * Set spin scale\n * @ko scale 을 조정할 수 있는 함수\n * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.setScale(2);// It moves twice as much.\n */\n public setScale(scale: number) {\n if (isNaN(scale) || scale < 0) {\n return this;\n }\n\n this._scale = scale;\n this._panScale = scale * DEFAULT_PAN_SCALE;\n this._panInput.options.scale = [this._panScale, this._panScale];\n\n return this;\n }\n\n /**\n * Get spin scale\n * @ko scale 값을 반환한다.\n *\n * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @example\n * viewer.getScale();// It returns number\n */\n public getScale() {\n return this._scale;\n }\n\n /**\n * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle.\n * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle상대적 회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinBy(720, {duration: 500});\n */\n public spinBy(angle = 0, param = {duration: 0}) {\n this._axes.setBy({angle}, param.duration);\n return this;\n }\n\n /**\n * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle).\n * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinTo(30, {duration:100});\n */\n public spinTo(angle = 0, param = {duration: 0}) {\n this._axes.setTo({angle}, param.duration);\n return this;\n }\n\n /**\n * Returns current angles\n * @ko 현재 각도를 반환한다.\n *\n * @return {Number} Current angle 현재 각도\n */\n public getAngle() {\n return this._axes.get().angle || 0;\n }\n}\n\nexport default SpinViewer;\n","import Component from \"@egjs/component\";\n\nconst withMethods = (component: any, prototype: any, vanillaInstance: string) => {\n [Component.prototype, component.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto).filter(name => !prototype[name] && !name.startsWith(\"_\") && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[vanillaInstance], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return descriptor.get?.call(this[vanillaInstance]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[vanillaInstance], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","import { PanoViewer } from \"../PanoViewer\";\n\nimport withMethods from \"./withMethods\";\n\nconst withPanoViewerMethods = (prototype: any, name: string) => {\n withMethods(PanoViewer, prototype, name);\n};\n\nexport default withPanoViewerMethods;\n","import { SpinViewer } from \"../SpinViewer\";\n\nimport withMethods from \"./withMethods\";\n\nconst withSpinViewerMethods = (prototype: any, name: string) => {\n withMethods(SpinViewer, prototype, name);\n};\n\nexport default withSpinViewerMethods;\n","import PanoViewer, { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\n\nexport default (panoViewer: PanoViewer, newProps: Partial, prevProps: Partial) => {\n if (isPropChanged(newProps.image, prevProps.image)) {\n panoViewer.setImage(newProps.image, {\n projectionType: newProps.projectionType,\n cubemapConfig: newProps.cubemapConfig,\n stereoFormat: newProps.stereoFormat,\n isVideo: false\n });\n } else if (isPropChanged(newProps.video, prevProps.video)) {\n panoViewer.setVideo(newProps.video, {\n projectionType: newProps.projectionType,\n cubemapConfig: newProps.cubemapConfig,\n stereoFormat: newProps.stereoFormat\n });\n }\n\n const singleUpdateOptions: Array = [\n \"fovRange\",\n \"gyroMode\",\n \"pitchRange\",\n \"showPolePoint\",\n \"touchDirection\",\n \"useKeyboard\",\n \"useZoom\",\n \"yawRange\"\n ];\n\n singleUpdateOptions.forEach(optionName => {\n updateOption(panoViewer, optionName, newProps, prevProps);\n });\n};\n\nconst isPropChanged = (val: any, prevVal: any): val is true => val != null && val !== prevVal;\nconst updateOption = (panoViewer: PanoViewer, optionName: string, newProps: Partial, prevProps: Partial) => {\n if (isPropChanged(newProps[optionName], prevProps[optionName])) {\n panoViewer[`set${optionName[0].toUpperCase()}${optionName.slice(1)}`](newProps[optionName]);\n }\n};\n","export const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n\nexport const generateCanvasKey = (oldKey: number) => {\n let newKey: number;\n\n do {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n newKey = array[0];\n } while (newKey === oldKey);\n\n return newKey;\n};\n","/*\n * Copyright (c) 2017 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport * as PanoViewer from \"./PanoViewer\";\nimport * as SpinViewer from \"./SpinViewer\";\nimport * as CFC from \"./cfc\";\nimport { merge } from \"./utils/utils\";\n\nconst View360: any = {};\n\nmerge(View360, PanoViewer);\nmerge(View360, SpinViewer);\nmerge(View360, CFC);\n\nexport default View360;\n"],"names":["VERSION","win","window","Math","self","Function","doc","document","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","IS_IOS","IS_SAFARI_ON_DESKTOP","Float32Array","Array","getComputedStyle","userAgent","SUPPORT_TOUCH","SUPPORT_DEVICEMOTION","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","target","i","len","length","SUPPORT_WILLCHANGE","CSS","supports","WEBXR_SUPPORTED","checkXRSupport","xr","isSessionSupported","then","res","catch","supportsSession","quatToVec3","quaternion","baseV","vec3","toDegree","a","PI","util","isPowerOfTwo","n","extractPitchFromQuat","atan2","sqrt","pow","hypot","x","y","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","getRotationDelta","prevQ","curQ","rotateKind","prevQuaternion","quat","curQuaternion","prevPoint","curPoint","rotateDistance","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","distance","abs","projectedPrevPoint","trigonometricRatio","theta","acos","crossVec","thetaDirection","deltaRadian","angleBetweenVec2","v1","v2","det","vec2","yawOffsetBetween","viewDir","targetDir","viewDirXZ","targetDirXZ","sign","Number","toAxis","source","offset","reduce","acc","v","version","branch","build","match","exec","parseInt","CHROME_VERSION","IS_CHROME_WITHOUT_DEVICE_MOTION","IS_ANDROID","test","CONTROL_MODE_VR","CONTROL_MODE_YAWPITCH","TOUCH_DIRECTION_NONE","TOUCH_DIRECTION_YAW","TOUCH_DIRECTION_PITCH","TOUCH_DIRECTION_ALL","MC_DECELERATION","MC_MAXIMUM_DURATION","MC_BIND_SCALE","MAX_FIELD_OF_VIEW","PAN_SCALE","YAW_RANGE_HALF","PITCH_RANGE_HALF","CIRCULAR_PITCH_RANGE_HALF","GYRO_MODE","NONE","YAWPITCH","VR","MathUtil","degToRad","radToDeg","Vector2","prototype","constructor","set","copy","subVectors","b","Vector3","z","normalize","scalar","invScalar","multiplyScalar","applyQuaternion","q","qx","qy","qz","qw","w","ix","iy","iz","iw","dot","crossVectors","ax","ay","az","bx","by","bz","Quaternion","undefined","setFromEulerXYZ","c1","cos","c2","c3","s1","sin","s2","s3","setFromEulerYXZ","setFromAxisAngle","axis","angle","halfAngle","s","multiply","multiplyQuaternions","qax","qay","qaz","qaw","qbx","qby","qbz","qbw","inverse","l","slerp","qb","t","cosHalfTheta","halfTheta","sinHalfTheta","ratioA","ratioB","setFromUnitVectors","r","EPS","vFrom","vTo","Util","MIN_TIMESTEP","MAX_TIMESTEP","base64","mimeType","clamp","value","min","max","lerp","isIOS","platform","isWebViewAndroid","indexOf","isSafari","isFirefoxAndroid","isR7","isLandscapeMode","rtn","orientation","isTimestampDeltaValid","timestampDeltaS","isNaN","getScreenWidth","screen","width","height","getScreenHeight","requestFullscreen","element","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","exitFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","getFullscreenElement","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","linkProgram","gl","vertexSource","fragmentSource","attribLocationMap","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","program","createProgram","attachShader","attribName","bindAttribLocation","deleteShader","getProgramUniforms","uniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","uniformName","uniformInfo","getActiveUniform","replace","getUniformLocation","orthoMatrix","out","left","right","bottom","top","near","far","lr","bt","nf","copyArray","dest","isMobile","check","substr","vendor","opera","extend","src","key","hasOwnProperty","safariCssSizeWorkaround","canvas","width_1","height_1","setTimeout","isDebug","getQueryParameter","regex","RegExp","results","location","search","decodeURIComponent","frameDataFromPose","piOver180","rad45","mat4_perspectiveFromFieldOfView","fov","upTan","tan","upDegrees","downTan","downDegrees","leftTan","leftDegrees","rightTan","rightDegrees","xScale","yScale","mat4_fromRotationTranslation","x2","y2","z2","xx","xy","xz","yy","yz","zz","wx","wy","wz","mat4_translate","a00","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","mat4_invert","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b06","b07","b08","b09","b10","b11","defaultOrientation","defaultPosition","updateEyeMatrices","projection","view","pose","parameters","vrDisplay","fieldOfView","depthNear","depthFar","position","frameData","timestamp","leftProjectionMatrix","leftViewMatrix","getEyeParameters","rightProjectionMatrix","rightViewMatrix","isInsideCrossDomainIFrame","isFramed","refDomain","getDomainFromUrl","referrer","thisDomain","href","url","domain","split","predictionTimeS","previousQ","previousTimestampS","deltaQ","outQ","currentQ","gyro","timestampS","angularSpeed","console","log","toFixed","deltaT","predictAngle","STILLNESS_THRESHOLD","__extends","_super","_this","_onDeviceMotion","bind","_onDeviceOrientation","_onChromeWithoutDeviceMotion","isWithoutDeviceMotion","isAndroid","stillGyroVec","rawGyroVec","adjustedGyroVec","_timer","lastDevicemotionTimestamp","_isEnabled","enable","addEventListener","removeEventListener","e","alpha","beta","gamma","trigger","ComponentEvent","inputEvent","deviceorientation","clearTimeout","Date","getTime","isGyroSensorAvailable","rotationRate","isGravitySensorAvailable","accelerationIncludingGravity","interval","devicemotionEvent","__assign","timeStamp","type","acceleration","adjustedRotationRate","Component","sample","sensorSample","kFilter","vector","currentGyroMeasurement","previousGyroMeasurement","run_","currentAccelMeasurement","SensorSample","filterQ","previousFilterQ","accelQ","isOrientationInitialized","estimatedGravity","measuredGravity","gyroIntegralQ","accelToQuaternion_","gyroDeltaQ","gyroToQuaternionDelta_","invFilterQ","getQuaternionAngle","targetQ","accel","normAccel","dt","ComplementaryFilter","isFilterQuaternionInitialized","getOrientation","K_FILTER","PREDICTION_TIME_S","deviceMotion","DeviceMotion","accelerometer","gyroscope","_onDeviceMotionChange","_onScreenOrientationChange","filter","posePredictor","PosePredictor","filterToWorldQ","isChromeUsingDegrees","inverseWorldToScreenQ","worldToScreenQ","originalPoseAdjustQ","_setScreenTransform","resetQ","on","isEnabled","disable","_deviceOrientationQ","deviceOrientationFixQ","_alpha","outQuat","_convertFusionToPredicted","_prevOrientation","predictedQ","getPrediction","_a","accGravity","rotRate","_triggerChange","addAccelMeasurement","addGyroMeasurement","getDeltaYaw","prvQ","yawDeltaByYaw","yawDeltaByRoll","getDeltaPitch","pitchDelta","el","options","_prevQuaternion","_quaternion","fusionPoseSensor","scale","threshold","_onPoseChange","axes","observer","FusionPoseSensor","_attachEvent","_dettachEvent","destroy","disconnect","event","change","off","screenRotationAngleInst","refCount","_onOrientationChange","_spinR","_screenOrientationAngle","glMatrix","betaR","gammaR","_useRotation","_screenRotationAngle","setUseRotation","useRotation","_userDirection","Axes","DIRECTION_ALL","unref","ScreenRotationAngle","_direction","DIRECTION_HORIZONTAL","connect","properties","useDirection","_getOffset","newOffset","getRadian","cosTheta","sinTheta","DIRECTION_VERTICAL","PanInput","Y_AXIS_VECTOR","_fusionPoseSensor","isTrusted","yaw","yawQ","conj","DEFAULT_YAW_RANGE","DEFAULT_PITCH_RANGE","CIRCULAR_PITCH_RANGE","opt","pitch","showPolePoint","useZoom","useKeyboard","gyroMode","touchDirection","yawRange","pitchRange","fovRange","aspectRatio","_element","_initialFov","_enabled","_isAnimating","_deviceQuaternion","_initAxes","option","param","_axes","get","areaHeight","_axesPanInput","deceleration","newValue","_getOptions","newOptions","changedKeyList","push","Object","keys","_setOptions","_getValidatedOptions","_applyOptions","updatePanScale","persistOrientation","_resetOrientation","duration","pos","p","f","maximumDuration","Infinity","setBy","yawPitch","getCombinedQuaternion","_axesWheelInput","_axesTiltMotionInput","_axesPinchInput","_axesMoveKeyInput","yRange","_updateYawRange","pRange","_updatePitchRange","RotationPanInput","WheelInput","PinchInput","MoveKeyInput","range","circular","_isCircular","bounce","hold","evt","delta","_updateControlScale","release","animationEnd","_getValidYawRange","_getValidPitchRange","arguments","isVR","isYawPitch","some","setTo","prevFov","nextFov","_initDeviceQuaternion","TiltMotionInput","_togglePinchInputByOption","_enableTouch","_inputs","direction","yawEnabled","pitchEnabled","DeviceQuaternion","newYawRange","newFov","newAspectRatio","ratio","_adjustAspectRatio","horizontalFov","isValid","newPitchRange","changeEvt","verticalAngle","halfFov","isPanorama","concat","horizontalAngle","halfHorizontalFov","mathUtil","targetElement","input","inputRange","outputRange","rangeIdx","inputA","inputB","outputA","outputB","_lerp","fraction","YawPitchControl","ERROR_TYPE","INVALID_DEVICE","NO_WEBGL","FAIL_IMAGE_LOAD","FAIL_BIND_TEXTURE","INVALID_RESOURCE","RENDERING_CONTEXT_LOST","PANOVIEWER_EVENTS","READY","VIEW_CHANGE","ANIMATION_END","ERROR","PROJECTION_TYPE","EQUIRECTANGULAR","CUBEMAP","CUBESTRIP","PANORAMA","STEREOSCOPIC_EQUI","STEREO_FORMAT","TOP_BOTTOM","LEFT_RIGHT","PANOVIEWER_OPTIONS","image","video","projectionType","cubemapConfig","stereoFormat","canvasClass","DEFAULT_CANVAS_CLASS","merge","_i","srcs","forEach","isArray","toImageElement","images","parsedImages","map","img","imgEl","Image","crossOrigin","toVideoElement","videoCandidate","HTMLVideoElement","video_1","createElement","setAttribute","appendSourceElement","sourceCount","querySelectorAll","readyState","load","videoUrl","videoSrc","videoType","sourceElement","appendChild","WEBGL_ERROR_CODE","webglAvailability","WebGLUtils","shader","success","getShaderParameter","COMPILE_STATUS","error","getShaderInfoLog","LINK_STATUS","deleteProgram","data","itemSize","attr","buffer","createBuffer","bindBuffer","bufferData","STATIC_DRAW","numItems","enableVertexAttribArray","vertexAttribPointer","FLOAT","userContextAttributes","webglIdentifiers","context","contextAttributes","preserveDrawingBuffer","antialias","onWebglcontextcreationerror","statusMessage","webglIdentifiers_1","__values","identifier","getContext","textureTarget","texture","createTexture","bindTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","webglContext","getWebglContext","loseContextExtension","getExtension","loseContext","agentInfo","isStableWebgl","parseFloat","code","pixels","texImage2D","RGBA","UNSIGNED_BYTE","getParameter","MAX_TEXTURE_SIZE","isIE11","majorVersion","EVENTS","_forceDimension","_pixelCanvas","_pixelContext","shaderProgram","indexBuffer","mvMatrix","pMatrix","uniformMatrix4fv","pMatrixUniform","mvMatrixUniform","drawElements","TRIANGLES","UNSIGNED_SHORT","pixelSource","naturalWidth","videoWidth","naturalHeight","videoHeight","forceDimension","isIE11Video","getDimension","contentDimension","textureDimension","drawImage","imageConfig","tileConfig","config","flipHorizontal","rotation","message","Renderer","CubeRenderer","order","_VERTEX_POSITION_DATA","_INDEX_DATA","indexData","vertexPositionData","getVertexPositionData","vertexOrder","extractOrder","base","_extractTileConfig","elemSize","vertexPerTile","trim","texCoords","face","floor","ordermap","shift","unshift","pop","elemPerTile","tileVertex","slice","tileTemp","j","splice","coord","_shrinkCoord","faceCoords","val","coords","baseOrder","orderMap","surfaceIdx","tileIdx","TEXTURE_CUBE_MAP_POSITIVE_X","maxCubeMapTextureSize","getMaxCubeMapTextureSize","tile","extractTileFromImage","_triggerError","TEXTURE_CUBE_MAP","updateTexture","inputTextureSize","outputTextureSize","getSourceTileSize","tilePerRow","MAX_CUBE_MAP_TEXTURE_SIZE","imageWidth","coordData","SHRINK_MULTIPLIER","axisMultipliers","axisIndex","axisDir","notSameDir","_vertices","indices","cols","rows","textureSize","c","tileConfigs","_transformCoord","index","TEXTURE_2D","_getPixelSource","size","maxSize","getMaxTextureSize","_initPixelSource","activeTexture","TEXTURE0","pixelStorei","UNPACK_FLIP_Y_WEBGL","newCoord","_flipHorizontalCoord","_rotateCoord","SHRINK_Y","SHRINK_X","rotationAngle","SIZE","shiftCount","moved","rotatedCoord","latitudeBands","longitudeBands","radius","ANGLE_CORRECTION_FOR_CENTER_ALIGN","textureCoordData","latIdx","lngIdx","phi","sinPhi","cosPhi","u","format","_stereoFormat","ctx","leftEyeScaleOffset","rightEyeScaleOffset","uTexScaleOffset","uniform4fv","render","SphereRenderer","_TEXTURE_COORD_DATA","MIN_ASPECT_RATIO_FOR_FULL_PANORAMA","CylinderRenderer","resizeDimension","_b","imageAspectRatio","cylinderMaxRadian","halfCylinderY","rotated","CYLIDER_Y","startAngleForCenterAlign","yIdx","yLength","VR_DISPLAY_PRESENT_CHANGE","DEFAULT_LEFT_BOUNDS","DEFAULT_RIGHT_BOUNDS","EYES","LEFT","RIGHT","_vrDisplay","removeEndCallback","isPresenting","exitPresent","_clear","_frameData","VRFrameData","Boolean","bindFramebuffer","FRAMEBUFFER","submitFrame","display","halfWidth","drawingBufferWidth","drawingBufferHeight","getFrameData","leftMVMatrix","rightMVMatrix","mat4","_yawOffset","viewport","callback","getVRDisplays","displays","Promise","reject","Error","capabilities","canPresent","requestPresent","leftEye","rightEye","renderWidth","renderHeight","_setDisplay","layers","getLayers","layer","_leftBounds","leftBounds","_rightBounds","rightBounds","addEndCallback","XR_REFERENCE_SPACE","xrSession","_xrSession","end","_options","frame","getViewerPose","_xrRefSpace","session","baseLayer","renderState","framebuffer","glLayer","views","getViewport","transform","matrix","projectionMatrix","_presenting","requiredFeatures","attributes","getContextAttributes","xrCompatible","makeXRCompatible","requestSession","xrLayer","XRWebGLLayer","updateRenderState","requestReferenceSpace","refSpace","_setSession","_xrLayer","args","_callback","_rafId","_context","requestAnimationFrame","_onLoop","before","performance","now","diff","_rafTimer","_onLoopNextTick","cancelAnimationFrame","ImageType","DEVICE_PIXEL_RATIO","BIND_TEXTURE","IMAGE_LOADED","RENDERING_CONTEXT_RESTORE","RENDERER_ERROR","isVideo","container","sphericalConfig","renderingContextAttributes","vr","_vr","animator","_animator","exitVR","_restoreStyle","updateViewportDimensions","_updateViewport","_bindBuffers","_shouldForceDraw","stop","setContext","setCallback","_render","start","time","eyeParams","getEyeParams","beforeRender","eyeIndex","eyeParam","uniform1f","uEye","_draw","afterRender","canRender","minusZDir","mat3","mvInv","pInv","yawOffset","setYawOffset","_renderStereo","_lastQuaternion","_lastYaw","_lastPitch","_lastFieldOfView","textureCoordBuffer","vertexBuffer","_initCanvas","_setDefaultCanvasStyle","_wrapper","_wrapperOrigStyle","_renderingContextAttributes","_image","_imageConfig","_imageIsReady","_keepUpdate","_onContentLoad","_onContentError","WebGLAnimator","setImage","imageType","yawPitchControl","_yawPitchControl","_isVideo","_setImageType","_contentLoader","ImReady","rej","contentLoader","isReady","_bindTexture","once","errorCount","parentElement","_hasExternalCanvas","detach","hasRenderingContext","removeChild","forceContextLoss","_onWebglcontextlost","_onWebglcontextrestored","isContextLost","viewPortChanged","h","doUpdate","isImageLoaded","updateFieldOfView","_renderer","resolve","_requestPresent","_imageType","_isCubeMap","CubeStripRenderer","_initWebGL","canvasInContainer","querySelector","_createCanvas","className","margin","maxHeight","maxWidth","outline","content","_triggerContentLoad","renderer","vsSource","getVertexShaderSource","fsSource","getFragmentShaderSource","getErrorNameFromWebGLErrorCode","getError","useProgram","vertexPositionAttribute","getAttribLocation","samplerUniform","textureCoordAttribute","clear","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","STENCIL_BUFFER_BIT","uniform1i","preventDefault","_initRenderingContext","_initShaderProgram","clearColor","deleteTexture","CULL_FACE","WebGLRenderingContext","getIndexData","getTextureCoordData","initBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","Uint16Array","isEAC","updateShaderData","_initBuffers","getFov","shouldRenderWithQuaternion","getQuaternion","renderWithQuaternion","getYawPitch","renderWithYawPitch","_updateTexture","XRManager","VRManager","_onFirstVRFrame","_setWrapperFullscreen","wrapper","getAttribute","wrapperStyle","zIndex","removeAttribute","PanoImageRenderer","isWebGLAvailable","isStableWebGL","_container","_projectionType","_cubemapConfig","_width","_height","_yaw","_pitch","_fov","_gyroMode","_aspectRatio","_canvasClass","PanoViewer","_isValidTouchDirection","yawPitchConfig","_isReady","_initYawPitchControl","_initRenderer","onDeviceMotionChange","checkGyro","timeout","race","fb","TOUCH_DIRECTION","YAW","PITCH","ALL","_photoSphereRenderer","getContent","warn","_deactivate","keepUpdate","requestPermission","permissionState","enableSensor","enterVR","containerSize","lookAt","verticalAngleOfImage","initialYaw","initialPitch","setYawPitchControl","_bindRendererHandler","_activate","ProjectionType","yawSize","maxFov","atan","minFov","attachTo","_updateYawPitchIfNeeded","startRender","getVideo","pause","stopRender","SPINVIEWER_OPTIONS","imageUrl","rowCount","colCount","autoHeight","colRow","frameIndex","wrapperClass","imageClass","SPINVIEWER_EVENTS","LOAD","IMAGE_ERROR","CHANGE","DEFAULT_WRAPPER_CLASS","DEFAULT_IMAGE_CLASS","_el","_rowCount","_colCount","_totalCount","_autoHeight","_colRow","setFrameIndex","SpriteImage","_getSizeString","imageInContainer","wrapperInContainer","onload","_bg","_createBgDiv","setColRow","bgElement","_autoPlayReservedInfo","play","onerror","overflow","ondragstart","willChange","unitWidth","unitHeight","paddingBottom","toColRow","col","row","_autoPlayTimer","clearInterval","playCount","getFrameIndex","count","frameCount","setInterval","DEFAULT_PAN_SCALE","_scale","_panScale","_frameCount","_sprites","_panInput","curr","getColRow","SpinViewer","withMethods","component","vanillaInstance","proto","getOwnPropertyNames","startsWith","descriptor","getOwnPropertyDescriptor","defineProperty","call","getterDescriptor","withPanoViewerMethods","withSpinViewerMethods","panoViewer","newProps","prevProps","isPropChanged","setVideo","singleUpdateOptions","optionName","updateOption","prevVal","toUpperCase","getValidProps","propsObj","props","propName","generateCanvasKey","oldKey","newKey","array","Uint32Array","crypto","getRandomValues","View360","CFC"],"mappings":";;;;;;;;;;;;;;EAAA,IAAMA,OAAO,GAAG,OAAhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECAA;EAOA;;EACA,IAAMC,GAAG,GAAG,OAAOC,MAAP,KAAkB,WAAlB,IAAiCA,MAAM,CAACC,IAAP,KAAgBA,IAAjD,GACRD,MADQ,GAER,OAAOE,IAAP,KAAgB,WAAhB,IAA+BA,IAAI,CAACD,IAAL,KAAcA,IAA7C,GACEC,IADF,GAEEC,QAAQ,CAAC,aAAD,CAAR,EAJN;EAKA;;EAEA,IAAMC,GAAG,GAAGL,GAAG,CAACM,QAAhB;EACA,IAAMC,GAAG,GAAGP,GAAG,CAACQ,SAAhB;EACA,IAAMC,OAAK,GAAGC,KAAQ,EAAtB;EACA,IAAMC,MAAM,GAAGF,OAAK,CAACG,EAAN,CAASC,IAAxB;EACA,IAAMC,WAAW,GAAGL,OAAK,CAACM,OAAN,CAAcF,IAAlC;EACA,IAAMG,MAAM,GAAGL,MAAM,KAAK,KAA1B;EACA,IAAMM,oBAAoB,GAAGN,MAAM,KAAK,KAAX,IAAoBG,WAAW,KAAK,QAAjE;;ECrBA;EAOAd,GAAG,CAACkB,YAAJ,GAAoB,OAAOlB,GAAG,CAACkB,YAAX,KAA4B,WAA7B,GAA4ClB,GAAG,CAACkB,YAAhD,GAA+DlB,GAAG,CAACmB,KAAtF;EAEA,IAAMD,cAAY,GAAGlB,GAAG,CAACkB,YAAzB;EACA,IAAME,gBAAgB,GAAGpB,GAAG,CAACoB,gBAA7B;EACA,IAAMC,SAAS,GAAGrB,GAAG,CAACQ,SAAJ,IAAiBR,GAAG,CAACQ,SAAJ,CAAca,SAAjD;EACA,IAAMC,aAAa,IAAG,kBAAkBtB,GAArB,CAAnB;EACA,IAAMuB,oBAAoB,IAAG,oBAAoBvB,GAAvB,CAA1B;EACA,IAAMwB,iBAAiB,GAAGxB,GAAG,CAACwB,iBAA9B;EACA,IAAMC,gBAAgB,GAAGzB,GAAG,CAACyB,gBAA7B;;EAEA,IAAMC,SAAS,GAAI;;;EACjB,MAAMC,QAAQ,SAAGtB,GAAG,SAAH,IAAAA,GAAG,WAAH,SAAA,GAAAA,GAAG,CAAEuB,eAAL,CAAqBC,wCAAS,EAA/C;EACA,MAAMC,MAAM,GAAG,CAAC,WAAD,EAAc,iBAAd,EAAiC,aAAjC,EAAgD,cAAhD,CAAf;;EAEA,OAAK,IAAIC,CAAC,GAAG,CAAR,EAAWC,GAAG,GAAGF,MAAM,CAACG,MAA7B,EAAqCF,CAAC,GAAGC,GAAzC,EAA8CD,CAAC,EAA/C,EAAmD;EACjD,QAAID,MAAM,CAACC,CAAD,CAAN,IAAaJ,QAAjB,EAA2B;EACzB,aAAOG,MAAM,CAACC,CAAD,CAAb;EACD;EACF;;EACD,SAAO,EAAP;EACD,CAViB,EAAlB;;;EAaA,IAAMG,kBAAkB,GAAGlC,GAAG,CAACmC,GAAJ,IAAWnC,GAAG,CAACmC,GAAJ,CAAQC,QAAnB,IAC1BpC,GAAG,CAACmC,GAAJ,CAAQC,QAAR,CAAiB,aAAjB,EAAgC,WAAhC,CADD;EAGA,IAAIC,eAAe,GAAG,KAAtB;;EAEA,IAAMC,cAAc,GAAG;EACrB,MAAM9B,SAAS,GAAGP,MAAM,CAACO,SAAzB;;EAEA,MAAI,CAACA,SAAS,CAAC+B,EAAf,EAAmB;EACjB;EACD;;EAED,MAAI/B,SAAS,CAAC+B,EAAV,CAAaC,kBAAjB,EAAqC;EACnChC,IAAAA,SAAS,CAAC+B,EAAV,CAAaC,kBAAb,CAAgC,cAAhC,EAAgDC,IAAhD,CAAqD,UAAAC,GAAA;EACnDL,MAAAA,eAAe,GAAGK,GAAlB;EACD,KAFD,EAEGC,KAFH,CAES;EAAM,aAAA,KAAK,CAAL;EAAM,KAFrB;EAGD,GAJD,MAIO,IAAInC,SAAS,CAAC+B,EAAV,CAAaK,eAAjB,EAAkC;EACvCpC,IAAAA,SAAS,CAAC+B,EAAV,CAAaK,eAAb,CAA6B,cAA7B,EAA6CH,IAA7C,CAAkD,UAAAC,GAAA;EAChDL,MAAAA,eAAe,GAAGK,GAAlB;EACD,KAFD,EAEGC,KAFH,CAES;EAAM,aAAA,KAAK,CAAL;EAAM,KAFrB;EAGD;EACF,CAhBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"} \ No newline at end of file diff --git a/dist/view360.pkgd.min.js b/dist/view360.pkgd.min.js new file mode 100644 index 000000000..1343069ed --- /dev/null +++ b/dist/view360.pkgd.min.js @@ -0,0 +1,10 @@ +/* +Copyright (c) 2017-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 3.6.3 +*/ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):((t="undefined"!=typeof globalThis?globalThis:t||self).eg=t.eg||{},t.eg.view360=e())}(this,function(){"use strict";var i="3.6.3",r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)};function s(t,e){function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var h=function(){return(h=Object.assign||function(t){for(var e,n=1,i=arguments.length;na[0]&&e[1]=t.length&&(t=void 0),{value:t&&t[i++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function f(){for(var t=[],e=0;e=t.length&&(t=void 0),{value:t&&t[i++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function a(){for(var t=[],e=0;e]*)>/)?((n=document.createElement("div")).innerHTML=t,nt(n.childNodes)):nt(document.querySelectorAll(t)),e||(n=1<=n.length?n[0]:void 0)):t!==at&&(!t.nodeName||1!==t.nodeType&&9!==t.nodeType)?"jQuery"in at&&t instanceof jQuery||t.constructor.prototype.jquery?n=e?t.toArray():t.get(0):Array.isArray(t)&&(n=t.map(function(t){return lt(t)}),e||(n=1<=n.length?n[0]:void 0)):n=t,n},dt=at.requestAnimationFrame||at.webkitRequestAnimationFrame,ft=at.cancelAnimationFrame||at.webkitCancelAnimationFrame;dt&&!ft?(it={},rt=dt,dt=function(e){var n=rt(function(t){it[n]&&e(t)});return it[n]=!0,n},ft=function(t){delete it[t]}):dt&&ft||(dt=function(t){return at.setTimeout(function(){t(at.performance&&at.performance.now&&at.performance.now()||(new Date).getTime())},16)},ft=at.clearTimeout);function _t(t,e){var n,i={};for(n in t)n&&(i[n]=e(t[n],n));return i}function pt(t,e){var n,i={};for(n in t)n&&e(t[n],n)&&(i[n]=t[n]);return i}function vt(t,e){for(var n in t)if(n&&!e(t[n],n))return!1;return!0}function gt(t,n){return vt(t,function(t,e){return t===n[e]})}function mt(t,e){return Ot[e]||(Ot[e]=Dt(e)),Ot[e](t)}function yt(t,n){return t&&n?_t(t,function(t,e){return mt(t,"number"==typeof n?n:n[e])}):t}function Et(t){if(!isFinite(t))return 0;var e=""+t;if(0<=e.indexOf("e")){for(var n=0,i=1;Math.round(t*i)/i!==t;)i*=10,n++;return n}return 0<=e.indexOf(".")?e.length-e.indexOf(".")-1:0}function xt(e){var n=!0;return Object.keys(ct).forEach(function(t){e&&e[t]===ct[t]||(n=!1)}),n}function wt(e,t,n){var i,r=((r={})[1]="auto",r[30]="none",r[24]="pan-x",r[6]="pan-y",r),o={};return e&&e.style&&(n=t.touchAction||r[n],i=ot(ot({},ct),{"touch-action":"none"===e.style["touch-action"]?"none":n}),Object.keys(i).forEach(function(t){o[t]=e.style[t],e.style[t]=i[t]})),o}function Rt(e,n){e&&e.style&&n&&Object.keys(n).forEach(function(t){e.style[t]=n[t]})}function Tt(t,e,n,i){return e=[!n[0]&&i?e[0]-i[0]:e[0],!n[1]&&i?e[1]+i[1]:e[1]],t=Math.max(e[0],t),t=Math.min(e[1],t)}function bt(t,e){return te[1]}function Ct(t,e,n){return n[1]&&t>e[1]||n[0]&&te.range[1]&&0!==e.bounce[1]?(t-e.range[1])/e.bounce[1]:0})},t}(),Lt=function(){function t(t){this._options=t,this._prevented=!1}var e=t.prototype;return e.isInterrupting=function(){return this._options.interruptable||this._prevented},e.isInterrupted=function(){return!this._options.interruptable&&this._prevented},e.setInterrupt=function(t){this._options.interruptable||(this._prevented=t)},t}(),Ft=function(){function t(t){var n=this;this._axis=t,this._complementOptions(),this._pos=Object.keys(this._axis).reduce(function(t,e){return t[e]=n._axis[e].range[0],t},{})}var e=t.prototype;return e.getDelta=function(t,e){var n=this.get(t);return _t(this.get(e),function(t,e){return t-n[e]})},e.get=function(t){var n=this;return t&&Array.isArray(t)?t.reduce(function(t,e){return e&&e in n._pos&&(t[e]=n._pos[e]),t},{}):ot(ot({},this._pos),t||{})},e.moveTo=function(n,i){void 0===i&&(i=this._pos);var t=_t(this._pos,function(t,e){return e in n&&e in i?n[e]-i[e]:0});return this.set(this.map(n,function(t,e){return e?Pt(t,e.range,e.circular):0})),{pos:ot({},this._pos),delta:t}},e.set=function(t){for(var e in t)e&&e in this._pos&&(this._pos[e]=t[e])},e.every=function(t,n){var i=this._axis;return vt(t,function(t,e){return n(t,i[e],e)})},e.filter=function(t,n){var i=this._axis;return pt(t,function(t,e){return n(t,i[e],e)})},e.map=function(t,n){var i=this._axis;return _t(t,function(t,e){return n(t,i[e],e)})},e.isOutside=function(t){return!this.every(t?this.get(t):this._pos,function(t,e){return!bt(t,e.range)})},e.getAxisOptions=function(t){return this._axis[t]},e._complementOptions=function(){var r=this;Object.keys(this._axis).forEach(function(i){r._axis[i]=ot({range:[0,100],bounce:[0,0],circular:[!1,!1]},r._axis[i]),["bounce","circular"].forEach(function(t){var e=r._axis,n=e[i][t];/string|number|boolean/.test(typeof n)&&(e[i][t]=[n,n])})})},t}(),Nt="ontouchstart"in at,Ut="PointerEvent"in at,kt="MSPointerEvent"in at,Qt=Ut||kt,t=function(){function t(){var e=this;this._stopContextMenu=function(t){t.preventDefault(),at.removeEventListener("contextmenu",e._stopContextMenu)}}var e=t.prototype;return e.extendEvent=function(t){var e=this.prevEvent,n=this._getCenter(t),i=e?this._getMovement(t):{x:0,y:0},r=e?this._getScale(t):1,o=e?(d=n.x-e.center.x,l=n.y-e.center.y,180*Math.atan2(l,d)/Math.PI):0,a=e?e.deltaX+i.x:i.x,s=e?e.deltaY+i.y:i.y,u=i.x,h=i.y,c=this._latestInterval,l=Date.now(),d=c?l-c.timestamp:0,i=e?e.velocityX:0,e=e?e.velocityY:0;return(!c||16<=d)&&(c&&(i=(d=[(a-c.deltaX)/d,(s-c.deltaY)/d])[0],e=d[1]),this._latestInterval={timestamp:l,deltaX:a,deltaY:s}),{srcEvent:t,scale:r,angle:o,center:n,deltaX:a,deltaY:s,offsetX:u,offsetY:h,velocityX:i,velocityY:e,preventSystemEvent:!0}},e._getDistance=function(t,e){var n=e.clientX-t.clientX,t=e.clientY-t.clientY;return Math.sqrt(n*n+t*t)},e._getButton=function(t){var e={1:st,2:"right",4:"middle"},t=this._isTouchEvent(t)?st:e[t.buttons];return t||null},e._isTouchEvent=function(t){return-1=n[e]-1e-6&&t<=n[e]+1e-6)return n[e];e=i._getRoundUnit(t,e);return mt(t,e)})},e._getRoundUnit=function(t,e){var n=this._options.round,i=null;return n||(e=this.axisManager.getAxisOptions(e),t=Math.max(Et(e.range[0]),Et(e.range[1]),Et(t)),i=1/Math.pow(10,t)),i||n},t}()),jt=function(r){function t(t,e,n){void 0===t&&(t={}),void 0===e&&(e={}),void 0===n&&(n=null);var i=r.call(this)||this;return i.axis=t,i._inputs=[],i.options=ot({easing:function(t){return 1-Math.pow(1-t,3)},interruptable:!0,maximumDuration:1/0,minimumDuration:0,deceleration:6e-4,round:null,nested:!1},e),i.interruptManager=new Lt(i.options),i.axisManager=new Ft(i.axis),i.eventManager=new Vt(i),i.animationManager=new Yt(i),i.inputObserver=new Gt(i),i.eventManager.setAnimationManager(i.animationManager),n&&i.eventManager.triggerChange(n),i}et(t,r);var e=t.prototype;return e.connect=function(t,e){t="string"==typeof t?t.split(" "):t.concat();return~this._inputs.indexOf(e)&&this.disconnect(e),e.mapAxes(t),e.connect(this.inputObserver),this._inputs.push(e),this},e.disconnect=function(t){return t?0<=(t=this._inputs.indexOf(t))&&(this._inputs[t].disconnect(),this._inputs.splice(t,1)):(this._inputs.forEach(function(t){return t.disconnect()}),this._inputs=[]),this},e.get=function(t){return this.axisManager.get(t)},e.setTo=function(t,e){return void 0===e&&(e=0),this.animationManager.setTo(t,e),this},e.setBy=function(t,e){return void 0===e&&(e=0),this.animationManager.setBy(t,e),this},e.stopAnimation=function(){return this.animationManager.stopAnimation(),this},e.updateAnimation=function(t){return this.animationManager.updateAnimation(t),this},e.isBounceArea=function(t){return this.axisManager.isOutside(t)},e.destroy=function(){this.disconnect(),this.eventManager.destroy()},t.VERSION="3.3.0",t.TRANSFORM=ht,t.DIRECTION_NONE=1,t.DIRECTION_LEFT=2,t.DIRECTION_RIGHT=4,t.DIRECTION_UP=8,t.DIRECTION_DOWN=16,t.DIRECTION_HORIZONTAL=6,t.DIRECTION_VERTICAL=24,t.DIRECTION_ALL=30,t}(e),Ht=function(){function t(t,e){var n=this;this.axes=[],this.element=null,this._enabled=!1,this._activeEvent=null,this._atRightEdge=!1,this._rightEdgeTimer=0,this._forceRelease=function(){var t=n._activeEvent,e=t.prevEvent;t.onRelease(),n._observer.release(n,e,[0,0]),n._detachWindowEvent(t)},this._voidFunction=function(){},this.element=lt(t),this.options=ot({inputType:["touch","mouse","pointer"],inputButton:[st],scale:[1,1],thresholdAngle:45,threshold:0,iOSEdgeSwipeThreshold:30,releaseOnScroll:!1,touchAction:null},e),this._onPanstart=this._onPanstart.bind(this),this._onPanmove=this._onPanmove.bind(this),this._onPanend=this._onPanend.bind(this)}var e=t.prototype;return e.mapAxes=function(t){var e=!!t[0],n=!!t[1];this._direction=e&&n?30:e?6:n?24:1,this.axes=t},e.connect=function(t){return this._activeEvent&&(this._detachElementEvent(),this._detachWindowEvent(this._activeEvent)),this._attachElementEvent(t),this._originalCssProps=wt(this.element,this.options,this._direction),this},e.disconnect=function(){return this._detachElementEvent(),this._detachWindowEvent(this._activeEvent),xt(this._originalCssProps)||Rt(this.element,this._originalCssProps),this._direction=1,this},e.destroy=function(){this.disconnect(),this.element=null},e.enable=function(){return this._enabled=!0,this},e.disable=function(){return this._enabled=!1,this},e.isEnabled=function(){return this._enabled},e._onPanstart=function(t){var e=this._activeEvent,n=e.onEventStart(t,this.options.inputButton);!n||!this._enabled||1window.innerWidth-t,this._attachWindowEvent(e),e.prevEvent=n)},e._onPanmove=function(t){var e=this,n=this._activeEvent,i=n.onEventMove(t,this.options.inputButton);if(i&&this._enabled&&!(1Math.abs(t.z)?Ye.set(-t.y,t.x,0):Ye.set(0,-t.z,t.y)):Ye.crossVectors(t,e),this.x=Ye.x,this.y=Ye.y,this.z=Ye.z,this.w=je,this.normalize(),this}};var tn,en,nn,rn,on,an,sn,un,hn,cn=null!==(z=null==Q?void 0:Q.userAgent)&&void 0!==z?z:"",ln=U.Util||{};function dn(t,e,n,i,r){c=t,a=i?i.fieldOfView:null,o=r.depthNear,h=r.depthFar,l=Math.tan(a?a.upDegrees*an:sn),u=Math.tan(a?a.downDegrees*an:sn),f=Math.tan(a?a.leftDegrees*an:sn),d=Math.tan(a?a.rightDegrees*an:sn),s=2/(f+d),a=2/(l+u),c[0]=s,c[1]=0,c[2]=0,c[3]=0,c[4]=0,c[5]=a,c[6]=0,c[7]=0,c[8]=-(f-d)*s*.5,c[9]=(l-u)*a*.5,c[10]=h/(o-h),c[11]=-1,c[12]=0,c[13]=0,c[14]=h*o/(o-h),c[15]=0;var o,a,s,u,h,c,l,d,f,_,p,v,g,m,y,E,x,w,R,T,b,C,P,M,I,A,t=n.orientation||un,r=n.position||hn;f=e,d=r,l=(s=t)[0],u=s[1],a=s[2],o=s[3],c=l*(h=l+l),r=l*(n=u+u),s=l*(t=a+a),l=u*n,u*=t,a*=t,h*=o,n*=o,t*=o,f[0]=1-(l+a),f[1]=r+t,f[2]=s-n,f[3]=0,f[4]=r-t,f[5]=1-(c+a),f[6]=u+h,f[7]=0,f[8]=s+n,f[9]=u-h,f[10]=1-(c+l),f[11]=0,f[12]=d[0],f[13]=d[1],f[14]=d[2],f[15]=1,i&&(b=I=e,T=i.offset,M=T[0],P=T[1],C=T[2],b===I?(I[12]=b[0]*M+b[4]*P+b[8]*C+b[12],I[13]=b[1]*M+b[5]*P+b[9]*C+b[13],I[14]=b[2]*M+b[6]*P+b[10]*C+b[14],I[15]=b[3]*M+b[7]*P+b[11]*C+b[15]):(_=b[0],g=b[1],E=b[2],w=b[3],p=b[4],m=b[5],A=b[6],R=b[7],v=b[8],y=b[9],x=b[10],T=b[11],I[0]=_,I[1]=g,I[2]=E,I[3]=w,I[4]=p,I[5]=m,I[6]=A,I[7]=R,I[8]=v,I[9]=y,I[10]=x,I[11]=T,I[12]=_*M+p*P+v*C+b[12],I[13]=g*M+m*P+y*C+b[13],I[14]=E*M+A*P+x*C+b[14],I[15]=w*M+R*P+T*C+b[15])),a=(t=r=e)[0],s=t[1],n=t[2],u=t[3],h=t[4],c=t[5],l=t[6],d=t[7],f=t[8],i=t[9],_=t[10],p=t[11],v=t[12],g=t[13],m=t[14],y=t[15],(t=(E=a*c-s*h)*(A=_*y-p*m)-(x=a*l-n*h)*(I=i*y-p*g)+(w=a*d-u*h)*(M=i*m-_*g)+(R=s*l-n*c)*(P=f*y-p*v)-(T=s*d-u*c)*(C=f*m-_*v)+(b=n*d-u*l)*(e=f*g-i*v))&&(t=1/t,r[0]=(c*A-l*I+d*M)*t,r[1]=(n*I-s*A-u*M)*t,r[2]=(g*b-m*T+y*R)*t,r[3]=(_*T-i*b-p*R)*t,r[4]=(l*P-h*A-d*C)*t,r[5]=(a*A-n*P+u*C)*t,r[6]=(m*w-v*b-y*x)*t,r[7]=(f*b-_*w+p*x)*t,r[8]=(h*I-c*P+d*e)*t,r[9]=(s*P-a*I-u*e)*t,r[10]=(v*T-g*w+y*E)*t,r[11]=(i*w-f*T-p*E)*t,r[12]=(c*C-h*M-l*e)*t,r[13]=(a*M-s*C+n*e)*t,r[14]=(g*x-v*R-m*E)*t,r[15]=(f*R-i*x+_*E)*t)}ln.MIN_TIMESTEP=.001,ln.MAX_TIMESTEP=1,ln.base64=function(t,e){return"data:"+t+";base64,"+e},ln.clamp=function(t,e,n){return Math.min(Math.max(e,t),n)},ln.lerp=function(t,e,n){return t+(e-t)*n},ln.isIOS=(tn=/iPad|iPhone|iPod/.test(null==Q?void 0:Q.platform),function(){return tn}),ln.isWebViewAndroid=(en=-1!==cn.indexOf("Version")&&-1!==cn.indexOf("Android")&&-1!==cn.indexOf("Chrome"),function(){return en}),ln.isSafari=(nn=/^((?!chrome|android).)*safari/i.test(cn),function(){return nn}),ln.isFirefoxAndroid=(rn=-1!==cn.indexOf("Firefox")&&-1!==cn.indexOf("Android"),function(){return rn}),ln.isR7=(on=-1!==cn.indexOf("R7 Build"),function(){return on}),ln.isLandscapeMode=function(){var t=90===U.orientation||-90===U.orientation;return ln.isR7()?!t:t},ln.isTimestampDeltaValid=function(t){return!isNaN(t)&&(!(t<=ln.MIN_TIMESTEP)&&!(t>ln.MAX_TIMESTEP))},ln.getScreenWidth=function(){return Math.max(U.screen.width,U.screen.height)*U.devicePixelRatio},ln.getScreenHeight=function(){return Math.min(U.screen.width,U.screen.height)*U.devicePixelRatio},ln.requestFullscreen=function(t){if(ln.isWebViewAndroid())return!1;if(t.requestFullscreen)t.requestFullscreen();else if(t.webkitRequestFullscreen)t.webkitRequestFullscreen();else if(t.mozRequestFullScreen)t.mozRequestFullScreen();else{if(!t.msRequestFullscreen)return!1;t.msRequestFullscreen()}return!0},ln.exitFullscreen=function(){if(k.exitFullscreen)k.exitFullscreen();else if(k.webkitExitFullscreen)k.webkitExitFullscreen();else if(k.mozCancelFullScreen)k.mozCancelFullScreen();else{if(!k.msExitFullscreen)return!1;k.msExitFullscreen()}return!0},ln.getFullscreenElement=function(){return k.fullscreenElement||k.webkitFullscreenElement||k.mozFullScreenElement||k.msFullscreenElement},ln.linkProgram=function(t,e,n,i){var r=t.createShader(t.VERTEX_SHADER);t.shaderSource(r,e),t.compileShader(r);e=t.createShader(t.FRAGMENT_SHADER);t.shaderSource(e,n),t.compileShader(e);var o,a=t.createProgram();for(o in t.attachShader(a,r),t.attachShader(a,e),i)t.bindAttribLocation(a,i[o],o);return t.linkProgram(a),t.deleteShader(r),t.deleteShader(e),a},ln.getProgramUniforms=function(t,e){for(var n={},i=t.getProgramParameter(e,t.ACTIVE_UNIFORMS),r="",o=0;oe[1]&&(i=e[1]),n!==i&&(o.setTo({fov:i},0),this._updateControlScale(),this.updatePanScale())),t.some(function(t){return"gyroMode"===t})&&j&&(this._axesTiltMotionInput&&(this._axes.disconnect(this._axesTiltMotionInput),this._axesTiltMotionInput.destroy(),this._axesTiltMotionInput=null),this._deviceQuaternion&&(this._deviceQuaternion.destroy(),this._deviceQuaternion=null),a?this._initDeviceQuaternion():s&&(this._axesTiltMotionInput=new mn(this._element),this._axes.connect(["yaw","pitch"],this._axesTiltMotionInput)),this._axesPanInput.setUseRotation(a)),t.some(function(t){return"useKeyboard"===t})&&(r.useKeyboard?o.connect(["yaw","pitch"],this._axesMoveKeyInput):o.disconnect(this._axesMoveKeyInput)),t.some(function(t){return"useZoom"===t})&&(a=r.useZoom,o.disconnect(this._axesWheelInput),a&&o.connect(["fov"],this._axesWheelInput)),this._togglePinchInputByOption(r.touchDirection,r.useZoom),t.some(function(t){return"touchDirection"===t})&&this._enabled&&this._enableTouch(u)},e._togglePinchInputByOption=function(t,e){this._axesPinchInput&&(this._axes.disconnect(this._axesPinchInput),e&&6===t&&-1===this._axes._inputs.indexOf(this._axesPinchInput)&&this._axes.connect(["fov"],this._axesPinchInput))},e._enableTouch=function(t){this._axesPanInput&&this._axes.disconnect(this._axesPanInput);var e=2&t?"yaw":null,t=4&t?"pitch":null;this._axes.connect([e,t],this._axesPanInput)},e._initDeviceQuaternion=function(){var e=this;this._deviceQuaternion=new Tn,this._deviceQuaternion.on("change",function(t){e._triggerChange(t)})},e._getValidYawRange=function(t,e,n){n=this._adjustAspectRatio(n||this.options.aspectRatio||1),n=(e||this._axes.get().fov)*n;return t[1]-t[0]>=n?t:this.options.yawRange||bn},e._getValidPitchRange=function(t,e){e=e||this._axes.get().fov;return t[1]-t[0]>=e?t:this.options.pitchRange||Cn},e._isCircular=function(t){return t[1]-t[0]<360?[!1,!1]:[!0,!0]},e._updateControlScale=function(t){var e=this.options,n=this._axes.get().fov,i=this._updatePitchRange(e.pitchRange,n,e.showPolePoint),r=this._updateYawRange(e.yawRange,n,e.aspectRatio),n=this._axes.get(),e=n.yaw,n=n.pitch;return Ue(this._axes.axis.yaw.range,r),Ue(this._axes.axis.pitch.range,i),this._axes.axis.yaw.circular=this._isCircular(r),this._axes.axis.pitch.circular=this._isCircular(i),er[1]&&(e=r[1]),ni[1]&&(n=i[1]),t&&t.set({yaw:e,pitch:n}),this._axes.setTo({yaw:e,pitch:n},0),this},e._updatePitchRange=function(t,e,n){if(this.options.gyroMode===Je.VR)return Pn;var i=t[1]-t[0],e=e/2;return!n||i<180?[t[0]+e,t[1]-e]:t.concat()},e._updateYawRange=function(t,e,n){if(this.options.gyroMode===Je.VR)return bn;if(360<=t[1]-t[0])return t.concat();e=We.toDegree(Math.atan2(n,1/Math.tan(e/2*te)));return[t[0]+e,t[1]-e]},e._triggerChange=function(t){var e=this._axes.get(),n=this.options,t={targetElement:n.element,isTrusted:t.isTrusted,yaw:e.yaw,pitch:e.pitch,fov:e.fov,quaternion:null};n.gyroMode===Je.VR&&this._deviceQuaternion&&(t.quaternion=this._deviceQuaternion.getCombinedQuaternion(e.yaw)),this.trigger(new _("change",t))},e._adjustAspectRatio=function(t){for(var e=[.52,.54,.563,.57,.584,.59,.609,.67,.702,.72,.76,.78,.82,.92,.97,1,1.07,1.14,1.19,1.25,1.32,1.38,1.4,1.43,1.53,1.62,1.76,1.77,1.86,1.96,2.26,2.3,2.6,3,5,6],n=[.51,.54,.606,.56,.628,.63,.647,.71,.736,.757,.78,.77,.8,.89,.975,1,1.07,1.1,1.15,1.18,1.22,1.27,1.3,1.33,1.39,1.45,1.54,1.55,1.58,1.62,1.72,1.82,1.92,2,2.24,2.3],i=-1,r=0;r=t.length&&(t=void 0),{value:t&&t[i++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}(a),h=u.next();!h.done;h=u.next()){if(h.value===e){a.splice(s,1);break}s++}}catch(t){n={error:t}}finally{try{h&&!h.done&&(i=u.return)&&i.call(u)}finally{if(n)throw n.error}}}return this},t.VERSION="2.2.2",t}(),An=function(t,e){return(An=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])})(t,e)};function Sn(t,e){function n(){this.constructor=t}An(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)}var On=function(){return(On=Object.assign||function(t){for(var e,n=1,i=arguments.length;n= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}"},n.getVertexPositionData=function(){return this._vertices||(this._vertices=[1,-1,1,-1,-1,1,-1,1,1,1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,1,-1,-1,-1,-1,1,-1,-1,1,1]),this._vertices},n.getIndexData=function(){var n=this;return function(){for(var t=[],e=0;ethis._rowCount-1||t>this._colCount-1||(this._image&&K&&(this._image.style[K]="translate("+-(t/this._colCount)*100+"%, "+-(e/this._rowCount)*100+"%)"),this._colRow=[t,e])},t.getColRow=function(){return this._colRow},t.stop=function(){this._autoPlayTimer&&(clearInterval(this._autoPlayTimer),this._autoPlayTimer=-1)},t.play=function(t){var e,n,i,r=this,o=void 0===t?{interval:1e3/this._totalCount,playCount:0}:t,t=o.interval,a=o.playCount;this._bg?(this._autoPlayTimer&&(clearInterval(this._autoPlayTimer),this._autoPlayTimer=-1),e=this.getFrameIndex(),i=n=0,this._autoPlayTimer=window.setInterval(function(){e%=r._totalCount;var t=r.toColRow(e);r.setColRow(t[0],t[1]),e++,++i===r._totalCount&&(i=0,n++),0=this._totalCount?[e-1,n-1]:[t%e,Math.floor(t/e)]},h.VERSION=i,h}(e),Zi=function(o){function t(t,e){void 0===e&&(e={});var n=o.call(this)||this;n._el=t;var i=h({},e),r=i.colCount||1,e=i.rowCount||1;return n._scale=i.scale||1,n._panScale=.21*n._scale,n._frameCount=r*e,n._sprites=new Ki(t,i).on({load:function(t){n.trigger(new _("load",t))},imageError:function(t){n.trigger(new _("imageError",{imageUrl:t.imageUrl}))}}),n._panInput=new Ht(n._el,{scale:[n._panScale,n._panScale]}),n._axes=new jt({angle:{range:[0,359],circular:!0}}).on({change:function(t){var e=Math.floor(t.pos.angle/(360/n._frameCount)),e=n._frameCount-e-1;n._sprites.setFrameIndex(e),n.trigger(new _("change",{frameIndex:e,colRow:n._sprites.getColRow(),angle:t.pos.angle}))},animationEnd:function(t){n.trigger(new _("animationEnd",{isTrusted:t.isTrusted}))}}),n._axes.connect("angle",n._panInput),n}s(t,o);var e=t.prototype;return e.setScale=function(t){return isNaN(t)||t<0||(this._scale=t,this._panScale=.21*t,this._panInput.options.scale=[this._panScale,this._panScale]),this},e.getScale=function(){return this._scale},e.spinBy=function(t,e){return void 0===t&&(t=0),void 0===e&&(e={duration:0}),this._axes.setBy({angle:t},e.duration),this},e.spinTo=function(t,e){return void 0===t&&(t=0),void 0===e&&(e={duration:0}),this._axes.setTo({angle:t},e.duration),this},e.getAngle=function(){return this._axes.get().angle||0},t.VERSION=i,t}(e),G={__proto__:null,SpinViewer:Zi,SpriteImage:Ki,VERSION:i,SPINVIEWER_OPTIONS:{imageUrl:!0,rowCount:!0,colCount:!0,width:!0,height:!0,autoHeight:!0,colRow:!0,scale:!0,frameIndex:!0,wrapperClass:!0,imageClass:!0},SPINVIEWER_EVENTS:{LOAD:"load",IMAGE_ERROR:"imageError",CHANGE:"change",ANIMATION_END:"animationEnd"},DEFAULT_WRAPPER_CLASS:Hi,DEFAULT_IMAGE_CLASS:qi},Ji=function(t,e){return null!=t&&t!==e},$i=function(t,e,n,i){Ji(n[e],i[e])&&t["set"+e[0].toUpperCase()+e.slice(1)](n[e])},kt={__proto__:null,withMethods:Wi,withPanoViewerMethods:function(t,e){Wi(ji,t,e)},withSpinViewerMethods:function(t,e){Wi(Zi,t,e)},updatePanoViewer:function(e,n,i){Ji(n.image,i.image)?e.setImage(n.image,{projectionType:n.projectionType,cubemapConfig:n.cubemapConfig,stereoFormat:n.stereoFormat,isVideo:!1}):Ji(n.video,i.video)&&e.setVideo(n.video,{projectionType:n.projectionType,cubemapConfig:n.cubemapConfig,stereoFormat:n.stereoFormat});["fovRange","gyroMode","pitchRange","showPolePoint","touchDirection","useKeyboard","useZoom","yawRange"].forEach(function(t){$i(e,t,n,i)})},getValidProps:function(n){return Object.keys(n).reduce(function(t,e){return null!=n[e]&&(t[e]=n[e]),t},{})},generateCanvasKey:function(t){var e;do{var n=new Uint32Array(1)}while(crypto.getRandomValues(n),(e=n[0])===t);return e}},q={};return ri(q,z),ri(q,G),ri(q,kt),q}); +//# sourceMappingURL=view360.pkgd.min.js.map diff --git a/dist/view360.pkgd.min.js.map b/dist/view360.pkgd.min.js.map new file mode 100644 index 000000000..eaa449331 --- /dev/null +++ b/dist/view360.pkgd.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.pkgd.min.js","sources":["../src/version.ts","../src/utils/browser.ts","../src/utils/browserFeature.ts","../src/utils/math-util.ts","../src/YawPitchControl/consts.ts","../src/YawPitchControl/input/lib/webvr-polyfill/math-util.ts","../src/YawPitchControl/input/lib/webvr-polyfill/util.ts","../src/YawPitchControl/input/lib/webvr-polyfill/pose-predictor.ts","../src/YawPitchControl/input/DeviceMotion.ts","../src/YawPitchControl/input/lib/webvr-polyfill/sensor-sample.ts","../src/YawPitchControl/input/lib/webvr-polyfill/complementary-filter.ts","../src/YawPitchControl/input/ComplementaryFilter.ts","../src/YawPitchControl/input/FusionPoseSensor.ts","../src/YawPitchControl/input/TiltMotionInput.ts","../src/YawPitchControl/utils.ts","../src/YawPitchControl/ScreenRotationAngle.ts","../src/YawPitchControl/input/RotationPanInput.ts","../src/YawPitchControl/DeviceQuaternion.ts","../src/YawPitchControl/YawPitchControl.ts","../src/PanoImageRenderer/renderer/SphereRenderer.ts","../src/PanoViewer/consts.ts","../src/utils/utils.ts","../src/PanoImageRenderer/WebGLUtils.ts","../src/PanoImageRenderer/renderer/Renderer.ts","../src/PanoImageRenderer/renderer/CubeRenderer.ts","../src/PanoImageRenderer/renderer/CubeStripRenderer.ts","../src/PanoImageRenderer/renderer/CylinderRenderer.ts","../src/PanoImageRenderer/vr/VRManager.ts","../src/PanoImageRenderer/vr/XRManager.ts","../src/PanoImageRenderer/WebGLAnimator.ts","../src/PanoImageRenderer/PanoImageRenderer.ts","../src/cfc/withMethods.ts","../src/PanoViewer/PanoViewer.ts","../src/SpinViewer/consts.ts","../src/SpinViewer/SpriteImage.ts","../src/SpinViewer/SpinViewer.ts","../src/cfc/updatePanoViewer.ts","../src/cfc/withPanoViewerMethods.ts","../src/cfc/withSpinViewerMethods.ts","../src/cfc/utils.ts","../src/index.umd.ts"],"sourcesContent":["const VERSION = \"#__VERSION__#\";\n\nexport {\n VERSION\n};\n","/* eslint-disable @typescript-eslint/no-implied-eval */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport getAgent from \"@egjs/agent\";\n\n/* eslint-disable no-new-func, no-nested-ternary */\nconst win = typeof window !== \"undefined\" && window.Math === Math\n ? window\n : typeof self !== \"undefined\" && self.Math === Math\n ? self\n : Function(\"return this\")();\n/* eslint-enable no-new-func, no-nested-ternary */\n\nconst doc = win.document;\nconst nav = win.navigator;\nconst agent = getAgent();\nconst osName = agent.os.name;\nconst browserName = agent.browser.name;\nconst IS_IOS = osName === \"ios\";\nconst IS_SAFARI_ON_DESKTOP = osName === \"mac\" && browserName === \"safari\";\nconst IS_SAMSUNG_BROWSER = browserName === \"samsung internet\";\n\nexport {\n win as window,\n doc as document,\n nav as navigator,\n IS_IOS,\n IS_SAFARI_ON_DESKTOP,\n IS_SAMSUNG_BROWSER\n};\n","/* eslint-disable @typescript-eslint/naming-convention */\n/**\n * Copyright (c) 2015 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { window as win, document as doc } from \"./browser\";\n\nwin.Float32Array = (typeof win.Float32Array !== \"undefined\") ? win.Float32Array : win.Array;\n\nconst Float32Array = win.Float32Array;\nconst getComputedStyle = win.getComputedStyle;\nconst userAgent = win.navigator && win.navigator.userAgent;\nconst SUPPORT_TOUCH = \"ontouchstart\" in win;\nconst SUPPORT_DEVICEMOTION = \"ondevicemotion\" in win;\nconst DeviceMotionEvent = win.DeviceMotionEvent;\nconst devicePixelRatio = win.devicePixelRatio;\n\nconst TRANSFORM = (() => {\n const docStyle = doc?.documentElement.style ?? {};\n const target = [\"transform\", \"webkitTransform\", \"msTransform\", \"mozTransform\"];\n\n for (let i = 0, len = target.length; i < len; i++) {\n if (target[i] in docStyle) {\n return target[i];\n }\n }\n return \"\";\n})();\n\n// check for will-change support\nconst SUPPORT_WILLCHANGE = win.CSS && win.CSS.supports &&\n\twin.CSS.supports(\"will-change\", \"transform\");\n\nlet WEBXR_SUPPORTED = false;\n\nconst checkXRSupport = () => {\n const navigator = window.navigator as any;\n\n if (!navigator.xr) {\n return;\n }\n\n if (navigator.xr.isSessionSupported) {\n navigator.xr.isSessionSupported(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n } else if (navigator.xr.supportsSession) {\n navigator.xr.supportsSession(\"immersive-vr\").then(res => {\n WEBXR_SUPPORTED = res;\n }).catch(() => void 0);\n }\n};\n\nexport {\n Float32Array,\n getComputedStyle,\n userAgent,\n TRANSFORM,\n SUPPORT_TOUCH,\n SUPPORT_DEVICEMOTION,\n SUPPORT_WILLCHANGE,\n checkXRSupport,\n WEBXR_SUPPORTED,\n DeviceMotionEvent,\n devicePixelRatio\n};\n\n","/**\n * Original Code\n * https://github.com/toji/gl-matrix/blob/v2.3.2/src/gl-matrix.js\n * Math Util\n * modified by egjs\n */\n/**\n * @fileoverview gl-matrix - High performance matrix and vector operations\n * @author Brandon Jones\n * @author Colin MacKenzie IV\n * @version 2.3.2\n */\n\n/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE. */\n\n// Some minimal math functionality borrowed from gl-Matrix and stripped down\n// for the purposes of this library.\n\nimport { vec2, vec3, quat } from \"gl-matrix\";\n\nimport { ValueOf } from \"../types/internal\";\n\nconst quatToVec3 = (quaternion: quat) => {\n const baseV = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(baseV, baseV, quaternion);\n return baseV;\n};\n\nconst toDegree = (a: number) => a * 180 / Math.PI;\n\nconst util: any = {};\n\nutil.isPowerOfTwo = (n: number) => n && (n & (n - 1)) === 0;\n\nutil.extractPitchFromQuat = (quaternion: quat) => {\n const baseV = quatToVec3(quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n};\n\nutil.hypot = Math.hypot || ((x: number, y: number) => Math.sqrt(x * x + y * y));\n\n// implement reference\n// the general equation of a plane : http://www.gisdeveloper.co.kr/entry/평면의-공식\n// calculating angle between two vectors : http://darkpgmr.tistory.com/121\nconst ROTATE_CONSTANT: {\n PITCH_DELTA: 1;\n YAW_DELTA_BY_ROLL: 2;\n YAW_DELTA_BY_YAW: 3;\n} = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n};\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nconst getRotationDelta = (prevQ: quat, curQ: quat, rotateKind: ValueOf) => {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n // const coefficientD = -1 * vec3.dot(vecN, meshPoint1);\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance =\n coefficientA * crossVec[0] +\n coefficientB * crossVec[1] +\n coefficientC * crossVec[2];\n\n let thetaDirection;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return toDegree(deltaRadian);\n};\n\nconst angleBetweenVec2 = (v1: vec2, v2: vec2) => {\n const det = v1[0] * v2[1] - v2[0] * v1[1];\n const theta = -Math.atan2(det, vec2.dot(v1, v2));\n return theta;\n};\n\nutil.yawOffsetBetween = (viewDir: number, targetDir: number) => {\n const viewDirXZ = vec2.fromValues(viewDir[0], viewDir[2]);\n const targetDirXZ = vec2.fromValues(targetDir[0], targetDir[2]);\n\n vec2.normalize(viewDirXZ, viewDirXZ);\n vec2.normalize(targetDirXZ, targetDirXZ);\n\n const theta = -angleBetweenVec2(viewDirXZ, targetDirXZ);\n\n return theta;\n};\n\nutil.sign = (x: number) => Math.sign\n ? Math.sign(x)\n : (Number(x > 0) - Number(x < 0)) || +x;\n\nutil.toDegree = toDegree;\nutil.getRotationDelta = getRotationDelta;\nutil.angleBetweenVec2 = angleBetweenVec2;\n\nexport {\n util,\n ROTATE_CONSTANT\n};\n","import { userAgent } from \"../utils/browserFeature\";\n/**\n * Returns a number value indiciating the version of Chrome being used,\n * or otherwise `null` if not on Chrome.\n *\n * Ref: https://github.com/immersive-web/cardboard-vr-display/pull/19\n */\n/**\n * In Chrome m65, `devicemotion` events are broken but subsequently fixed\n * in 65.0.3325.148. Since many browsers use Chromium, ensure that\n * we scope this detection by branch and build numbers to provide\n * a proper fallback.\n * https://github.com/immersive-web/webvr-polyfill/issues/307\n */\nlet version = -1; // It should not be null because it will be compared with number\nlet branch: string | null = null;\nlet build: string | null = null;\n\nconst match = /Chrome\\/([0-9]+)\\.(?:[0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(userAgent);\n\nif (match) {\n version = parseInt(match[1], 10);\n branch = match[2];\n build = match[3];\n}\n\nconst CHROME_VERSION = version;\nconst IS_CHROME_WITHOUT_DEVICE_MOTION = version === 65 && branch === \"3325\" && parseInt(build!, 10) < 148;\nconst IS_ANDROID = /Android/i.test(userAgent);\n\nconst CONTROL_MODE_VR = 1;\nconst CONTROL_MODE_YAWPITCH = 2;\n\nconst TOUCH_DIRECTION_NONE = 1;\nconst TOUCH_DIRECTION_YAW = 2;\nconst TOUCH_DIRECTION_PITCH = 4;\nconst TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_YAW | TOUCH_DIRECTION_PITCH;\n\n/* Const for MovableCoord */\nconst MC_DECELERATION = 0.0014;\nconst MC_MAXIMUM_DURATION = 1000;\nconst MC_BIND_SCALE = [0.20, 0.20];\n\nconst MIN_FIELD_OF_VIEW = 20;\nconst MAX_FIELD_OF_VIEW = 110;\nconst PAN_SCALE = 320;\n\n// const DELTA_THRESHOLD = 0.015;\n// const DELTA_THRESHOLD = 0.09; // Note4\n// const DELTA_THRESHOLD = 0.0825;\n// const DELTA_THRESHOLD = 0.075;\n// const DELTA_THRESHOLD = 0.06;\n// const DELTA_THRESHOLD = 0.045;\nconst DELTA_THRESHOLD = 0.0375; // Note2\n\nconst YAW_RANGE_HALF = 180;\nconst PITCH_RANGE_HALF = 90;\nconst CIRCULAR_PITCH_RANGE_HALF = 180;\nconst PINCH_EVENTS = \"pinchstart pinchmove pinchend\";\n\nconst KEYMAP = {\n LEFT_ARROW: 37,\n A: 65,\n UP_ARROW: 38,\n W: 87,\n RIGHT_ARROW: 39,\n D: 68,\n DOWN_ARROW: 40,\n S: 83\n};\n\nconst GYRO_MODE: {\n NONE: \"none\";\n YAWPITCH: \"yawPitch\";\n VR: \"VR\";\n} = {\n NONE: \"none\",\n YAWPITCH: \"yawPitch\",\n VR: \"VR\"\n};\n\nexport {\n GYRO_MODE,\n\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n\n TOUCH_DIRECTION_NONE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MIN_FIELD_OF_VIEW,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n DELTA_THRESHOLD,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n PINCH_EVENTS,\n KEYMAP,\n\n CHROME_VERSION,\n IS_CHROME_WITHOUT_DEVICE_MOTION,\n IS_ANDROID\n};\n","/* eslint-disable */\n/*\n * Copyright 2016 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { window as win } from \"../../../../utils/browser\";\n\nconst MathUtil = win.MathUtil || {};\n\nMathUtil.degToRad = Math.PI / 180;\nMathUtil.radToDeg = 180 / Math.PI;\n\n// Some minimal math functionality borrowed from THREE.Math and stripped down\n// for the purposes of this library.\n\n\nMathUtil.Vector2 = function( x, y ) {\n this.x = x || 0;\n this.y = y || 0;\n};\n\nMathUtil.Vector2.prototype = {\n constructor: MathUtil.Vector2,\n\n set: function( x, y ) {\n this.x = x;\n this.y = y;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n\n return this;\n },\n\n subVectors: function( a, b ) {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n\n return this;\n }\n};\n\nMathUtil.Vector3 = function( x, y, z ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n};\n\nMathUtil.Vector3.prototype = {\n constructor: MathUtil.Vector3,\n\n set: function( x, y, z ) {\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n },\n\n copy: function( v ) {\n this.x = v.x;\n this.y = v.y;\n this.z = v.z;\n\n return this;\n },\n\n length: function() {\n return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );\n },\n\n normalize: function() {\n const scalar = this.length();\n\n if ( scalar !== 0 ) {\n const invScalar = 1 / scalar;\n\n this.multiplyScalar(invScalar);\n } else {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n }\n\n return this;\n },\n\n multiplyScalar: function( scalar ) {\n this.x *= scalar;\n this.y *= scalar;\n this.z *= scalar;\n },\n\n applyQuaternion: function( q ) {\n const x = this.x;\n const y = this.y;\n const z = this.z;\n\n const qx = q.x;\n const qy = q.y;\n const qz = q.z;\n const qw = q.w;\n\n // calculate quat * vector\n const ix = qw * x + qy * z - qz * y;\n const iy = qw * y + qz * x - qx * z;\n const iz = qw * z + qx * y - qy * x;\n const iw = - qx * x - qy * y - qz * z;\n\n // calculate result * inverse quat\n this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;\n this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;\n this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;\n\n return this;\n },\n\n dot: function( v ) {\n return this.x * v.x + this.y * v.y + this.z * v.z;\n },\n\n crossVectors: function( a, b ) {\n const ax = a.x;\n const ay = a.y;\n const az = a.z;\n const bx = b.x;\n const by = b.y;\n const bz = b.z;\n\n this.x = ay * bz - az * by;\n this.y = az * bx - ax * bz;\n this.z = ax * by - ay * bx;\n\n return this;\n }\n};\n\nMathUtil.Quaternion = function( x, y, z, w ) {\n this.x = x || 0;\n this.y = y || 0;\n this.z = z || 0;\n this.w = ( w !== undefined ) ? w : 1;\n};\n\nMathUtil.Quaternion.prototype = {\n constructor: MathUtil.Quaternion,\n\n set: function( x, y, z, w ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.w = w;\n\n return this;\n },\n\n copy: function( quaternion ) {\n this.x = quaternion.x;\n this.y = quaternion.y;\n this.z = quaternion.z;\n this.w = quaternion.w;\n\n return this;\n },\n\n setFromEulerXYZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 + s1 * s2 * c3;\n this.w = c1 * c2 * c3 - s1 * s2 * s3;\n\n return this;\n },\n\n setFromEulerYXZ: function( x, y, z ) {\n const c1 = Math.cos( x / 2 );\n const c2 = Math.cos( y / 2 );\n const c3 = Math.cos( z / 2 );\n const s1 = Math.sin( x / 2 );\n const s2 = Math.sin( y / 2 );\n const s3 = Math.sin( z / 2 );\n\n this.x = s1 * c2 * c3 + c1 * s2 * s3;\n this.y = c1 * s2 * c3 - s1 * c2 * s3;\n this.z = c1 * c2 * s3 - s1 * s2 * c3;\n this.w = c1 * c2 * c3 + s1 * s2 * s3;\n\n return this;\n },\n\n setFromAxisAngle: function( axis, angle ) {\n // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm\n // assumes axis is normalized\n\n const halfAngle = angle / 2;\n const s = Math.sin( halfAngle );\n\n this.x = axis.x * s;\n this.y = axis.y * s;\n this.z = axis.z * s;\n this.w = Math.cos( halfAngle );\n\n return this;\n },\n\n multiply: function( q ) {\n return this.multiplyQuaternions( this, q );\n },\n\n multiplyQuaternions: function( a, b ) {\n // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm\n\n const qax = a.x;\n const qay = a.y;\n const qaz = a.z;\n const qaw = a.w;\n const qbx = b.x;\n const qby = b.y;\n const qbz = b.z;\n const qbw = b.w;\n\n this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;\n this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;\n this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;\n this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;\n\n return this;\n },\n\n inverse: function() {\n this.x *= -1;\n this.y *= -1;\n this.z *= -1;\n\n this.normalize();\n\n return this;\n },\n\n normalize: function() {\n let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );\n\n if ( l === 0 ) {\n this.x = 0;\n this.y = 0;\n this.z = 0;\n this.w = 1;\n } else {\n l = 1 / l;\n\n this.x = this.x * l;\n this.y = this.y * l;\n this.z = this.z * l;\n this.w = this.w * l;\n }\n\n return this;\n },\n\n slerp: function( qb, t ) {\n if ( t === 0 ) return this;\n if ( t === 1 ) return this.copy( qb );\n\n const x = this.x;\n const y = this.y;\n const z = this.z;\n const w = this.w;\n\n // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/\n\n let cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;\n\n if ( cosHalfTheta < 0 ) {\n this.w = - qb.w;\n this.x = - qb.x;\n this.y = - qb.y;\n this.z = - qb.z;\n\n cosHalfTheta = - cosHalfTheta;\n } else {\n this.copy( qb );\n }\n\n if ( cosHalfTheta >= 1.0 ) {\n this.w = w;\n this.x = x;\n this.y = y;\n this.z = z;\n\n return this;\n }\n\n const halfTheta = Math.acos( cosHalfTheta );\n const sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );\n\n if ( Math.abs( sinHalfTheta ) < 0.001 ) {\n this.w = 0.5 * ( w + this.w );\n this.x = 0.5 * ( x + this.x );\n this.y = 0.5 * ( y + this.y );\n this.z = 0.5 * ( z + this.z );\n\n return this;\n }\n\n const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;\n const ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;\n\n this.w = ( w * ratioA + this.w * ratioB );\n this.x = ( x * ratioA + this.x * ratioB );\n this.y = ( y * ratioA + this.y * ratioB );\n this.z = ( z * ratioA + this.z * ratioB );\n\n return this;\n },\n\n setFromUnitVectors: function() {\n // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final\n // assumes direction vectors vFrom and vTo are normalized\n\n let v1;\n let r;\n const EPS = 0.000001;\n\n return function( vFrom, vTo ) {\n if ( v1 === undefined ) v1 = new MathUtil.Vector3();\n\n r = vFrom.dot( vTo ) + 1;\n\n if ( r < EPS ) {\n r = 0;\n\n if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {\n v1.set( - vFrom.y, vFrom.x, 0 );\n } else {\n v1.set( 0, - vFrom.z, vFrom.y );\n }\n } else {\n v1.crossVectors( vFrom, vTo );\n }\n\n this.x = v1.x;\n this.y = v1.y;\n this.z = v1.z;\n this.w = r;\n\n this.normalize();\n\n return this;\n };\n }()\n};\n\nexport default MathUtil;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// tslint:disable: only-arrow-functions\n\nimport { window as win, document as doc, navigator as nav } from \"../../../../utils/browser\";\n\nconst userAgent = nav?.userAgent ?? \"\";\nconst Util = (win ).Util || {};\n\nUtil.MIN_TIMESTEP = 0.001;\nUtil.MAX_TIMESTEP = 1;\n\nUtil.base64 = function(mimeType, base64) {\n return \"data:\" + mimeType + \";base64,\" + base64;\n};\n\nUtil.clamp = function(value, min, max) {\n return Math.min(Math.max(min, value), max);\n};\n\nUtil.lerp = function(a, b, t) {\n return a + ((b - a) * t);\n};\n\nUtil.isIOS = (function() {\n const isIOS = /iPad|iPhone|iPod/.test(nav?.platform);\n return function() {\n return isIOS;\n };\n})();\n\nUtil.isWebViewAndroid = (function() {\n const isWebViewAndroid = userAgent.indexOf(\"Version\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1 &&\n userAgent.indexOf(\"Chrome\") !== -1;\n return function() {\n return isWebViewAndroid;\n };\n})();\n\nUtil.isSafari = (function() {\n const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);\n return function() {\n return isSafari;\n };\n})();\n\nUtil.isFirefoxAndroid = (function() {\n const isFirefoxAndroid = userAgent.indexOf(\"Firefox\") !== -1 &&\n userAgent.indexOf(\"Android\") !== -1;\n return function() {\n return isFirefoxAndroid;\n };\n})();\n\nUtil.isR7 = (function() {\n const isR7 = userAgent.indexOf(\"R7 Build\") !== -1;\n return function() {\n return isR7;\n };\n})();\n\nUtil.isLandscapeMode = function() {\n const rtn = (win.orientation === 90 || win.orientation === -90);\n return Util.isR7() ? !rtn : rtn;\n};\n\n// Helper method to validate the time steps of sensor timestamps.\nUtil.isTimestampDeltaValid = function(timestampDeltaS) {\n if (isNaN(timestampDeltaS)) {\n return false;\n }\n if (timestampDeltaS <= Util.MIN_TIMESTEP) {\n return false;\n }\n if (timestampDeltaS > Util.MAX_TIMESTEP) {\n return false;\n }\n return true;\n};\n\nUtil.getScreenWidth = function() {\n return Math.max(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.getScreenHeight = function() {\n return Math.min(win.screen.width, win.screen.height) *\n win.devicePixelRatio;\n};\n\nUtil.requestFullscreen = function(element) {\n if (Util.isWebViewAndroid()) {\n return false;\n }\n if (element.requestFullscreen) {\n element.requestFullscreen();\n } else if (element.webkitRequestFullscreen) {\n element.webkitRequestFullscreen();\n } else if (element.mozRequestFullScreen) {\n element.mozRequestFullScreen();\n } else if (element.msRequestFullscreen) {\n element.msRequestFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.exitFullscreen = function() {\n if (doc.exitFullscreen) {\n doc.exitFullscreen();\n } else if (doc.webkitExitFullscreen) {\n doc.webkitExitFullscreen();\n } else if (doc.mozCancelFullScreen) {\n doc.mozCancelFullScreen();\n } else if (doc.msExitFullscreen) {\n doc.msExitFullscreen();\n } else {\n return false;\n }\n\n return true;\n};\n\nUtil.getFullscreenElement = function() {\n return doc.fullscreenElement ||\n doc.webkitFullscreenElement ||\n doc.mozFullScreenElement ||\n doc.msFullscreenElement;\n};\n\nUtil.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {\n // No error checking for brevity.\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n const program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n\n for (const attribName in attribLocationMap)\n gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);\n\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n return program;\n};\n\nUtil.getProgramUniforms = function(gl, program) {\n const uniforms = {};\n const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n let uniformName = \"\";\n for (let i = 0; i < uniformCount; i++) {\n const uniformInfo = gl.getActiveUniform(program, i);\n uniformName = uniformInfo.name.replace(\"[0]\", \"\");\n uniforms[uniformName] = gl.getUniformLocation(program, uniformName);\n }\n return uniforms;\n};\n\nUtil.orthoMatrix = function(out, left, right, bottom, top, near, far) {\n const lr = 1 / (left - right);\n const bt = 1 / (bottom - top);\n const nf = 1 / (near - far);\n out[0] = -2 * lr;\n out[1] = 0;\n out[2] = 0;\n out[3] = 0;\n out[4] = 0;\n out[5] = -2 * bt;\n out[6] = 0;\n out[7] = 0;\n out[8] = 0;\n out[9] = 0;\n out[10] = 2 * nf;\n out[11] = 0;\n out[12] = (left + right) * lr;\n out[13] = (top + bottom) * bt;\n out[14] = (far + near) * nf;\n out[15] = 1;\n return out;\n};\n\nUtil.copyArray = function(source, dest) {\n for (let i = 0, n = source.length; i < n; i++) {\n dest[i] = source[i];\n }\n};\n\nUtil.isMobile = function() {\n let check = false;\n (function(a) {\n if (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(a.substr(0, 4)))check = true;\n })(userAgent || nav?.vendor || win.opera);\n return check;\n};\n\nUtil.extend = function(dest, src) {\n for (const key in src) {\n if (src.hasOwnProperty(key)) {\n dest[key] = src[key];\n }\n }\n\n return dest;\n};\n\nUtil.safariCssSizeWorkaround = function(canvas) {\n // TODO(smus): Remove this workaround when Safari for iOS is fixed.\n // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).\n //\n // \"To the last I grapple with thee;\n // from hell's heart I stab at thee;\n // for hate's sake I spit my last breath at thee.\"\n // -- Moby Dick, by Herman Melville\n if (Util.isIOS()) {\n const width = canvas.style.width;\n const height = canvas.style.height;\n canvas.style.width = (parseInt(width) + 1) + \"px\";\n canvas.style.height = (parseInt(height)) + \"px\";\n setTimeout(function() {\n canvas.style.width = width;\n canvas.style.height = height;\n }, 100);\n }\n\n // Debug only.\n win.Util = Util;\n win.canvas = canvas;\n};\n\nUtil.isDebug = function() {\n return Util.getQueryParameter(\"debug\");\n};\n\nUtil.getQueryParameter = function(name) {\n name = name.replace(/[\\[]/, \"\\\\[\").replace(/[\\]]/, \"\\\\]\");\n const regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\");\n const results = regex.exec(location.search);\n return results === null ? \"\" : decodeURIComponent(results[1].replace(/\\+/g, \" \"));\n};\n\nUtil.frameDataFromPose = (function() {\n const piOver180 = Math.PI / 180.0;\n const rad45 = Math.PI * 0.25;\n\n // Borrowed from glMatrix.\n function mat4_perspectiveFromFieldOfView(out, fov, near, far) {\n const upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45);\n const downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45);\n const leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45);\n const rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45);\n const xScale = 2.0 / (leftTan + rightTan);\n const yScale = 2.0 / (upTan + downTan);\n\n out[0] = xScale;\n out[1] = 0.0;\n out[2] = 0.0;\n out[3] = 0.0;\n out[4] = 0.0;\n out[5] = yScale;\n out[6] = 0.0;\n out[7] = 0.0;\n out[8] = -((leftTan - rightTan) * xScale * 0.5);\n out[9] = ((upTan - downTan) * yScale * 0.5);\n out[10] = far / (near - far);\n out[11] = -1.0;\n out[12] = 0.0;\n out[13] = 0.0;\n out[14] = (far * near) / (near - far);\n out[15] = 0.0;\n return out;\n }\n\n function mat4_fromRotationTranslation(out, q, v) {\n // Quaternion math\n const x = q[0];\n const y = q[1];\n const z = q[2];\n const w = q[3];\n const x2 = x + x;\n const y2 = y + y;\n const z2 = z + z;\n\n const xx = x * x2;\n const xy = x * y2;\n const xz = x * z2;\n const yy = y * y2;\n const yz = y * z2;\n const zz = z * z2;\n const wx = w * x2;\n const wy = w * y2;\n const wz = w * z2;\n\n out[0] = 1 - (yy + zz);\n out[1] = xy + wz;\n out[2] = xz - wy;\n out[3] = 0;\n out[4] = xy - wz;\n out[5] = 1 - (xx + zz);\n out[6] = yz + wx;\n out[7] = 0;\n out[8] = xz + wy;\n out[9] = yz - wx;\n out[10] = 1 - (xx + yy);\n out[11] = 0;\n out[12] = v[0];\n out[13] = v[1];\n out[14] = v[2];\n out[15] = 1;\n\n return out;\n }\n\n function mat4_translate(out, a, v) {\n const x = v[0];\n const y = v[1];\n const z = v[2];\n let a00;\n let a01;\n let a02;\n let a03;\n let a10;\n let a11;\n let a12;\n let a13;\n let a20;\n let a21;\n let a22;\n let a23;\n\n if (a === out) {\n out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n } else {\n a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];\n a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];\n a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];\n\n out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;\n out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;\n out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;\n\n out[12] = a00 * x + a10 * y + a20 * z + a[12];\n out[13] = a01 * x + a11 * y + a21 * z + a[13];\n out[14] = a02 * x + a12 * y + a22 * z + a[14];\n out[15] = a03 * x + a13 * y + a23 * z + a[15];\n }\n\n return out;\n }\n\n function mat4_invert(out, a) {\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[4];\n const a11 = a[5];\n const a12 = a[6];\n const a13 = a[7];\n const a20 = a[8];\n const a21 = a[9];\n const a22 = a[10];\n const a23 = a[11];\n const a30 = a[12];\n const a31 = a[13];\n const a32 = a[14];\n const a33 = a[15];\n\n const b00 = a00 * a11 - a01 * a10;\n const b01 = a00 * a12 - a02 * a10;\n const b02 = a00 * a13 - a03 * a10;\n const b03 = a01 * a12 - a02 * a11;\n const b04 = a01 * a13 - a03 * a11;\n const b05 = a02 * a13 - a03 * a12;\n const b06 = a20 * a31 - a21 * a30;\n const b07 = a20 * a32 - a22 * a30;\n const b08 = a20 * a33 - a23 * a30;\n const b09 = a21 * a32 - a22 * a31;\n const b10 = a21 * a33 - a23 * a31;\n const b11 = a22 * a33 - a23 * a32;\n\n // Calculate the determinant\n let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n\n if (!det) {\n return null;\n }\n det = 1.0 / det;\n\n out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n\n return out;\n }\n\n const defaultOrientation = new Float32Array([0, 0, 0, 1]);\n const defaultPosition = new Float32Array([0, 0, 0]);\n\n function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {\n mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);\n\n const orientation = pose.orientation || defaultOrientation;\n const position = pose.position || defaultPosition;\n\n mat4_fromRotationTranslation(view, orientation, position);\n if (parameters)\n mat4_translate(view, view, parameters.offset);\n mat4_invert(view, view);\n }\n\n return function(frameData, pose, vrDisplay) {\n if (!frameData || !pose)\n return false;\n\n frameData.pose = pose;\n frameData.timestamp = pose.timestamp;\n\n updateEyeMatrices(\n frameData.leftProjectionMatrix, frameData.leftViewMatrix,\n pose, vrDisplay.getEyeParameters(\"left\"), vrDisplay);\n updateEyeMatrices(\n frameData.rightProjectionMatrix, frameData.rightViewMatrix,\n pose, vrDisplay.getEyeParameters(\"right\"), vrDisplay);\n\n return true;\n };\n})();\n\nUtil.isInsideCrossDomainIFrame = function() {\n const isFramed = (win.self !== win.top);\n const refDomain = Util.getDomainFromUrl(doc.referrer);\n const thisDomain = Util.getDomainFromUrl(win.location.href);\n\n return isFramed && (refDomain !== thisDomain);\n};\n\n// From http://stackoverflow.com/a/23945027.\nUtil.getDomainFromUrl = function(url) {\n let domain;\n // Find & remove protocol (http, ftp, etc.) and get domain.\n if (url.indexOf(\"://\") > -1) {\n domain = url.split(\"/\")[2];\n } else {\n domain = url.split(\"/\")[0];\n }\n\n // find & remove port number\n domain = domain.split(\":\")[0];\n\n return domain;\n};\n\nexport default Util;\n","/* eslint-disable */\n\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * Given an orientation and the gyroscope data, predicts the future orientation\n * of the head. This makes rendering appear faster.\n *\n * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf\n * @param {Number} predictionTimeS time from head movement to the appearance of\n * the corresponding image.\n */\nclass PosePredictor {\n public predictionTimeS;\n public previousQ;\n public previousTimestampS;\n public deltaQ;\n public outQ;\n\n public constructor(predictionTimeS) {\n this.predictionTimeS = predictionTimeS;\n\n // The quaternion corresponding to the previous state.\n this.previousQ = new MathUtil.Quaternion();\n // Previous time a prediction occurred.\n this.previousTimestampS = null;\n\n // The delta quaternion that adjusts the current pose.\n this.deltaQ = new MathUtil.Quaternion();\n // The output quaternion.\n this.outQ = new MathUtil.Quaternion();\n }\n\n public getPrediction(currentQ, gyro, timestampS) {\n if (!this.previousTimestampS) {\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n return currentQ;\n }\n\n // Calculate axis and angle based on gyroscope rotation rate data.\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n\n const angularSpeed = gyro.length();\n\n // If we're rotating slowly, don't do prediction.\n if (angularSpeed < MathUtil.degToRad * 20) {\n if (Util.isDebug()) {\n console.log(\"Moving slowly, at %s deg/s: no prediction\",\n (MathUtil.radToDeg * angularSpeed).toFixed(1));\n }\n this.outQ.copy(currentQ);\n this.previousQ.copy(currentQ);\n return this.outQ;\n }\n\n // Get the predicted angle based on the time delta and latency.\n const deltaT = timestampS - this.previousTimestampS;\n const predictAngle = angularSpeed * this.predictionTimeS;\n\n this.deltaQ.setFromAxisAngle(axis, predictAngle);\n this.outQ.copy(this.previousQ);\n this.outQ.multiply(this.deltaQ);\n\n this.previousQ.copy(currentQ);\n this.previousTimestampS = timestampS;\n\n return this.outQ;\n }\n}\n\nexport default PosePredictor;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3 } from \"gl-matrix\";\n\nimport { Mutable } from \"../../types/internal\";\nimport { window } from \"../../utils/browser\";\nimport { IS_CHROME_WITHOUT_DEVICE_MOTION, IS_ANDROID } from \"../consts\";\n\nconst STILLNESS_THRESHOLD = 200; // millisecond\n\nexport default class DeviceMotion extends Component<{\n devicemotion: {\n inputEvent: DeviceMotionEvent | {\n deviceorientation: {\n alpha: number;\n beta: number;\n gamma: number;\n };\n };\n };\n}> {\n public readonly isWithoutDeviceMotion: boolean;\n public readonly isAndroid: boolean;\n\n public stillGyroVec: vec3;\n public rawGyroVec: vec3;\n public adjustedGyroVec: vec3;\n public lastDevicemotionTimestamp: number;\n\n private _timer: number;\n private _isEnabled: boolean;\n\n public constructor() {\n super();\n this._onDeviceMotion = this._onDeviceMotion.bind(this);\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onChromeWithoutDeviceMotion = this._onChromeWithoutDeviceMotion.bind(this);\n\n this.isWithoutDeviceMotion = IS_CHROME_WITHOUT_DEVICE_MOTION;\n this.isAndroid = IS_ANDROID;\n\n this.stillGyroVec = vec3.create();\n this.rawGyroVec = vec3.create();\n this.adjustedGyroVec = vec3.create();\n\n this._timer = -1;\n\n this.lastDevicemotionTimestamp = 0;\n this._isEnabled = false;\n this.enable();\n }\n\n public enable() {\n if (this.isAndroid) {\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n }\n if (this.isWithoutDeviceMotion) {\n window.addEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n } else {\n window.addEventListener(\"devicemotion\", this._onDeviceMotion);\n }\n this._isEnabled = true;\n }\n\n public disable() {\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"deviceorientation\", this._onChromeWithoutDeviceMotion);\n window.removeEventListener(\"devicemotion\", this._onDeviceMotion);\n this._isEnabled = false;\n }\n\n private _onChromeWithoutDeviceMotion(e: DeviceOrientationEvent) {\n let {alpha, beta, gamma} = e;\n\n // There is deviceorientation event trigged with empty values\n // on Headless Chrome.\n if (alpha === null) {\n return;\n }\n\n // convert to radian\n alpha = (alpha || 0) * Math.PI / 180;\n beta = (beta || 0) * Math.PI / 180;\n gamma = (gamma || 0) * Math.PI / 180;\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: {\n deviceorientation: {\n alpha,\n beta,\n gamma: -gamma\n }\n }\n }));\n }\n\n private _onDeviceOrientation() {\n if (this._timer) {\n clearTimeout(this._timer);\n }\n\n this._timer = window.setTimeout(() => {\n if ((new Date().getTime() - this.lastDevicemotionTimestamp) < STILLNESS_THRESHOLD) {\n vec3.copy(this.stillGyroVec, this.rawGyroVec);\n }\n }, STILLNESS_THRESHOLD);\n }\n\n private _onDeviceMotion(e: DeviceMotionEvent) {\n // desktop chrome triggers devicemotion event with empthy sensor values.\n // Those events should ignored.\n const isGyroSensorAvailable = !(e.rotationRate!.alpha == null);\n const isGravitySensorAvailable = !(e.accelerationIncludingGravity!.x == null);\n\n if (e.interval === 0 || !(isGyroSensorAvailable && isGravitySensorAvailable)) {\n return;\n }\n\n const devicemotionEvent = {...e} as Mutable;\n\n devicemotionEvent.interval = e.interval;\n devicemotionEvent.timeStamp = e.timeStamp;\n devicemotionEvent.type = e.type;\n devicemotionEvent.rotationRate = {\n alpha: e.rotationRate!.alpha,\n beta: e.rotationRate!.beta,\n gamma: e.rotationRate!.gamma\n };\n devicemotionEvent.accelerationIncludingGravity = {\n x: e.accelerationIncludingGravity!.x,\n y: e.accelerationIncludingGravity!.y,\n z: e.accelerationIncludingGravity!.z\n };\n devicemotionEvent.acceleration = {\n x: e.acceleration!.x,\n y: e.acceleration!.y,\n z: e.acceleration!.z\n };\n\n if (this.isAndroid) {\n vec3.set(\n this.rawGyroVec,\n e.rotationRate!.alpha || 0,\n e.rotationRate!.beta || 0,\n e.rotationRate!.gamma || 0);\n vec3.subtract(this.adjustedGyroVec, this.rawGyroVec, this.stillGyroVec);\n this.lastDevicemotionTimestamp = new Date().getTime();\n\n (devicemotionEvent as any).adjustedRotationRate = {\n alpha: this.adjustedGyroVec[0],\n beta: this.adjustedGyroVec[1],\n gamma: this.adjustedGyroVec[2]};\n }\n\n this.trigger(new ComponentEvent(\"devicemotion\", {\n inputEvent: devicemotionEvent\n }));\n }\n}\n","class SensorSample {\n public sample;\n public timestampS;\n\n public constructor(sample?, timestampS?) {\n this.set(sample, timestampS);\n }\n\n public set(sample, timestampS) {\n this.sample = sample;\n this.timestampS = timestampS;\n }\n\n public copy(sensorSample) {\n this.set(sensorSample.sample, sensorSample.timestampS);\n }\n}\n\nexport default SensorSample;\n","/* eslint-disable */\n/*\n * Copyright 2015 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport SensorSample from \"./sensor-sample\";\nimport MathUtil from \"./math-util\";\nimport Util from \"./util\";\n\n/**\n * An implementation of a simple complementary filter, which fuses gyroscope and\n * accelerometer data from the 'devicemotion' event.\n *\n * Accelerometer data is very noisy, but stable over the long term.\n * Gyroscope data is smooth, but tends to drift over the long term.\n *\n * This fusion is relatively simple:\n * 1. Get orientation estimates from accelerometer by applying a low-pass filter\n * on that data.\n * 2. Get orientation estimates from gyroscope by integrating over time.\n * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the\n * short term.\n */\nclass ComplementaryFilter {\n public kFilter;\n public currentAccelMeasurement;\n public currentGyroMeasurement;\n public previousGyroMeasurement;\n public filterQ;\n public previousFilterQ;\n public accelQ;\n public isOrientationInitialized;\n public estimatedGravity;\n public measuredGravity;\n public gyroIntegralQ;\n\n constructor(kFilter) {\n this.kFilter = kFilter;\n\n // Raw sensor measurements.\n this.currentAccelMeasurement = new SensorSample();\n this.currentGyroMeasurement = new SensorSample();\n this.previousGyroMeasurement = new SensorSample();\n\n // Set default look direction to be in the correct direction.\n if (Util.isIOS()) {\n this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);\n } else {\n this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);\n }\n this.previousFilterQ = new MathUtil.Quaternion();\n this.previousFilterQ.copy(this.filterQ);\n\n // Orientation based on the accelerometer.\n this.accelQ = new MathUtil.Quaternion();\n // Whether or not the orientation has been initialized.\n this.isOrientationInitialized = false;\n // Running estimate of gravity based on the current orientation.\n this.estimatedGravity = new MathUtil.Vector3();\n // Measured gravity based on accelerometer.\n this.measuredGravity = new MathUtil.Vector3();\n\n // Debug only quaternion of gyro-based orientation.\n this.gyroIntegralQ = new MathUtil.Quaternion();\n }\n\n public addAccelMeasurement(vector, timestampS) {\n this.currentAccelMeasurement.set(vector, timestampS);\n }\n\n public addGyroMeasurement = function(vector, timestampS) {\n this.currentGyroMeasurement.set(vector, timestampS);\n\n const deltaT = timestampS - this.previousGyroMeasurement.timestampS;\n if (Util.isTimestampDeltaValid(deltaT)) {\n this.run_();\n }\n\n this.previousGyroMeasurement.copy(this.currentGyroMeasurement);\n };\n\n public getOrientation() {\n return this.filterQ;\n }\n\n public run_() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n if (Util.isDebug()) {\n console.log(\"Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)\",\n MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),\n (this.estimatedGravity.x).toFixed(1),\n (this.estimatedGravity.y).toFixed(1),\n (this.estimatedGravity.z).toFixed(1),\n (this.measuredGravity.x).toFixed(1),\n (this.measuredGravity.y).toFixed(1),\n (this.measuredGravity.z).toFixed(1));\n }\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n }\n\n private accelToQuaternion_(accel) {\n const normAccel = new MathUtil.Vector3();\n normAccel.copy(accel);\n normAccel.normalize();\n const quat = new MathUtil.Quaternion();\n quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);\n quat.inverse();\n return quat;\n }\n\n private gyroToQuaternionDelta_(gyro, dt) {\n // Extract axis and angle from the gyroscope data.\n const quat = new MathUtil.Quaternion();\n const axis = new MathUtil.Vector3();\n axis.copy(gyro);\n axis.normalize();\n quat.setFromAxisAngle(axis, gyro.length() * dt);\n return quat;\n }\n}\n\nexport default ComplementaryFilter;\n","import MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport ComplementaryFilter from \"./lib/webvr-polyfill/complementary-filter\";\n\nComplementaryFilter.prototype.run_ = function() {\n if (!this.isOrientationInitialized) {\n this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);\n this.previousFilterQ.copy(this.accelQ);\n this.isOrientationInitialized = true;\n return;\n }\n\n const deltaT = this.currentGyroMeasurement.timestampS -\n this.previousGyroMeasurement.timestampS;\n\n // Convert gyro rotation vector to a quaternion delta.\n const gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);\n\n this.gyroIntegralQ.multiply(gyroDeltaQ);\n\n // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.\n this.filterQ.copy(this.previousFilterQ);\n this.filterQ.multiply(gyroDeltaQ);\n\n // Calculate the delta between the current estimated gravity and the real\n // gravity vector from accelerometer.\n const invFilterQ = new MathUtil.Quaternion();\n\n invFilterQ.copy(this.filterQ);\n invFilterQ.inverse();\n\n this.estimatedGravity.set(0, 0, -1);\n this.estimatedGravity.applyQuaternion(invFilterQ);\n this.estimatedGravity.normalize();\n\n this.measuredGravity.copy(this.currentAccelMeasurement.sample);\n this.measuredGravity.normalize();\n\n // Compare estimated gravity with measured gravity, get the delta quaternion\n // between the two.\n const deltaQ = new MathUtil.Quaternion();\n\n deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);\n deltaQ.inverse();\n\n // Calculate the SLERP target: current orientation plus the measured-estimated\n // quaternion delta.\n const targetQ = new MathUtil.Quaternion();\n\n targetQ.copy(this.filterQ);\n targetQ.multiply(deltaQ);\n\n // SLERP factor: 0 is pure gyro, 1 is pure accel.\n this.filterQ.slerp(targetQ, 1 - this.kFilter);\n\n this.previousFilterQ.copy(this.filterQ);\n\n if (!this.isFilterQuaternionInitialized) {\n this.isFilterQuaternionInitialized = true;\n }\n};\n\nComplementaryFilter.prototype.getOrientation = function() {\n if (this.isFilterQuaternionInitialized) {\n return this.filterQ;\n } else {\n return null;\n }\n};\n\nexport default ComplementaryFilter;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\n\nimport { window, IS_IOS, IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { CHROME_VERSION } from \"../consts\";\n\nimport PosePredictor from \"./lib/webvr-polyfill/pose-predictor\";\nimport MathUtil from \"./lib/webvr-polyfill/math-util\";\nimport Util from \"./lib/webvr-polyfill/util\";\nimport DeviceMotion from \"./DeviceMotion\";\nimport ComplementaryFilter from \"./ComplementaryFilter\";\n\n\nconst K_FILTER = 0.98;\nconst PREDICTION_TIME_S = 0.040;\n\nexport default class FusionPoseSensor extends Component<{\n change: {\n quaternion: quat;\n };\n}> {\n public deviceMotion: DeviceMotion | null;\n public accelerometer: any;\n public gyroscope: any;\n public filter: ComplementaryFilter;\n public posePredictor: PosePredictor;\n public filterToWorldQ: any;\n public isFirefoxAndroid: boolean;\n public isIOS: boolean;\n public isChromeUsingDegrees: boolean;\n public inverseWorldToScreenQ: any;\n public worldToScreenQ: any;\n public originalPoseAdjustQ: any;\n public resetQ: any;\n public deviceOrientationFixQ: any;\n public predictedQ: any;\n public previousTimestampS: number;\n\n private _isEnabled: boolean;\n private _deviceOrientationQ: any;\n private _prevOrientation: quat;\n private _alpha: number;\n\n public constructor() {\n super();\n\n this.deviceMotion = new DeviceMotion();\n\n this.accelerometer = new MathUtil.Vector3();\n this.gyroscope = new MathUtil.Vector3();\n\n this._onDeviceMotionChange = this._onDeviceMotionChange.bind(this);\n this._onScreenOrientationChange = this._onScreenOrientationChange.bind(this);\n\n this.filter = new ComplementaryFilter(K_FILTER);\n this.posePredictor = new PosePredictor(PREDICTION_TIME_S);\n\n this.filterToWorldQ = new MathUtil.Quaternion();\n\n this.isFirefoxAndroid = Util.isFirefoxAndroid();\n // This includes iPhone & iPad(both desktop and mobile mode) ref #326\n this.isIOS = IS_IOS || IS_SAFARI_ON_DESKTOP;\n\n // Ref https://github.com/immersive-web/cardboard-vr-display/issues/18\n this.isChromeUsingDegrees = CHROME_VERSION >= 66;\n\n this._isEnabled = false;\n\n // Set the filter to world transform, depending on OS.\n if (this.isIOS) {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);\n } else {\n this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);\n }\n\n this.inverseWorldToScreenQ = new MathUtil.Quaternion();\n this.worldToScreenQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ = new MathUtil.Quaternion();\n this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),\n -window.orientation * Math.PI / 180);\n\n this._setScreenTransform();\n // Adjust this filter for being in landscape mode.\n if (Util.isLandscapeMode()) {\n this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);\n }\n\n // Keep track of a reset transform for resetSensor.\n this.resetQ = new MathUtil.Quaternion();\n\n this.deviceMotion.on(\"devicemotion\", this._onDeviceMotionChange);\n this.enable();\n }\n\n public enable() {\n if (this.isEnabled()) {\n return;\n }\n this.deviceMotion!.enable();\n this._isEnabled = true;\n window.addEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public disable() {\n if (!this.isEnabled()) {\n return;\n }\n this.deviceMotion!.disable();\n this._isEnabled = false;\n window.removeEventListener(\"orientationchange\", this._onScreenOrientationChange);\n }\n\n public isEnabled() {\n return this._isEnabled;\n }\n\n public destroy() {\n this.disable();\n this.deviceMotion = null;\n }\n\n public getOrientation() {\n let orientation;\n\n // Hack around using deviceorientation instead of devicemotion\n if (this.deviceMotion!.isWithoutDeviceMotion && this._deviceOrientationQ) {\n this.deviceOrientationFixQ = this.deviceOrientationFixQ || (() => {\n const y = new MathUtil.Quaternion()\n .setFromAxisAngle(new MathUtil.Vector3(0, 1, 0), -this._alpha);\n\n return y;\n })();\n\n orientation = this._deviceOrientationQ;\n const out = new MathUtil.Quaternion();\n\n out.copy(orientation);\n out.multiply(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.worldToScreenQ);\n out.multiplyQuaternions(this.deviceOrientationFixQ, out);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n } else {\n // Convert from filter space to the the same system used by the\n // deviceorientation event.\n orientation = this.filter.getOrientation();\n\n if (!orientation) {\n return null;\n }\n\n const out = this._convertFusionToPredicted(orientation);\n\n // return quaternion as glmatrix quaternion object\n const outQuat = quat.fromValues(\n out.x,\n out.y,\n out.z,\n out.w\n );\n\n return quat.normalize(outQuat, outQuat);\n }\n }\n\n private _triggerChange() {\n const orientation = this.getOrientation();\n\n // if orientation is not prepared. don't trigger change event\n if (!orientation) {\n return;\n }\n\n if (!this._prevOrientation) {\n this._prevOrientation = orientation;\n return;\n }\n\n if (quat.equals(this._prevOrientation, orientation)) {\n return;\n }\n\n this.trigger(new ComponentEvent(\"change\", { quaternion: orientation }));\n }\n\n private _convertFusionToPredicted(orientation: quat) {\n // Predict orientation.\n this.predictedQ =\n this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);\n\n // Convert to THREE coordinate system: -Z forward, Y up, X right.\n const out = new MathUtil.Quaternion();\n\n out.copy(this.filterToWorldQ);\n out.multiply(this.resetQ);\n out.multiply(this.predictedQ);\n out.multiply(this.worldToScreenQ);\n\n return out;\n }\n\n private _onDeviceMotionChange({ inputEvent }) {\n const deviceorientation = inputEvent.deviceorientation;\n const deviceMotion = inputEvent;\n const accGravity = deviceMotion.accelerationIncludingGravity;\n const rotRate = deviceMotion.adjustedRotationRate || deviceMotion.rotationRate;\n let timestampS = deviceMotion.timeStamp / 1000;\n\n if (deviceorientation) {\n if (!this._alpha) {\n this._alpha = deviceorientation.alpha;\n }\n this._deviceOrientationQ = this._deviceOrientationQ || new MathUtil.Quaternion();\n this._deviceOrientationQ.setFromEulerYXZ(\n deviceorientation.beta,\n deviceorientation.alpha,\n deviceorientation.gamma\n );\n\n this._triggerChange();\n } else {\n // Firefox Android timeStamp returns one thousandth of a millisecond.\n if (this.isFirefoxAndroid) {\n timestampS /= 1000;\n }\n\n this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);\n this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);\n\n // Browsers on iOS, Firefox/Android, and Chrome m66/Android `rotationRate`\n // is reported in degrees, so we first convert to radians.\n if (this.isIOS || this.isFirefoxAndroid || this.isChromeUsingDegrees) {\n this.gyroscope.multiplyScalar(Math.PI / 180);\n }\n\n this.filter.addAccelMeasurement(this.accelerometer, timestampS);\n this.filter.addGyroMeasurement(this.gyroscope, timestampS);\n\n this._triggerChange();\n\n this.previousTimestampS = timestampS;\n }\n }\n\n private _onScreenOrientationChange() {\n this._setScreenTransform();\n }\n\n private _setScreenTransform() {\n this.worldToScreenQ.set(0, 0, 0, 1);\n\n const orientation = window.orientation;\n\n switch (orientation) {\n case 0:\n break;\n case 90:\n case -90:\n case 180:\n this.worldToScreenQ\n .setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), orientation / -180 * Math.PI);\n break;\n default:\n break;\n }\n this.inverseWorldToScreenQ.copy(this.worldToScreenQ);\n this.inverseWorldToScreenQ.inverse();\n }\n}\n","import Component from \"@egjs/component\";\nimport { quat } from \"gl-matrix\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\n\nimport { toAxis } from \"../utils\";\nimport { util, ROTATE_CONSTANT } from \"../../utils/math-util\";\n\nimport FusionPoseSensor from \"./FusionPoseSensor\";\n\nconst getDeltaYaw = (prvQ: quat, curQ: quat): number => {\n const yawDeltaByYaw = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(util.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nconst getDeltaPitch = (prvQ: quat, curQ: quat): number => {\n const pitchDelta = util.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport default class TiltMotionInput extends Component<{}> {\n public element: HTMLElement;\n public options: { scale: number; threshold: number };\n public fusionPoseSensor: FusionPoseSensor | null;\n public axes: string[];\n public observer: InputTypeObserver | null;\n\n private _prevQuaternion: quat | null;\n private _quaternion: quat | null;\n\n public constructor(el: HTMLElement, options: Partial<{ scale: number; threshold: number }> = {}) {\n super();\n this.element = el;\n\n this._prevQuaternion = null;\n this._quaternion = null;\n\n this.fusionPoseSensor = null;\n\n this.options = {\n ...{\n scale: 1,\n threshold: 0\n }, ...options\n };\n\n this._onPoseChange = this._onPoseChange.bind(this);\n }\n\n public mapAxes(axes: string[]) {\n this.axes = axes;\n }\n\n public connect(observer: InputTypeObserver) {\n if (this.observer) {\n return this;\n }\n this.observer = observer;\n this.fusionPoseSensor = new FusionPoseSensor();\n this.fusionPoseSensor.enable();\n this._attachEvent();\n return this;\n }\n\n public disconnect() {\n if (!this.observer) {\n return this;\n }\n\n this._dettachEvent();\n this.fusionPoseSensor!.disable();\n this.fusionPoseSensor!.destroy();\n this.fusionPoseSensor = null;\n this.observer = null;\n return this;\n }\n\n public destroy() {\n this.disconnect();\n (this.element as any) = null;\n (this.options as any) = null;\n (this.axes as any) = null;\n this._prevQuaternion = null;\n this._quaternion = null;\n }\n\n private _onPoseChange(event) {\n if (!this._prevQuaternion) {\n this._prevQuaternion = quat.clone(event.quaternion);\n this._quaternion = quat.clone(event.quaternion);\n return;\n }\n\n quat.copy(this._prevQuaternion, this._quaternion!);\n quat.copy(this._quaternion!, event.quaternion);\n\n this.observer!.change(this, event, toAxis(this.axes, [\n getDeltaYaw(this._prevQuaternion, this._quaternion as quat),\n getDeltaPitch(this._prevQuaternion, this._quaternion as quat)\n ]));\n }\n\n private _attachEvent() {\n this.fusionPoseSensor!.on(\"change\", this._onPoseChange);\n }\n\n private _dettachEvent() {\n this.fusionPoseSensor!.off(\"change\", this._onPoseChange);\n }\n}\n","import { quat } from \"gl-matrix\";\n\nimport {\n util as mathUtil,\n ROTATE_CONSTANT\n} from \"../utils/math-util\";\n\nexport const toAxis = (source, offset) => offset.reduce((acc, v, i) => {\n if (source[i]) {\n acc[source[i]] = v;\n }\n return acc;\n}, {});\n\nexport const getDeltaYaw = (prvQ: quat, curQ: quat) => {\n const yawDeltaByYaw = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW) as number;\n const yawDeltaByRoll = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) *\n Math.sin(mathUtil.extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n};\n\nexport const getDeltaPitch = (prvQ: quat, curQ: quat) => {\n const pitchDelta = mathUtil.getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n\n return pitchDelta;\n};\n","import { glMatrix } from \"gl-matrix\";\n\nimport { window } from \"../utils/browser\";\n\n// Singleton\nlet screenRotationAngleInst: ScreenRotationAngle | null = null;\nlet refCount = 0;\n\nexport default class ScreenRotationAngle {\n private _spinR: number;\n private _screenOrientationAngle: number;\n\n public constructor() {\n refCount++;\n\n if (screenRotationAngleInst) {\n return screenRotationAngleInst;\n }\n /* eslint-disable */\n screenRotationAngleInst = this;\n /* eslint-enable */\n this._onDeviceOrientation = this._onDeviceOrientation.bind(this);\n this._onOrientationChange = this._onOrientationChange.bind(this);\n\n this._spinR = 0;\n\n this._screenOrientationAngle = 0;\n window.addEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.addEventListener(\"orientationchange\", this._onOrientationChange);\n }\n\n public getRadian() {\n // Join with screen orientation\n // this._testVal = this._spinR + \", \" + this._screenOrientationAngle + \", \" + window.orientation;\n return this._spinR + glMatrix.toRadian(this._screenOrientationAngle);\n }\n\n public unref() {\n if (--refCount > 0) {\n return;\n }\n\n window.removeEventListener(\"deviceorientation\", this._onDeviceOrientation);\n window.removeEventListener(\"orientationchange\", this._onOrientationChange);\n\n this._spinR = 0;\n this._screenOrientationAngle = 0;\n /* eslint-disable */\n screenRotationAngleInst = null;\n /* eslint-enable */\n refCount = 0;\n }\n\n private _onDeviceOrientation(e: DeviceOrientationEvent) {\n if (e.beta === null || e.gamma === null) {\n // (Chrome) deviceorientation is fired with invalid information {alpha=null, beta=null, ...} despite of not dispatching it. We skip it.\n return;\n }\n\n // Radian\n const betaR = glMatrix.toRadian(e.beta);\n const gammaR = glMatrix.toRadian(e.gamma);\n\n /* spinR range = [-180, 180], left side: 0 ~ -180(deg), right side: 0 ~ 180(deg) */\n this._spinR = Math.atan2(Math.cos(betaR) * Math.sin(gammaR), Math.sin(betaR));\n }\n\n private _onOrientationChange() {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientationAngle = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n /* iOS */\n this._screenOrientationAngle = window.orientation >= 0 ?\n window.orientation : 360 + (window.orientation as number);\n }\n }\n}\n","import Axes, { PanInput } from \"@egjs/axes\";\nimport { InputTypeObserver } from \"@egjs/axes/declaration/inputType/InputType\";\nimport { PanInputOption } from \"@egjs/axes/declaration/inputType/PanInput\";\n\nimport ScreenRotationAngle from \"../ScreenRotationAngle\";\n\n/**\n * RotationPanInput is extension of PanInput to compensate coordinates by screen rotation angle.\n *\n * The reason for using this function is that in VR mode,\n * the roll angle is adjusted in the direction opposite to the screen rotation angle.\n *\n * Therefore, the angle that the user touches and moves does not match the angle at which the actual object should move.\n * @extends PanInput\n */\nexport default class RotationPanInput extends PanInput {\n private _useRotation: boolean;\n private _screenRotationAngle: ScreenRotationAngle | null;\n private _userDirection: number;\n\n /**\n * Constructor\n * @private\n * @param {HTMLElement} el target element\n * @param {Object} [options] The option object\n * @param {Boolean} [options.useRotation] Whether to use rotation(or VR)\n */\n public constructor(el: HTMLElement, options: Partial<{ useRotation: boolean } & PanInputOption> = {}) {\n super(el, options);\n\n this._useRotation = false;\n this._screenRotationAngle = null;\n\n this.setUseRotation(!!(options && options.useRotation));\n\n this._userDirection = Axes.DIRECTION_ALL;\n }\n\n public setUseRotation(useRotation: boolean) {\n this._useRotation = useRotation;\n\n if (this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n this._screenRotationAngle = null;\n }\n\n if (this._useRotation) {\n this._screenRotationAngle = new ScreenRotationAngle();\n }\n }\n\n public connect(observer: InputTypeObserver) {\n // User intetened direction\n this._userDirection = this._direction;\n\n // In VR Mode, Use ALL direction if direction is not none\n // Because horizontal and vertical is changed dynamically by screen rotation.\n // this._direction is used to initialize hammerjs\n if (this._useRotation && (this._direction & Axes.DIRECTION_ALL)) {\n this._direction = Axes.DIRECTION_HORIZONTAL;\n }\n\n return super.connect(observer);\n }\n\n public destroy() {\n if (this._useRotation && this._screenRotationAngle) {\n this._screenRotationAngle.unref();\n }\n\n super.destroy();\n }\n\n protected _getOffset(properties: number[], useDirection: boolean[]) {\n if (this._useRotation === false) {\n return super._getOffset(properties, useDirection);\n }\n\n const offset = super._getOffset(properties, [true, true]);\n const newOffset = [0, 0];\n\n const theta = this._screenRotationAngle!.getRadian();\n\n const cosTheta = Math.cos(theta);\n const sinTheta = Math.sin(theta);\n\n // RotateZ\n newOffset[0] = offset[0] * cosTheta - offset[1] * sinTheta;\n newOffset[1] = offset[1] * cosTheta + offset[0] * sinTheta;\n\n // Use only user allowed direction.\n if (!(this._userDirection & Axes.DIRECTION_HORIZONTAL)) {\n newOffset[0] = 0;\n } else if (!(this._userDirection & Axes.DIRECTION_VERTICAL)) {\n newOffset[1] = 0;\n }\n\n return newOffset;\n }\n}\n\n/**\n * Override getDirectionByAngle to return DIRECTION_ALL\n * Ref: https://github.com/naver/egjs-axes/issues/99\n *\n * But we obey axes's rule. If axes's rule is problem, let's apply following code.\n */\n// PanInput.getDirectionByAngle = function (angle, thresholdAngle) {\n// \treturn DIRECTION_ALL;\n// };\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { vec3, glMatrix, quat } from \"gl-matrix\";\n\nimport FusionPoseSensor from \"./input/FusionPoseSensor\";\n\nconst Y_AXIS_VECTOR = vec3.fromValues(0, 1, 0);\n\nexport default class DeviceQuaternion extends Component<{\n change: {\n isTrusted: boolean;\n };\n}> {\n private _fusionPoseSensor: FusionPoseSensor | null;\n private _quaternion: quat;\n\n public constructor() {\n super();\n\n this._fusionPoseSensor = new FusionPoseSensor();\n this._quaternion = quat.create();\n\n this._fusionPoseSensor.enable();\n this._fusionPoseSensor.on(\"change\", e => {\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(\"change\", { isTrusted: true }));\n });\n }\n\n public getCombinedQuaternion(yaw: number) {\n const yawQ = quat.setAxisAngle(quat.create(), Y_AXIS_VECTOR, glMatrix.toRadian(-yaw));\n const conj = quat.conjugate(quat.create(), this._quaternion);\n // Multiply pitch quaternion -> device quaternion -> yaw quaternion\n const outQ = quat.multiply(quat.create(), conj, yawQ);\n\n return outQ;\n }\n\n public destroy() {\n // detach all event handler\n this.off();\n\n if (this._fusionPoseSensor) {\n this._fusionPoseSensor.off();\n this._fusionPoseSensor.destroy();\n this._fusionPoseSensor = null;\n }\n }\n}\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PinchInput, MoveKeyInput, WheelInput } from \"@egjs/axes\";\nimport { vec2, quat, glMatrix } from \"gl-matrix\";\n\nimport { SUPPORT_TOUCH, SUPPORT_DEVICEMOTION } from \"../utils/browserFeature\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { ValueOf } from \"../types/internal\";\n\nimport TiltMotionInput from \"./input/TiltMotionInput\";\nimport RotationPanInput from \"./input/RotationPanInput\";\nimport DeviceQuaternion from \"./DeviceQuaternion\";\nimport {\n GYRO_MODE,\n TOUCH_DIRECTION_YAW,\n TOUCH_DIRECTION_PITCH,\n TOUCH_DIRECTION_ALL,\n MC_DECELERATION,\n MC_MAXIMUM_DURATION,\n MC_BIND_SCALE,\n MAX_FIELD_OF_VIEW,\n PAN_SCALE,\n YAW_RANGE_HALF,\n PITCH_RANGE_HALF,\n CIRCULAR_PITCH_RANGE_HALF,\n CONTROL_MODE_VR,\n CONTROL_MODE_YAWPITCH,\n TOUCH_DIRECTION_NONE\n} from \"./consts\";\n\n\nconst DEFAULT_YAW_RANGE = [-YAW_RANGE_HALF, YAW_RANGE_HALF];\nconst DEFAULT_PITCH_RANGE = [-PITCH_RANGE_HALF, PITCH_RANGE_HALF];\nconst CIRCULAR_PITCH_RANGE = [-CIRCULAR_PITCH_RANGE_HALF, CIRCULAR_PITCH_RANGE_HALF];\n\nexport interface YawPitchControlOptions {\n element: HTMLElement | null;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n touchDirection: number;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n aspectRatio: number;\n}\ninterface YawPitchControlEvents {\n change: ComponentEvent<{\n yaw: number;\n pitch: number;\n fov: number;\n quaternion: quat | null;\n targetElement: HTMLElement;\n isTrusted: boolean;\n }>;\n hold: ComponentEvent<{\n isTrusted: boolean;\n }>;\n animationEnd: ComponentEvent<{\n isTrusted: boolean;\n }>;\n}\n\n/**\n * A module used to provide coordinate based on yaw/pitch orientation. This module receives user touch action, keyboard, mouse and device orientation(if it exists) as input, then combines them and converts it to yaw/pitch coordinates.\n * @alias eg.YawPitchControl\n * @extends eg.Component\n *\n * @support {\"ie\": \"10+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass YawPitchControl extends Component {\n public static VERSION = VERSION;\n // Expose DeviceOrientationControls sub module for test purpose\n public static CONTROL_MODE_VR = CONTROL_MODE_VR;\n public static CONTROL_MODE_YAWPITCH = CONTROL_MODE_YAWPITCH;\n public static TOUCH_DIRECTION_ALL = TOUCH_DIRECTION_ALL;\n public static TOUCH_DIRECTION_YAW = TOUCH_DIRECTION_YAW;\n public static TOUCH_DIRECTION_PITCH = TOUCH_DIRECTION_PITCH;\n public static TOUCH_DIRECTION_NONE = TOUCH_DIRECTION_NONE;\n\n public options: YawPitchControlOptions;\n\n private _element: HTMLElement | null;\n private _initialFov: number;\n private _enabled: boolean;\n private _isAnimating: boolean;\n private _deviceQuaternion: DeviceQuaternion | null;\n\n private _axes: Axes;\n private _axesPanInput: RotationPanInput;\n private _axesWheelInput: WheelInput;\n private _axesTiltMotionInput: TiltMotionInput | null;\n private _axesPinchInput: PinchInput | null;\n private _axesMoveKeyInput: MoveKeyInput;\n\n /**\n * @param {object} options The option object of the eg.YawPitch module\n * @param {HTMLElement|null}[options.element=null] element A base element for the eg.YawPitch module\n * @param {number} [options.yaw=0] initial yaw (degree)\n * @param {number} [options.pitch=0] initial pitch (degree)\n * @param {number} [options.fov=65] initial field of view (degree)\n * @param {boolean} [optiosn.showPolePoint=true] Indicates whether pole is shown\n * @param {boolean} [options.useZoom=true] Indicates whether zoom is available\n * @param {boolean} [options.useKeyboard=true] Indicates whether keyboard is enabled\n * @param {string} [config.gyroMode=yawPitch] Enables control through device motion.\n * @param {number} [options.touchDirection=TOUCH_DIRECTION_ALL] Direction of the touch movement (TOUCH_DIRECTION_ALL: all, TOUCH_DIRECTION_YAW: horizontal, TOUCH_DIRECTION_PITCH: vertical, TOUCH_DIRECTION_NONE: no move)\n * @param {number[]} [options.yawRange=[-180, 180] Range of visible yaw\n * @param {number[]} [options.pitchRange=[-90, 90] Range of visible pitch\n * @param {number[]} [options.fovRange=[30, 110] Range of FOV\n * @param {number} [options.aspectRatio=1] Aspect Ratio\n */\n public constructor(options: Partial) {\n super();\n this.options = {} as any;\n\n const opt = {\n ...{\n element: null,\n yaw: 0,\n pitch: 0,\n fov: 65,\n showPolePoint: false,\n useZoom: true,\n useKeyboard: true,\n gyroMode: GYRO_MODE.YAWPITCH,\n touchDirection: TOUCH_DIRECTION_ALL,\n yawRange: DEFAULT_YAW_RANGE,\n pitchRange: DEFAULT_PITCH_RANGE,\n fovRange: [30, 110],\n aspectRatio: 1 /* TODO: Need Mandatory? */\n }, ...options\n };\n\n this._element = opt.element;\n this._initialFov = opt.fov;\n this._enabled = false;\n this._isAnimating = false;\n this._deviceQuaternion = null;\n\n this._initAxes(opt);\n this.option(opt);\n }\n\n /**\n * Update Pan Scale\n *\n * Scale(Sensitivity) values of panning is related with fov and height.\n * If at least one of them is changed, this function need to be called.\n * @param {*} param\n */\n public updatePanScale(param: Partial<{\n height: number;\n }> = {}) {\n const fov = this._axes.get().fov;\n const areaHeight = param.height || parseInt(window.getComputedStyle(this._element!).height, 10);\n const scale = MC_BIND_SCALE[0] * fov / this._initialFov * PAN_SCALE / areaHeight;\n\n this._axesPanInput.options.scale = [scale, scale];\n this._axes.options.deceleration = MC_DECELERATION * fov / MAX_FIELD_OF_VIEW;\n\n return this;\n }\n\n public option(): YawPitchControlOptions;\n public option(key: K): YawPitchControlOptions[K];\n public option(key: K, newValue: YawPitchControlOptions[K]): YawPitchControl;\n public option(newOptions: Partial): YawPitchControl;\n /*\n * Override component's option method\n * to call method for updating values which is affected by option change.\n *\n * @param {*} args\n */\n public option(key?: K | Partial, newValue?: YawPitchControlOptions[K]) {\n // Getter\n if (!key) {\n return this._getOptions();\n } else if (key && typeof key === \"string\" && typeof newValue === \"undefined\") {\n return this._getOptions(key);\n }\n\n // Setter\n let newOptions: Partial = {};\n let changedKeyList: string[] = []; // TODO: if value is not changed, then do not push on changedKeyList.\n\n if (typeof key === \"string\") {\n changedKeyList.push(key);\n newOptions[key] = newValue;\n } else {\n const options = key; // Retrieving object here\n changedKeyList = Object.keys(options);\n newOptions = {...options};\n }\n\n this._setOptions(this._getValidatedOptions(newOptions));\n this._applyOptions(changedKeyList);\n return this;\n }\n\n /**\n * Enable YawPitch functionality\n * @method eg.YawPitch#enable\n */\n public enable() {\n if (this._enabled) {\n return this;\n }\n\n this._enabled = true;\n\n // touchDirection is decided by parameter is valid string (Ref. Axes.connect)\n this._applyOptions(Object.keys(this.options));\n\n // TODO: Is this code is needed? Check later.\n this.updatePanScale();\n\n return this;\n }\n\n /**\n * Disable YawPitch functionality\n * @method eg.YawPitch#disable\n */\n public disable(persistOrientation: boolean = false) {\n if (!this._enabled) {\n return this;\n }\n\n // TODO: Check peristOrientation is needed!\n if (!persistOrientation) {\n this._resetOrientation();\n }\n this._axes.disconnect();\n this._enabled = false;\n return this;\n }\n\n /**\n * Set one or more of yaw, pitch, fov\n * @param {Object} coordinate yaw, pitch, fov\n * @param {Number} duration Animation duration. if it is above 0 then it's animated.\n */\n public lookAt({yaw, pitch, fov}, duration) {\n const pos = this._axes.get();\n\n const y = yaw === undefined ? 0 : yaw - pos.yaw;\n const p = pitch === undefined ? 0 : pitch - pos.pitch;\n const f = fov === undefined ? 0 : fov - pos.fov;\n\n // Allow duration of animation to have more than MC_MAXIMUM_DURATION.\n this._axes.options.maximumDuration = Infinity;\n\n this._axes.setBy({\n yaw: y,\n pitch: p,\n fov: f\n }, duration);\n }\n\n public getYawPitch() {\n const yawPitch = this._axes.get();\n\n return {\n yaw: yawPitch.yaw,\n pitch: yawPitch.pitch\n };\n }\n\n public getFov() {\n return this._axes.get().fov;\n }\n\n public getQuaternion() {\n const pos = this._axes.get();\n\n return this._deviceQuaternion!.getCombinedQuaternion(pos.yaw);\n }\n\n public shouldRenderWithQuaternion() {\n return this.options.gyroMode === GYRO_MODE.VR;\n }\n\n /**\n * Destroys objects\n */\n public destroy() {\n /* eslint-disable @typescript-eslint/no-unused-expressions */\n this._axes && this._axes.destroy();\n this._axesPanInput && this._axesPanInput.destroy();\n this._axesWheelInput && this._axesWheelInput.destroy();\n this._axesTiltMotionInput && this._axesTiltMotionInput.destroy();\n this._axesPinchInput && this._axesPinchInput.destroy();\n this._axesMoveKeyInput && this._axesMoveKeyInput.destroy();\n this._deviceQuaternion && this._deviceQuaternion.destroy();\n /* eslint-enable @typescript-eslint/no-unused-expressions */\n }\n\n private _initAxes(opt: YawPitchControlOptions) {\n const yRange = this._updateYawRange(opt.yawRange, opt.fov, opt.aspectRatio);\n const pRange = this._updatePitchRange(opt.pitchRange, opt.fov, opt.showPolePoint);\n const useRotation = opt.gyroMode === GYRO_MODE.VR;\n\n this._axesPanInput = new RotationPanInput(this._element!, {useRotation});\n this._axesWheelInput = new WheelInput(this._element, {scale: -4});\n this._axesTiltMotionInput = null;\n this._axesPinchInput = SUPPORT_TOUCH ? new PinchInput(this._element, {scale: -1}) : null;\n this._axesMoveKeyInput = new MoveKeyInput(this._element, {scale: [-6, 6]});\n\n this._axes = new Axes({\n yaw: {\n range: yRange,\n circular: this._isCircular(yRange),\n bounce: [0, 0]\n },\n pitch: {\n range: pRange,\n circular: this._isCircular(pRange),\n bounce: [0, 0]\n },\n fov: {\n range: opt.fovRange,\n circular: [false, false],\n bounce: [0, 0]\n }\n }, {\n deceleration: MC_DECELERATION,\n maximumDuration: MC_MAXIMUM_DURATION\n }, {\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }).on({\n // TODO: change event type after Axes event type inference update\n hold: (evt: any) => {\n // Restore maximumDuration not to be spin too mush.\n this._axes.options.maximumDuration = MC_MAXIMUM_DURATION;\n\n this.trigger(new ComponentEvent(\"hold\", { isTrusted: evt.isTrusted }));\n },\n change: (evt: any) => {\n if (evt.delta.fov !== 0) {\n this._updateControlScale(evt);\n this.updatePanScale();\n }\n this._triggerChange(evt);\n },\n release: evt => {\n this._triggerChange(evt);\n },\n animationEnd: (evt: any) => {\n this.trigger(new ComponentEvent(\"animationEnd\", { isTrusted: evt.isTrusted }));\n }\n });\n }\n\n private _getValidatedOptions(newOptions: Partial) {\n if (newOptions.yawRange) {\n newOptions.yawRange =\n this._getValidYawRange(newOptions.yawRange, newOptions.fov, newOptions.aspectRatio);\n }\n if (newOptions.pitchRange) {\n newOptions.pitchRange = this._getValidPitchRange(newOptions.pitchRange, newOptions.fov);\n }\n return newOptions;\n }\n\n private _getOptions(): YawPitchControlOptions;\n private _getOptions(key: K): YawPitchControlOptions[K];\n private _getOptions(key?: K) {\n let value;\n\n if (typeof key === \"string\") {\n value = this.options[key];\n } else if (arguments.length === 0) {\n value = this.options;\n }\n return value;\n }\n\n private _setOptions(options: Partial): void {\n for (const key in options) {\n this.options[key] = options[key];\n }\n }\n\n private _applyOptions(keys: string[]) {\n const options = this.options;\n const axes = this._axes;\n const isVR = options.gyroMode === GYRO_MODE.VR;\n const isYawPitch = options.gyroMode === GYRO_MODE.YAWPITCH;\n // If it's VR mode, restrict user interaction to yaw direction only\n const touchDirection = isVR ?\n (TOUCH_DIRECTION_YAW & options.touchDirection) :\n options.touchDirection;\n\n // If one of below is changed, call updateControlScale()\n if (keys.some(key =>\n key === \"showPolePoint\" || key === \"fov\" || key === \"aspectRatio\" ||\n key === \"yawRange\" || key === \"pitchRange\"\n )) {\n // If fov is changed, update pan scale\n if (keys.indexOf(\"fov\") >= 0) {\n axes.setTo({\"fov\": options.fov});\n this.updatePanScale();\n }\n\n this._updateControlScale();\n }\n\n if (keys.some(key => key === \"fovRange\")) {\n const fovRange = options.fovRange;\n const prevFov = axes.get().fov;\n let nextFov = axes.get().fov;\n\n vec2.copy(axes.axis.fov.range as vec2, fovRange as vec2);\n\n if (nextFov < fovRange[0]) {\n nextFov = fovRange[0];\n } else if (prevFov > fovRange[1]) {\n nextFov = fovRange[1];\n }\n\n if (prevFov !== nextFov) {\n axes.setTo({\n fov: nextFov\n }, 0);\n this._updateControlScale();\n this.updatePanScale();\n }\n }\n\n if (keys.some(key => key === \"gyroMode\") && SUPPORT_DEVICEMOTION) {\n // Disconnect first\n if (this._axesTiltMotionInput) {\n this._axes.disconnect(this._axesTiltMotionInput);\n this._axesTiltMotionInput.destroy();\n this._axesTiltMotionInput = null;\n }\n\n if (this._deviceQuaternion) {\n this._deviceQuaternion.destroy();\n this._deviceQuaternion = null;\n }\n\n if (isVR) {\n this._initDeviceQuaternion();\n } else if (isYawPitch) {\n this._axesTiltMotionInput = new TiltMotionInput(this._element!);\n this._axes.connect([\"yaw\", \"pitch\"], this._axesTiltMotionInput);\n }\n\n this._axesPanInput.setUseRotation(isVR);\n }\n\n if (keys.some(key => key === \"useKeyboard\")) {\n const useKeyboard = options.useKeyboard;\n\n if (useKeyboard) {\n axes.connect([\"yaw\", \"pitch\"], this._axesMoveKeyInput);\n } else {\n axes.disconnect(this._axesMoveKeyInput);\n }\n }\n\n if (keys.some(key => key === \"useZoom\")) {\n const useZoom = options.useZoom;\n\n // Disconnect first\n axes.disconnect(this._axesWheelInput);\n if (useZoom) {\n axes.connect([\"fov\"], this._axesWheelInput);\n }\n }\n\n this._togglePinchInputByOption(options.touchDirection, options.useZoom);\n\n if (keys.some(key => key === \"touchDirection\") && this._enabled) {\n this._enableTouch(touchDirection);\n }\n }\n\n private _togglePinchInputByOption(touchDirection: YawPitchControlOptions[\"touchDirection\"], useZoom: boolean) {\n if (this._axesPinchInput) {\n // disconnect first\n this._axes.disconnect(this._axesPinchInput);\n\n // If the touchDirection option is not ALL, pinchInput should be disconnected to make use of a native scroll.\n if (\n useZoom &&\n touchDirection === TOUCH_DIRECTION_ALL &&\n // TODO: Get rid of using private property of axes instance.\n (this._axes as any)._inputs.indexOf(this._axesPinchInput) === -1\n ) {\n this._axes.connect([\"fov\"], this._axesPinchInput);\n }\n }\n }\n\n private _enableTouch(direction: YawPitchControlOptions[\"touchDirection\"]) {\n // Disconnect first\n if (this._axesPanInput) {\n this._axes.disconnect(this._axesPanInput);\n }\n\n const yawEnabled = direction & TOUCH_DIRECTION_YAW ? \"yaw\" : null;\n const pitchEnabled = direction & TOUCH_DIRECTION_PITCH ? \"pitch\" : null;\n\n this._axes.connect([yawEnabled, pitchEnabled] as string[], this._axesPanInput);\n }\n\n private _initDeviceQuaternion() {\n this._deviceQuaternion = new DeviceQuaternion();\n this._deviceQuaternion.on(\"change\", e => {\n this._triggerChange(e);\n });\n }\n\n private _getValidYawRange(newYawRange: number[], newFov?: number, newAspectRatio?: number) {\n const ratio = this._adjustAspectRatio(newAspectRatio || this.options.aspectRatio || 1);\n const fov = newFov || this._axes.get().fov;\n const horizontalFov = fov * ratio;\n const isValid = newYawRange[1] - newYawRange[0] >= horizontalFov;\n\n if (isValid) {\n return newYawRange;\n } else {\n return this.options.yawRange || DEFAULT_YAW_RANGE;\n }\n }\n\n private _getValidPitchRange(newPitchRange: number[], newFov?: number) {\n const fov = newFov || this._axes.get().fov;\n const isValid = newPitchRange[1] - newPitchRange[0] >= fov;\n\n if (isValid) {\n return newPitchRange;\n } else {\n return this.options.pitchRange || DEFAULT_PITCH_RANGE;\n }\n }\n\n private _isCircular(range: number[]) {\n return range[1] - range[0] < 360 ? [false, false] : [true, true];\n }\n\n /**\n * Update yaw/pitch min/max by 5 factor\n *\n * 1. showPolePoint\n * 2. fov\n * 3. yawRange\n * 4. pitchRange\n * 5. aspectRatio\n *\n * If one of above is changed, call this function\n */\n private _updateControlScale(changeEvt?: any) { // TODO: Change type after Axes type inference update\n const opt = this.options;\n const fov = this._axes.get().fov;\n\n const pRange = this._updatePitchRange(opt.pitchRange, fov, opt.showPolePoint);\n const yRange = this._updateYawRange(opt.yawRange, fov, opt.aspectRatio);\n\n // TODO: If not changed!?\n const pos = this._axes.get();\n let y = pos.yaw;\n let p = pos.pitch;\n\n vec2.copy(this._axes.axis.yaw.range as any, yRange as any);\n vec2.copy(this._axes.axis.pitch.range as any, pRange as any);\n this._axes.axis.yaw.circular = this._isCircular(yRange);\n this._axes.axis.pitch.circular = this._isCircular(pRange);\n\n /**\n * update yaw/pitch by it's range.\n */\n if (y < yRange[0]) {\n y = yRange[0];\n } else if (y > yRange[1]) {\n y = yRange[1];\n }\n\n if (p < pRange[0]) {\n p = pRange[0];\n } else if (p > pRange[1]) {\n p = pRange[1];\n }\n\n if (changeEvt) {\n changeEvt.set({\n yaw: y,\n pitch: p\n });\n }\n\n this._axes.setTo({\n yaw: y,\n pitch: p\n }, 0);\n\n return this;\n }\n\n private _updatePitchRange(pitchRange: number[], fov: number, showPolePoint: boolean) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n // Circular pitch on VR\n return CIRCULAR_PITCH_RANGE;\n }\n\n const verticalAngle = pitchRange[1] - pitchRange[0];\n const halfFov = fov / 2;\n const isPanorama = verticalAngle < 180;\n\n if (showPolePoint && !isPanorama) {\n // Use full pinch range\n return pitchRange.concat();\n }\n\n // Round value as movableCood do.\n return [pitchRange[0] + halfFov, pitchRange[1] - halfFov];\n }\n\n private _updateYawRange(yawRange: number[], fov: number, aspectRatio: number) {\n if (this.options.gyroMode === GYRO_MODE.VR) {\n return DEFAULT_YAW_RANGE;\n }\n\n const horizontalAngle = yawRange[1] - yawRange[0];\n\n /**\n * Full 360 Mode\n */\n if (horizontalAngle >= 360) {\n // Don't limit yaw range on Full 360 mode.\n return yawRange.concat();\n }\n\n /**\n * Panorama mode\n */\n // Ref : https://github.com/naver/egjs-view360/issues/290\n const halfHorizontalFov =\n mathUtil.toDegree(Math.atan2(aspectRatio, 1 / Math.tan(glMatrix.toRadian(fov / 2)))) as number;\n\n // Round value as movableCood do.\n return [\n yawRange[0] + halfHorizontalFov,\n yawRange[1] - halfHorizontalFov\n ];\n }\n\n // TODO: update param type after Axes event type inference update\n private _triggerChange(evt: any) {\n const pos = this._axes.get();\n const opt = this.options;\n const event: YawPitchControlEvents[\"change\"] extends ComponentEvent ? T : never = {\n targetElement: opt.element as HTMLElement,\n isTrusted: evt.isTrusted,\n yaw: pos.yaw,\n pitch: pos.pitch,\n fov: pos.fov,\n quaternion: null\n };\n\n if (opt.gyroMode === GYRO_MODE.VR && this._deviceQuaternion) {\n event.quaternion = this._deviceQuaternion.getCombinedQuaternion(pos.yaw);\n }\n\n this.trigger(new ComponentEvent(\"change\", event));\n }\n\n // TODO: makes constant to be logic\n private _adjustAspectRatio(input: number) {\n const inputRange = [\n 0.520, 0.540, 0.563, 0.570, 0.584, 0.590, 0.609, 0.670,\n 0.702, 0.720, 0.760, 0.780, 0.820, 0.920, 0.970, 1.00, 1.07, 1.14, 1.19,\n 1.25, 1.32, 1.38, 1.40, 1.43, 1.53, 1.62, 1.76, 1.77, 1.86, 1.96, 2.26,\n 2.30, 2.60, 3.00, 5.00, 6.00\n ];\n const outputRange = [\n 0.510, 0.540, 0.606, 0.560, 0.628, 0.630, 0.647, 0.710,\n 0.736, 0.757, 0.780, 0.770, 0.800, 0.890, 0.975, 1.00, 1.07, 1.10, 1.15,\n 1.18, 1.22, 1.27, 1.30, 1.33, 1.39, 1.45, 1.54, 1.55, 1.58, 1.62, 1.72,\n 1.82, 1.92, 2.00, 2.24, 2.30\n ];\n\n let rangeIdx = -1;\n\n for (let i = 0; i < inputRange.length - 1; i++) {\n if (inputRange[i] <= input && inputRange[i + 1] >= input) {\n rangeIdx = i;\n break;\n }\n }\n\n if (rangeIdx === -1) {\n if (inputRange[0] > input) {\n return outputRange[0];\n } else {\n // FIXME: this looks definitely wrong\n return outputRange[(outputRange[0] as any).length - 1];\n }\n }\n\n const inputA = inputRange[rangeIdx];\n const inputB = inputRange[rangeIdx + 1];\n const outputA = outputRange[rangeIdx];\n const outputB = outputRange[rangeIdx + 1];\n\n return this._lerp(outputA, outputB, (input - inputA) / (inputB - inputA));\n }\n\n private _lerp(a: number, b: number, fraction: number) {\n return a + fraction * (b - a);\n }\n\n private _resetOrientation() {\n const opt = this.options;\n\n this._axes.setTo({\n yaw: opt.yaw,\n pitch: opt.pitch,\n fov: opt.fov\n }, 0);\n\n return this;\n }\n}\n\nexport default YawPitchControl;\n","import WebGLUtils from \"../WebGLUtils\";\nimport { STEREO_FORMAT } from \"../../PanoViewer/consts\";\nimport { ValueOf } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nconst latitudeBands = 60;\nconst longitudeBands = 60;\nconst radius = 2;\nconst ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\nlet latIdx: number;\nlet lngIdx: number;\n\nfor (latIdx = 0; latIdx <= latitudeBands; latIdx++) {\n const theta = (latIdx / latitudeBands - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const phi = (lngIdx / longitudeBands - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / longitudeBands;\n const v = latIdx / latitudeBands;\n\n textureCoordData.push(u, v);\n vertexPositionData.push(radius * x, radius * y, radius * z);\n\n if (lngIdx !== longitudeBands && latIdx !== latitudeBands) {\n const a = latIdx * (longitudeBands + 1) + lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n}\n\nclass SphereRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n private _stereoFormat: ValueOf;\n\n public constructor(format: SphereRenderer[\"_stereoFormat\"]) {\n super();\n\n this._stereoFormat = format;\n }\n\n public render(ctx: Parameters[0]) {\n const {gl, shaderProgram} = ctx;\n\n let leftEyeScaleOffset: number[];\n let rightEyeScaleOffset: number[];\n\n switch (this._stereoFormat) {\n case STEREO_FORMAT.TOP_BOTTOM:\n leftEyeScaleOffset = [1, 0.5, 0, 0];\n rightEyeScaleOffset = [1, 0.5, 0, 0.5];\n break;\n case STEREO_FORMAT.LEFT_RIGHT:\n leftEyeScaleOffset = [0.5, 1, 0, 0];\n rightEyeScaleOffset = [0.5, 1, 0.5, 0];\n break;\n default:\n leftEyeScaleOffset = [1, 1, 0, 0];\n rightEyeScaleOffset = [1, 1, 0, 0];\n }\n\n const uTexScaleOffset = gl.getUniformLocation(shaderProgram, \"uTexScaleOffset\");\n\n gl.uniform4fv(uTexScaleOffset, [...leftEyeScaleOffset, ...rightEyeScaleOffset]);\n\n super.render(ctx);\n }\n\n public getVertexPositionData() {\n return SphereRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return SphereRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return SphereRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nuniform float uEye;\nuniform vec4 uTexScaleOffset[2];\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vec4 scaleOffset = uTexScaleOffset[int(uEye)];\n vTextureCoord = aTextureCoord.xy * scaleOffset.xy + scaleOffset.zw;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vTextureCoord.st);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const { width, height } = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n}\n\nexport default SphereRenderer;\n","/**\n * Constant value for gyro mode.
(Reference {@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide})\n * @ko gyro 모드 대한 상수 값.
({@link https://github.com/naver/egjs-view360/wiki/PanoViewer-3.0-User-Guide} 참고)\n * @namespace\n * @name GYRO_MODE\n * @memberof eg.view360.PanoViewer\n */\n/**\n * Disable gyro\n * @ko gyro 비활성화\n * @name NONE\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"none\"\n */\n/**\n * YawPitch Mode\n * @ko YawPitch Mode\n * @name YAWPITCH\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"yawPitch\"\n */\n/**\n * VR Mode\n * @ko VR Mode\n * @name VR\n * @memberof eg.view360.PanoViewer.GYRO_MODE\n * @constant\n * @type {String}\n * @default \"VR\"\n */\nimport { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\nimport { GYRO_MODE } from \"../YawPitchControl/consts\";\n\n/**\n * Constant value for errors\n * @ko 에러에 대한 상수 값\n * @namespace\n * @name ERROR_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst ERROR_TYPE = {\n /**\n * Unsupported device\n * @ko 미지원 기기\n * @name INVALID_DEVICE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 10\n */\n INVALID_DEVICE: 10,\n /**\n * Webgl not support\n * @ko WEBGL 미지원\n * @name NO_WEBGL\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 11\n */\n NO_WEBGL: 11,\n /**\n * Failed to load image\n * @ko 이미지 로드 실패\n * @name FAIL_IMAGE_LOAD\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 12\n */\n FAIL_IMAGE_LOAD: 12,\n /**\n * Failed to bind texture\n * @ko 텍스쳐 바인딩 실패\n * @name FAIL_BIND_TEXTURE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 13\n */\n FAIL_BIND_TEXTURE: 13,\n /**\n * Only one resource(image or video) should be specified\n * @ko 리소스 지정 오류 (image 혹은 video 중 하나만 지정되어야 함)\n * @name INVALID_RESOURCE\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 14\n */\n INVALID_RESOURCE: 14,\n /**\n * WebGL context lost occurred\n * @ko WebGL context lost 발생\n * @name RENDERING_CONTEXT_LOST\n * @memberof eg.view360.PanoViewer.ERROR_TYPE\n * @constant\n * @type {Number}\n * @default 15\n */\n RENDERING_CONTEXT_LOST: 15\n};\n\n/**\n * Constant value for events\n * @ko 이벤트에 대한 상수 값\n * @namespace\n * @name EVENTS\n * @memberof eg.view360.PanoViewer\n */\nconst PANOVIEWER_EVENTS: {\n READY: \"ready\";\n VIEW_CHANGE: \"viewChange\";\n ANIMATION_END: \"animationEnd\";\n ERROR: \"error\";\n} = {\n /**\n * Events that is fired when PanoViewer is ready to show image and handle user interaction.\n * @ko PanoViewer 가 사용자의 인터렉션 및 렌더링이 준비되상태에 발생하는 이벤트\n * @name READY\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default ready\n */\n READY: \"ready\",\n /**\n * Events that is fired when direction or fov is changed.\n * @ko PanoViewer 에서 바라보고 있는 방향이나 FOV(화각)가 변경되었을때 발생하는 이벤트\n * @name VIEW_CHANGE\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default viewChange\n */\n VIEW_CHANGE: \"viewChange\",\n /**\n * Events that is fired when animation which is triggered by inertia is ended.\n * @ko 관성에 의한 애니메이션 동작이 완료되었을때 발생하는 이벤트\n * @name ANIMATION_END\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default animationEnd\n */\n ANIMATION_END: \"animationEnd\",\n /**\n * Events that is fired when error occurs\n * @ko 에러 발생 시 발생하는 이벤트\n * @name ERROR\n * @memberof eg.view360.PanoViewer.EVENTS\n * @constant\n * @type {String}\n * @default error\n */\n ERROR: \"error\"\n};\n\n/**\n * Constant value for projection type\n * @ko 프로젝션 타입 대한 상수 값\n * @namespace\n * @name PROJECTION_TYPE\n * @memberof eg.view360.PanoViewer\n */\nconst PROJECTION_TYPE: {\n EQUIRECTANGULAR: \"equirectangular\";\n CUBEMAP: \"cubemap\";\n CUBESTRIP: \"cubestrip\";\n PANORAMA: \"panorama\";\n STEREOSCOPIC_EQUI: \"stereoequi\";\n} = {\n /**\n * Constant value for equirectangular type.\n * @ko equirectangular 에 대한 상수 값.\n * @name EQUIRECTANGULAR\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default equirectangular\n */\n EQUIRECTANGULAR: \"equirectangular\",\n /**\n * Constant value for cubemap type.\n * @ko cubemap 에 대한 상수 값.\n * @name CUBEMAP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubemap\n */\n CUBEMAP: \"cubemap\",\n /**\n * Constant value for cubestrip type.\n * Cubestrip is a format for a single image with a combination of six cube faces. It is almost identical to cubemap, but it is implemented in a different way. It aims at better performance and efficiency. In addition, it automatically detects and supports EAC.\n * @ko cubemap 에 대한 상수 값.Cubestrip 은 cube 면이 6개가 조합된 조합을 한장의 이미지를 위한 포맷이다. cubemap 과 사용방법이 거의 동일하지만 다른 방식으로 구현되었다. 보다 좋은 성능과 효율성을 목적으로 한다. 더불어 자동으로 EAC 를 감지하고 지원한다.\n * @name CUBESTRIP\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default cubestrip\n */\n CUBESTRIP: \"cubestrip\",\n /**\n * Constant value for PANORAMA type.\n *\n * PANORAMA is a format for a panorma image which is taken from smartphone.\n * @ko PANORAMA 에 대한 상수값. 파노라마는 스마트 폰에서 가져온 파노라마 이미지의 형식입니다.\n *\n * @name PANORAMA\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default panorama\n */\n PANORAMA: \"panorama\",\n /**\n * Constant value for EQUI_STEREOSCOPY type.\n *\n * Constant value for EQUI_STEREOSCOPY. Stereoscopy image format of EQUIRECTANGULAR. It is an experimental function to show a stereoscopic type equirectangular image on a plane. It does not support stereoscopic viewing function through special visual equipment at present.\n * @ko EQUI_STEREOSCOPY 에 대한 상수값. EQUIRECTANGULAR 의 Stereoscopy 이미지 형식입니다. Stereoscopic 형태의 equirectangular 이미지를 평면에 보여주기 위한 실험적인 기능으로 현재는 특수한 시각 장비를 통한 입체적인 보기 기능은 지원하지 않습니다.\n *\n * @name STEREOSCOPIC_EQUI\n * @memberof eg.view360.PanoViewer.PROJECTION_TYPE\n * @constant\n * @type {String}\n * @default stereoequi\n */\n STEREOSCOPIC_EQUI: \"stereoequi\"\n};\n\n/**\n * A constant value for the format of the stereoscopic equirectangular projection type.\n * @ko Stereoscopic equirectangular 프로젝션 타입의 포맷에 대한 상수 값\n * @namespace\n * @name STEREO_FORMAT\n * @memberof eg.view360.PanoViewer\n */\nconst STEREO_FORMAT: {\n TOP_BOTTOM: \"3dv\";\n LEFT_RIGHT: \"3dh\";\n NONE: \"\";\n} = {\n /**\n * A constant value for format of top bottom stereoscopic 360 equirectangular projection.\n * @ko top bottom stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name TOP_BOTTOM\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dv\"\n */\n TOP_BOTTOM: \"3dv\",\n /**\n * A constant value for format of left right stereoscopic 360 equirectangular projection.\n * @ko Left right stereoscopic 360 equirectangular projection 콘텐츠 포맷에 대한 상수값.\n * @name LEFT_RIGHT\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"3dh\"\n */\n LEFT_RIGHT: \"3dh\",\n /**\n * A constant value specifying media is not in stereoscopic format.\n * @ko Stereoscopic 영상이 아닐 경우에 적용하는 상수값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.STEREO_FORMAT\n * @constant\n * @type {String}\n * @default \"\"\n */\n NONE: \"\"\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst PANOVIEWER_OPTIONS: { [key in keyof PanoViewerOptions]: true } = {\n image: true,\n video: true,\n projectionType: true,\n cubemapConfig: true,\n stereoFormat: true,\n width: true,\n height: true,\n yaw: true,\n pitch: true,\n fov: true,\n showPolePoint: true,\n useZoom: true,\n useKeyboard: true,\n gyroMode: true,\n yawRange: true,\n pitchRange: true,\n fovRange: true,\n touchDirection: true,\n canvasClass: true\n};\n\nconst DEFAULT_CANVAS_CLASS = \"view360-canvas\";\n\nexport {\n GYRO_MODE,\n PANOVIEWER_EVENTS,\n ERROR_TYPE,\n PROJECTION_TYPE,\n STEREO_FORMAT,\n PANOVIEWER_OPTIONS,\n DEFAULT_CANVAS_CLASS\n};\n","import { ImageCandidate, VideoCandidate } from \"../types/internal\";\nimport { Merged } from \"../types/internal\";\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: From, ...srcs: To[]): Merged => {\n srcs.forEach(source => {\n\t Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n\t });\n });\n\n return target as Merged;\n};\n\nexport const toImageElement = (image: ImageCandidate): HTMLImageElement | HTMLImageElement[] => {\n const images = image instanceof Array ? image : [image];\n const parsedImages = images.map(img => {\n let imgEl = img;\n\n if (typeof img === \"string\") {\n imgEl = new Image();\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = img;\n }\n return imgEl as HTMLImageElement;\n });\n\n return parsedImages.length === 1\n ? parsedImages[0]\n : parsedImages;\n};\n\nexport const toVideoElement = (videoCandidate: VideoCandidate): HTMLVideoElement => {\n if (videoCandidate instanceof HTMLVideoElement) {\n return videoCandidate;\n } else {\n // url\n const video = document.createElement(\"video\");\n video.setAttribute(\"crossorigin\", \"anonymous\");\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.setAttribute(\"playsinline\", \"\");\n\n if (videoCandidate instanceof Array) {\n videoCandidate.forEach(v => appendSourceElement(video, v));\n } else {\n appendSourceElement(video, videoCandidate);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0) {\n if (video.readyState < 1) {\n video.load();\n }\n }\n\n return video;\n }\n};\n\n/**\n *\n * @param {Object | String} videoUrl Object or String containing Video Source URL비디오 URL 정보를 담고 있는 문자열이나 객체 {type, src}\n */\nexport const appendSourceElement = (video: HTMLVideoElement, videoUrl: string | { src: string; type: string }) => {\n let videoSrc: string | undefined;\n let videoType: string | undefined;\n\n if (typeof videoUrl === \"object\") {\n videoSrc = videoUrl.src;\n videoType = videoUrl.type;\n } else if (typeof videoUrl === \"string\") {\n videoSrc = videoUrl;\n }\n\n if (!videoSrc) {\n return false;\n }\n\n const sourceElement = document.createElement(\"source\");\n\n sourceElement.src = videoSrc;\n if (videoType) {\n sourceElement.type = videoType;\n }\n\n video.appendChild(sourceElement);\n};\n","import agent from \"@egjs/agent\";\n\nimport { TypedArray } from \"../types/internal\";\n\nconst WEBGL_ERROR_CODE = {\n \"0\": \"NO_ERROR\",\n \"1280\": \"INVALID_ENUM\",\n \"1281\": \"INVALID_VALUE\",\n \"1282\": \"INVALID_OPERATION\",\n \"1285\": \"OUT_OF_MEMORY\",\n \"1286\": \"INVALID_FRAMEBUFFER_OPERATION\",\n \"37442\": \"CONTEXT_LOST_WEBGL\"\n};\n\nlet webglAvailability: boolean | null = null;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet MAX_TEXTURE_SIZE_FOR_TEST: number | null = null;\n\nexport default class WebGLUtils {\n public static createShader(gl: WebGLRenderingContext, type: number, source: string) {\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (success) {\n return shader;\n }\n\n // eslint-disable-next-line\n console.error(gl.getShaderInfoLog(shader));\n\n return null;\n }\n\n public static createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {\n const program = gl.createProgram()!;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (success) {\n return program;\n }\n\n gl.deleteProgram(program);\n return null;\n }\n\n public static initBuffer(gl: WebGLRenderingContext, target: number /* bind point */, data: TypedArray, itemSize: number, attr?: number) {\n const buffer = gl.createBuffer()!;\n\n gl.bindBuffer(target, buffer);\n gl.bufferData(target, data, gl.STATIC_DRAW);\n\n if (buffer) {\n (buffer as any).itemSize = itemSize;\n (buffer as any).numItems = data.length / itemSize;\n }\n\n if (attr !== undefined) {\n gl.enableVertexAttribArray(attr);\n gl.vertexAttribPointer(attr, (buffer as any).itemSize, gl.FLOAT, false, 0, 0);\n }\n\n return buffer;\n }\n\n public static getWebglContext(canvas: HTMLCanvasElement, userContextAttributes?: WebGLContextAttributes) {\n const webglIdentifiers = [\"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n const contextAttributes = {\n ...{\n preserveDrawingBuffer: false,\n antialias: false\n }, ...userContextAttributes\n };\n\n const onWebglcontextcreationerror = e => e.statusMessage;\n\n canvas.addEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(\"webglcontextcreationerror\", onWebglcontextcreationerror);\n\n return context;\n }\n\n public static createTexture(gl: WebGLRenderingContext, textureTarget: number) {\n const texture = gl.createTexture();\n\n gl.bindTexture(textureTarget, texture);\n gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(textureTarget, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.bindTexture(textureTarget, null);\n\n return texture;\n }\n\n /**\n * Returns the webgl availability of the current browser.\n * @method WebGLUtils#isWebGLAvailable\n * @retuen {Boolean} isWebGLAvailable\n */\n public static isWebGLAvailable(): boolean {\n if (webglAvailability === null) {\n const canvas = document.createElement(\"canvas\");\n const webglContext = WebGLUtils.getWebglContext(canvas);\n\n webglAvailability = !!webglContext;\n\n // webglContext Resource forced collection\n if (webglContext) {\n const loseContextExtension = webglContext.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n return !!webglAvailability;\n }\n\n /**\n * Returns whether webgl is stable in the current browser.\n * @method WebGLUtils#isStableWebGL\n * @retuen {Boolean} isStableWebGL\n */\n public static isStableWebGL() {\n const agentInfo = agent();\n let isStableWebgl = true;\n\n if (agentInfo.os.name === \"android\") {\n const version = parseFloat(agentInfo.os.version);\n\n if (version <= 4.3 && version >= 1) {\n isStableWebgl = false;\n } else if (version === 4.4) {\n if (agentInfo.browser.name !== \"chrome\") {\n isStableWebgl = false;\n }\n }\n }\n return isStableWebgl;\n }\n\n public static getErrorNameFromWebGLErrorCode(code: number | string) {\n if (!(code in WEBGL_ERROR_CODE)) {\n return \"UNKNOWN_ERROR\";\n }\n\n return WEBGL_ERROR_CODE[code];\n }\n\n\n /**\n * This function is wrapper for texImage2D to handle exceptions on texImage2D.\n * Purpose is to prevent service from being stopped by script error.\n */\n public static texImage2D(gl: WebGLRenderingContext, target: number, pixels: TexImageSource) {\n try {\n gl.texImage2D(target, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\n } catch (error) {\n /* eslint-disable no-console */\n console.error(\"WebGLUtils.texImage2D error:\", error);\n /* eslint-enable no-console */\n }\n }\n\n public static getMaxTextureSize(gl: WebGLRenderingContext) {\n // WARN: MAX_TEXTURE_SIZE_FOR_TEST is used for test\n return MAX_TEXTURE_SIZE_FOR_TEST || gl.getParameter(gl.MAX_TEXTURE_SIZE);\n }\n}\n\n/**\n * This function should not be used in service code. It's provided only for test purpose.\n * It should be set to null or 0 when test is done.\n * @param {Number} size\n */\nconst setMaxTextureSizeForTestOnlyPurpose = (size: number) => {\n MAX_TEXTURE_SIZE_FOR_TEST = size;\n};\n\nexport {\n setMaxTextureSizeForTestOnlyPurpose\n};\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport agent from \"@egjs/agent\";\nimport { mat4 } from \"gl-matrix\";\n\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nconst agentInfo = agent();\nconst isIE11 = agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11;\n\nconst EVENTS: {\n ERROR: \"error\";\n} = {\n ERROR: \"error\"\n};\n\n/**\n *\n * Extends Component for firing errors occurs internally.\n */\nabstract class Renderer extends Component<{\n [EVENTS.ERROR]: {\n message: string;\n };\n}> {\n public static EVENTS = EVENTS;\n\n private _forceDimension: { width: number; height: number } | null;\n private _pixelCanvas: HTMLCanvasElement | null;\n private _pixelContext: CanvasRenderingContext2D | null;\n\n public constructor() {\n super();\n\n this._forceDimension = null;\n this._pixelCanvas = null;\n this._pixelContext = null;\n }\n\n public abstract getVertexPositionData(): number[];\n public abstract getIndexData(): number[];\n public abstract getTextureCoordData(textureData: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }): number[];\n\n public abstract getVertexShaderSource(): string;\n public abstract getFragmentShaderSource(): string;\n public abstract bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n public abstract updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig?: CubemapConfig): void;\n\n public render({ gl, shaderProgram, indexBuffer, mvMatrix, pMatrix }: {\n gl: WebGLRenderingContext;\n shaderProgram: WebGLProgram;\n indexBuffer: WebGLBuffer;\n mvMatrix: mat4;\n pMatrix: mat4;\n }) {\n gl.uniformMatrix4fv((shaderProgram as any).pMatrixUniform, false, pMatrix);\n gl.uniformMatrix4fv((shaderProgram as any).mvMatrixUniform, false, mvMatrix);\n\n if (indexBuffer) {\n gl.drawElements(gl.TRIANGLES, (indexBuffer as any).numItems, gl.UNSIGNED_SHORT, 0);\n }\n }\n\n // Define interface for Renderers\n /**\n * Following MUST BE DEFINED on Child of Renderer\n *\n * DATA\n *\n * - getVertexPositionData\n * - getIndexData\n * - getTextureCoordData\n *\n * SOURCE\n *\n * - getVertexShaderSource\n * - getFragmentShaderSource\n *\n * TEXTURE\n *\n * - bindTexture\n */\n public getDimension(pixelSource: HTMLImageElement | HTMLVideoElement) {\n const width = (pixelSource as HTMLImageElement).naturalWidth\n || (pixelSource as HTMLVideoElement).videoWidth;\n const height = (pixelSource as HTMLImageElement).naturalHeight\n || (pixelSource as HTMLVideoElement).videoHeight;\n\n return { width, height };\n }\n\n /**\n * Update data used by shader\n */\n public updateShaderData(param) { // eslint-disable-line @typescript-eslint/no-unused-vars\n /*\n * Update following data in implementation layer.\n * If the data is not changed, it does not need to implement this function.\n *\n * - _VERTEX_POSITION_DATA\n * - _TEXTURE_COORD_DATA\n * - _INDEX_DATA\n */\n }\n\n /**\n *\n * @param {HTMLImageElement | HTMLVideoElement} image\n * @param {Object = {width, height}} forceDimension Forced dimension to resize\n */\n protected _initPixelSource(image: HTMLImageElement | HTMLVideoElement, forceDimension: Renderer[\"_forceDimension\"] = null) {\n const isIE11Video = isIE11 && (image instanceof HTMLVideoElement);\n\n if (isIE11Video || forceDimension) {\n const {width, height} = forceDimension || this.getDimension(image);\n\n this._pixelCanvas = document.createElement(\"canvas\");\n this._pixelCanvas.width = width;\n this._pixelCanvas.height = height;\n this._pixelContext = this._pixelCanvas.getContext(\"2d\");\n }\n this._forceDimension = forceDimension;\n }\n\n protected _getPixelSource(image: HTMLImageElement | HTMLVideoElement) {\n if (!this._pixelCanvas) {\n return image;\n }\n\n /**\n * IE11 && Video\n * or\n * Dimension is forced (Image is larger than texture size.)\n */\n const contentDimension = this.getDimension(image);\n const textureDimension = this._forceDimension || contentDimension;\n\n if (this._pixelCanvas.width !== textureDimension.width) {\n this._pixelCanvas.width = textureDimension.width;\n }\n\n if (this._pixelCanvas.height !== textureDimension.height) {\n this._pixelCanvas.height = textureDimension.height;\n }\n\n if (this._forceDimension) {\n this._pixelContext!.drawImage(image,\n 0, 0, contentDimension.width, contentDimension.height,\n 0, 0, textureDimension.width, textureDimension.height);\n } else {\n this._pixelContext!.drawImage(image, 0, 0);\n }\n\n return this._pixelCanvas;\n }\n\n protected _extractTileConfig(imageConfig: CubemapConfig) {\n let tileConfig: TileConfig[] =\n Array.isArray(imageConfig.tileConfig) ?\n imageConfig.tileConfig : Array(...Array(6)).map(() => imageConfig.tileConfig) as TileConfig[];\n\n tileConfig = tileConfig.map(\n config => ({\n ...{\n flipHorizontal: false,\n rotation: 0\n }, ...config\n })\n );\n\n return tileConfig;\n }\n\n protected _triggerError(error) {\n /* eslint-disable no-console */\n console.error(\"Renderer Error:\", error);\n /* eslint-enable no-console */\n\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n message: typeof error === \"string\" ? error : error.message\n }));\n }\n}\n\nexport default Renderer;\n","import agent from \"@egjs/agent\";\n\nimport WebGLUtils from \"../WebGLUtils\";\nimport { util as mathUtil } from \"../../utils/math-util\";\nimport { CubemapConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nclass CubeRenderer extends Renderer {\n public static extractOrder(imageConfig: CubemapConfig) {\n return imageConfig.order || \"RLUDBF\";\n }\n\n private static _VERTEX_POSITION_DATA: number[] | null = null;\n private static _INDEX_DATA: number[] | null = null;\n\n public getVertexPositionData() {\n CubeRenderer._VERTEX_POSITION_DATA =\n CubeRenderer._VERTEX_POSITION_DATA !== null ? CubeRenderer._VERTEX_POSITION_DATA : [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // top\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // bottom\n 1, -1, -1,\n -1, -1, -1,\n -1, -1, 1,\n 1, -1, 1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n return CubeRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n if (CubeRenderer._INDEX_DATA) {\n return CubeRenderer._INDEX_DATA;\n }\n\n const indexData: number[] = [];\n const vertexPositionData = this.getVertexPositionData();\n\n for (let i = 0; i < (vertexPositionData.length / 3); i += 4) {\n indexData.push(\n i,\n i + 2,\n i + 1,\n i,\n i + 3,\n i + 2\n );\n }\n\n CubeRenderer._INDEX_DATA = indexData;\n return indexData;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n const vertexOrder = \"BFUDRL\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const base = this.getVertexPositionData();\n const tileConfig = this._extractTileConfig(imageConfig);\n const elemSize = 3;\n const vertexPerTile = 4;\n const { trim } = imageConfig;\n\n const texCoords = vertexOrder.split(\"\")\n .map(face => tileConfig[order.indexOf(face)])\n .map((config, i) => {\n const rotation = Math.floor(config.rotation / 90);\n const ordermap = config.flipHorizontal ? [0, 1, 2, 3] : [1, 0, 3, 2];\n\n for (let r = 0; r < Math.abs(rotation); r++) {\n if ((config.flipHorizontal && rotation > 0) ||\n (!config.flipHorizontal && rotation < 0)) {\n ordermap.push(ordermap.shift()!);\n } else {\n ordermap.unshift(ordermap.pop()!);\n }\n }\n\n const elemPerTile = elemSize * vertexPerTile;\n const tileVertex = base.slice(i * elemPerTile, i * elemPerTile + elemPerTile);\n const tileTemp: number[][] = [];\n\n for (let j = 0; j < vertexPerTile; j++) {\n tileTemp[ordermap[j]] = tileVertex.splice(0, elemSize);\n }\n return tileTemp;\n })\n .map(coord => this._shrinkCoord({ image, faceCoords: coord, trim }))\n .reduce((acc: number[], val: number[][]) => [\n ...acc,\n ...val.reduce((coords, coord) => [...coords, ...coord], [])\n ], []);\n\n return texCoords;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec3 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n vVertexDirectionVector = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nuniform samplerCube uSampler;\nvarying highp vec3 vVertexDirectionVector;\nvoid main(void) {\n gl_FragColor = textureCube(uSampler, vVertexDirectionVector);\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n const baseOrder = \"RLUDBF\";\n const order = CubeRenderer.extractOrder(imageConfig);\n const orderMap = {};\n\n order.split(\"\").forEach((v, i) => {\n orderMap[v] = i;\n });\n\n try {\n if (image instanceof Array) {\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, image[tileIdx]);\n }\n } else {\n const maxCubeMapTextureSize = this.getMaxCubeMapTextureSize(gl, image);\n\n for (let surfaceIdx = 0; surfaceIdx < 6; surfaceIdx++) {\n const tileIdx = orderMap[baseOrder[surfaceIdx]];\n const tile = this.extractTileFromImage(\n image, tileIdx, maxCubeMapTextureSize\n );\n\n WebGLUtils.texImage2D(gl, gl.TEXTURE_CUBE_MAP_POSITIVE_X + surfaceIdx, tile);\n }\n }\n } catch (e) {\n this._triggerError(e);\n }\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement, imageConfig: CubemapConfig) {\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n this.updateTexture(gl, image, imageConfig);\n }\n\n public getSourceTileSize(image: HTMLImageElement | HTMLVideoElement) {\n const {width, height} = this.getDimension(image);\n const aspectRatio = width / height;\n let inputTextureSize;\n\n if (aspectRatio === 1 / 6) {\n inputTextureSize = width;\n } else if (aspectRatio === 6) {\n inputTextureSize = height;\n } else if (aspectRatio === 2 / 3) {\n inputTextureSize = width / 2;\n } else {\n inputTextureSize = width / 3;\n }\n return inputTextureSize;\n }\n\n public extractTileFromImage(image: HTMLImageElement | HTMLVideoElement, tileIdx: number, outputTextureSize: number) {\n const {width} = this.getDimension(image);\n const inputTextureSize = this.getSourceTileSize(image);\n\n const canvas = document.createElement(\"canvas\");\n\n canvas.width = outputTextureSize;\n canvas.height = outputTextureSize;\n const context = canvas.getContext(\"2d\");\n const tilePerRow = width / inputTextureSize;\n\n const x = inputTextureSize * tileIdx % (inputTextureSize * tilePerRow);\n const y = Math.floor(tileIdx / tilePerRow) * (inputTextureSize);\n\n context!.drawImage(\n image, x, y,\n inputTextureSize, inputTextureSize, 0, 0, outputTextureSize, outputTextureSize\n );\n return canvas;\n }\n\n public getMaxCubeMapTextureSize(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n const agentInfo = agent();\n const maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);\n let imageWidth = this.getSourceTileSize(image);\n\n if (agentInfo.browser.name === \"ie\" && agentInfo.browser.majorVersion === 11) {\n if (!mathUtil.isPowerOfTwo(imageWidth)) {\n for (let i = 1; i < maxCubeMapTextureSize; i *= 2) {\n if (i < imageWidth) {\n continue;\n } else {\n imageWidth = i;\n break;\n }\n }\n }\n }\n if (agentInfo.os.name === \"ios\") {\n const majorVersion = agentInfo.os.majorVersion;\n\n // ios 9 의 경우 텍스쳐 최대사이즈는 1024 이다.\n if (majorVersion === 9) {\n imageWidth = 1024;\n }\n // ios 8 의 경우 텍스쳐 최대사이즈는 512 이다.\n if (majorVersion === 8) {\n imageWidth = 512;\n }\n }\n // maxCubeMapTextureSize 보다는 작고, imageWidth 보다 큰 2의 승수 중 가장 작은 수\n return Math.min(maxCubeMapTextureSize, imageWidth);\n }\n\n private _shrinkCoord(coordData: {\n image: HTMLImageElement | HTMLVideoElement;\n faceCoords: number[][];\n trim: number;\n }) {\n const { image, faceCoords, trim } = coordData;\n\n const inputTextureSize = Array.isArray(image)\n ? this.getDimension(image[0]).width\n : this.getSourceTileSize(image);\n\n // Shrink by \"trim\" px\n const SHRINK_MULTIPLIER = 1 - trim * (2 / inputTextureSize);\n\n const axisMultipliers = [0, 1, 2].map(axisIndex => {\n const axisDir = mathUtil.sign(faceCoords[0][axisIndex]);\n const notSameDir = faceCoords.some(coord => mathUtil.sign(coord[axisIndex]) !== axisDir);\n\n return notSameDir;\n }).map(notSameDir => notSameDir ? SHRINK_MULTIPLIER : 1);\n\n return faceCoords.map(coords => coords.map((coord, axisIndex) => coord * axisMultipliers[axisIndex]));\n }\n}\n\nexport default CubeRenderer;\n","\nimport WebGLUtils from \"../WebGLUtils\";\nimport { CubemapConfig, TileConfig } from \"../../types/internal\";\n\nimport Renderer from \"./Renderer\";\n\nexport default class CubeStripRenderer extends Renderer {\n private _vertices: number[];\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\n#define PI 3.14159265359\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nuniform bool uIsEAC;\nconst vec2 OPERATE_COORDS_RANGE = vec2(-1.0, 1.0);\nconst vec2 TEXTURE_COORDS_RANGE = vec2(0.0, 1.0);\n// vector type is used for initializing values instead of array.\nconst vec4 TEXTURE_DIVISION_X = vec4(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);\nconst vec3 TEXTURE_DIVISION_Y = vec3(0.0, 1.0 / 2.0, 1.0);\nconst float EAC_CONST = 2.0 / PI;\nfloat scale(vec2 domainRange, vec2 targetRange, float val) {\n float unit = 1.0 / (domainRange[1] - domainRange[0]);\n return targetRange[0] + (targetRange[1] - targetRange[0]) * (val - domainRange[0]) * unit;\n}\nvoid main(void) {\n float transformedCoordX;\n float transformedCoordY;\n\n if (uIsEAC) {\n vec2 orgTextureRangeX;\n vec2 orgTextureRangeY;\n\n // Apply EAC transform\n if (vTextureCoord.s >= TEXTURE_DIVISION_X[2]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[2], TEXTURE_DIVISION_X[3]);\n } else if (vTextureCoord.s >= TEXTURE_DIVISION_X[1]) {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[1], TEXTURE_DIVISION_X[2]);\n } else {\n orgTextureRangeX = vec2(TEXTURE_DIVISION_X[0], TEXTURE_DIVISION_X[1]);\n }\n\n if (vTextureCoord.t >= TEXTURE_DIVISION_Y[1]) {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[1], TEXTURE_DIVISION_Y[2]);\n } else {\n orgTextureRangeY = vec2(TEXTURE_DIVISION_Y[0], TEXTURE_DIVISION_Y[1]);\n }\n\n // scaling coors by the coordinates following the range from -1.0 to 1.0.\n float px = scale(orgTextureRangeX, OPERATE_COORDS_RANGE, vTextureCoord.s);\n float py = scale(orgTextureRangeY, OPERATE_COORDS_RANGE, vTextureCoord.t);\n\n float qu = EAC_CONST * atan(px) + 0.5;\n float qv = EAC_CONST * atan(py) + 0.5;\n\n // re-scaling coors by original coordinates ranges\n transformedCoordX = scale(TEXTURE_COORDS_RANGE, orgTextureRangeX, qu);\n transformedCoordY = scale(TEXTURE_COORDS_RANGE, orgTextureRangeY, qv);\n } else {\n // normal cubemap\n transformedCoordX = vTextureCoord.s;\n transformedCoordY = vTextureCoord.t;\n }\n\n gl_FragColor = texture2D(uSampler, vec2(transformedCoordX, transformedCoordY));\n}`;\n }\n\n public getVertexPositionData() {\n if (!this._vertices) {\n this._vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n }\n\n return this._vertices;\n }\n\n public getIndexData() {\n // TODO: 한번만 계산하도록 수정하기\n const indices = (() => {\n const indexData: number[] = [];\n\n for (let i = 0; i < (this._vertices.length / 3); i += 4) {\n indexData.push(\n i,\n i + 1,\n i + 2,\n i,\n i + 2,\n i + 3\n );\n }\n return indexData;\n })();\n\n return indices;\n }\n\n public getTextureCoordData({ image, imageConfig }: {\n image: HTMLImageElement | HTMLVideoElement;\n imageConfig: CubemapConfig;\n }) {\n // TODO: make it cols, rows as config.\n const cols = 3;\n const rows = 2;\n\n const textureSize = this.getDimension(image);\n const { trim } = imageConfig;\n\n const order = imageConfig.order || \"RLUDFB\";\n let coords: number[][] = [];\n\n // 텍스쳐의 좌표는 윗쪽이 큰 값을 가지므로 row 는 역순으로 넣는다.\n for (let r = rows - 1; r >= 0; r--) {\n for (let c = 0; c < cols; c++) {\n const coord = [\n c / cols, r / rows,\n (c + 1) / cols, r / rows,\n (c + 1) / cols, (r + 1) / rows,\n c / cols, (r + 1) / rows\n ];\n\n coords.push(coord);\n }\n }\n\n const tileConfigs = this._extractTileConfig(imageConfig);\n\n // Transform Coord By Flip & Rotation\n coords = coords\n // shrink coord to avoid pixel bleeding\n .map(coord => this._shrinkCoord(coord, textureSize, trim))\n .map((coord, i) => this._transformCoord(coord, tileConfigs[i]));\n\n // vertices 에서 지정된 순서대로 그대로 그리기 위해 vertex 의 순서를 BFUDRL 로 재배치\n return \"BFUDRL\".split(\"\")\n .map(face => order.indexOf(face))\n .map(index => coords[index])\n .reduce((acc, val) => acc.concat(val), []);\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device limit(${maxSize}))`);\n return;\n }\n\n // Pixel Source for IE11 & Video\n this._initPixelSource(image);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n private _transformCoord(coord: number[], tileConfig: TileConfig) {\n let newCoord = coord.slice();\n\n if (tileConfig.flipHorizontal) {\n newCoord = this._flipHorizontalCoord(newCoord);\n }\n\n if (tileConfig.rotation) {\n newCoord = this._rotateCoord(newCoord, tileConfig.rotation);\n }\n\n return newCoord;\n }\n\n private _shrinkCoord(coord: number[], textureSize: { width: number; height: number }, trim: number) {\n const { width, height } = textureSize;\n\n // Shrink by \"trim\" px\n const SHRINK_Y = trim * (1 / height);\n const SHRINK_X = trim * (1 / width);\n\n return [\n coord[0] + SHRINK_X, coord[1] + SHRINK_Y,\n coord[2] - SHRINK_X, coord[3] + SHRINK_Y,\n coord[4] - SHRINK_X, coord[5] - SHRINK_Y,\n coord[6] + SHRINK_X, coord[7] - SHRINK_Y\n ];\n }\n\n private _rotateCoord(coord: number[], rotationAngle: number) {\n const SIZE = 2; // coord means x,y coordinates. Two values(x, y) makes a one coord.\n const shiftCount = Math.floor(rotationAngle / 90) % 4;\n\n if (shiftCount === 0) {\n return coord;\n }\n\n let moved;\n let rotatedCoord: number[] = [];\n\n if (shiftCount > 0) {\n moved = coord.splice(0, shiftCount * SIZE);\n rotatedCoord = coord.concat(moved);\n } else {\n moved = coord.splice((4 + shiftCount) * SIZE, -shiftCount * SIZE);\n rotatedCoord = moved.concat(coord);\n }\n\n return rotatedCoord;\n }\n\n private _flipHorizontalCoord(coord: number[]) {\n return [\n coord[2], coord[3],\n coord[0], coord[1],\n coord[6], coord[7],\n coord[4], coord[5]\n ];\n }\n}\n","import { glMatrix } from \"gl-matrix\";\n\nimport WebGLUtils from \"../WebGLUtils\";\n\nimport Renderer from \"./Renderer\";\n\n// const latitudeBands = 60;\nconst MIN_ASPECT_RATIO_FOR_FULL_PANORAMA = 6;\nconst longitudeBands = 60;\n\nconst textureCoordData: number[] = [];\nconst vertexPositionData: number[] = [];\nconst indexData: number[] = [];\n\nclass CylinderRenderer extends Renderer {\n private static _VERTEX_POSITION_DATA = vertexPositionData;\n private static _TEXTURE_COORD_DATA = textureCoordData;\n private static _INDEX_DATA = indexData;\n\n public getVertexPositionData() {\n return CylinderRenderer._VERTEX_POSITION_DATA;\n }\n\n public getIndexData() {\n return CylinderRenderer._INDEX_DATA;\n }\n\n public getTextureCoordData() {\n return CylinderRenderer._TEXTURE_COORD_DATA;\n }\n\n public getVertexShaderSource() {\n return `\nattribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform mat4 uMVMatrix;\nuniform mat4 uPMatrix;\nvarying highp vec2 vTextureCoord;\nvoid main(void) {\n vTextureCoord = aTextureCoord;\n gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n}`;\n }\n\n public getFragmentShaderSource() {\n return `\nprecision highp float;\nvarying highp vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void) {\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}`;\n }\n\n public updateTexture(gl: WebGLRenderingContext, image: HTMLImageElement | HTMLVideoElement) {\n WebGLUtils.texImage2D(gl, gl.TEXTURE_2D, this._getPixelSource(image));\n }\n\n public bindTexture(gl: WebGLRenderingContext, texture: WebGLTexture, image: HTMLImageElement | HTMLVideoElement) {\n // Make sure image isn't too big\n const {width, height} = this.getDimension(image);\n const size = Math.max(width, height);\n const maxSize = WebGLUtils.getMaxTextureSize(gl);\n let resizeDimension: { width: number; height: number } | undefined;\n\n if (size > maxSize) {\n this._triggerError(`Image width(${width}) exceeds device texture limit(${maxSize}))`);\n\n // Request resizing texture.\n /**\n * TODO: Is it need to apply on another projection type?\n */\n resizeDimension = width > height ?\n {width: maxSize, height: maxSize * height / width} :\n {width: maxSize * width / height, height: maxSize};\n }\n\n // Pixel Source for IE11 & Video or resizing needed\n this._initPixelSource(image, resizeDimension);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n\n this.updateTexture(gl, image);\n }\n\n public updateShaderData({ imageAspectRatio = MIN_ASPECT_RATIO_FOR_FULL_PANORAMA }) {\n let lngIdx: number;\n let cylinderMaxRadian: number;\n let halfCylinderY: number;\n let rotated: boolean;\n let aspectRatio: number;\n\n // Exception case: orientation is rotated.\n if (imageAspectRatio < 1) {\n /**\n * If rotated is true, we assume that image is rotated counter clockwise.\n * TODO: If there's other rotation, it is need to implement by each rotation.\n */\n rotated = true;\n aspectRatio = 1 / imageAspectRatio;\n } else {\n rotated = false;\n aspectRatio = imageAspectRatio;\n }\n\n if (aspectRatio >= MIN_ASPECT_RATIO_FOR_FULL_PANORAMA) {\n const fov = 360 / aspectRatio;\n\n cylinderMaxRadian = 2 * Math.PI; // 360 deg\n halfCylinderY = Math.tan(glMatrix.toRadian(fov / 2));\n } else {\n cylinderMaxRadian = aspectRatio;\n halfCylinderY = 0.5; // Range of cylinder is [-0.5, 0.5] to make height to 1.\n }\n\n // initialize shader data before update\n textureCoordData.length = 0;\n vertexPositionData.length = 0;\n indexData.length = 0;\n\n const CYLIDER_Y = [-halfCylinderY, halfCylinderY];\n const startAngleForCenterAlign = Math.PI / 2 + (2 * Math.PI - cylinderMaxRadian) / 2; // Math.PI / 2 start point when cylinderMaxRadian is 2 phi(360)\n\n // console.log(\"cylinderMaxRadian:\", glMatrix.toDegree(cylinderMaxRadian), \"CYLIDER_Y\", CYLIDER_Y, \"start angle\", glMatrix.toDegree(startAngleForCenterAlign));\n for (let yIdx = 0, yLength = CYLIDER_Y.length; yIdx < yLength/* bottom & top */; yIdx++) {\n for (lngIdx = 0; lngIdx <= longitudeBands; lngIdx++) {\n const angle = startAngleForCenterAlign + (lngIdx / longitudeBands * cylinderMaxRadian);\n const x = Math.cos(angle);\n const y = CYLIDER_Y[yIdx];\n const z = Math.sin(angle);\n let u: number;\n let v: number;\n\n if (rotated) {\n // Rotated 90 degree (counter clock wise)\n u = 1 - yIdx; // yLength - yIdx;\n v = lngIdx / longitudeBands;\n } else {\n // \t// Normal case (Not rotated)\n u = lngIdx / longitudeBands;\n v = yIdx;\n }\n\n textureCoordData.push(u, v);\n vertexPositionData.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < longitudeBands) {\n const a = lngIdx;\n const b = a + longitudeBands + 1;\n\n indexData.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n }\n}\n\nexport default CylinderRenderer;\n","import Promise from \"promise-polyfill\";\nimport { mat4 } from \"gl-matrix\";\n\nconst VR_DISPLAY_PRESENT_CHANGE = \"vrdisplaypresentchange\";\nconst DEFAULT_LEFT_BOUNDS = [0, 0, 0.5, 1];\nconst DEFAULT_RIGHT_BOUNDS = [0.5, 0, 0.5, 1];\nconst EYES = {\n LEFT: \"left\",\n RIGHT: \"right\"\n} as const;\n\nclass VRManager {\n private _vrDisplay: VRDisplay | null;\n private _frameData: VRFrameData;\n private _yawOffset: number;\n private _leftBounds: number[];\n private _rightBounds: number[];\n\n public constructor() {\n this._frameData = new window.VRFrameData();\n this._clear();\n }\n\n public get context() { return this._vrDisplay; }\n\n public destroy = () => {\n const vrDisplay = this._vrDisplay;\n\n this.removeEndCallback(this.destroy);\n\n if (vrDisplay && vrDisplay.isPresenting) {\n void vrDisplay.exitPresent();\n }\n\n this._clear();\n };\n\n public canRender() {\n return Boolean(this._vrDisplay);\n }\n\n public beforeRender(gl: WebGLRenderingContext) {\n // Render to the default backbuffer\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public afterRender() {\n this._vrDisplay!.submitFrame();\n }\n\n public getEyeParams(gl: WebGLRenderingContext) {\n const display = this._vrDisplay!;\n const halfWidth = gl.drawingBufferWidth * 0.5;\n const height = gl.drawingBufferHeight;\n const frameData = this._frameData;\n\n display.getFrameData(frameData);\n\n const leftMVMatrix = frameData.leftViewMatrix;\n const rightMVMatrix = frameData.rightViewMatrix;\n\n mat4.rotateY(leftMVMatrix, leftMVMatrix, this._yawOffset);\n mat4.rotateY(rightMVMatrix, rightMVMatrix, this._yawOffset);\n\n return [\n {\n viewport: [0, 0, halfWidth, height],\n mvMatrix: leftMVMatrix,\n pMatrix: frameData.leftProjectionMatrix\n },\n {\n viewport: [halfWidth, 0, halfWidth, height],\n mvMatrix: rightMVMatrix,\n pMatrix: frameData.rightProjectionMatrix\n }\n ];\n }\n\n public isPresenting() {\n return Boolean(this._vrDisplay && this._vrDisplay.isPresenting);\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n window.addEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n window.removeEventListener(VR_DISPLAY_PRESENT_CHANGE, callback);\n }\n\n public requestPresent(canvas: HTMLCanvasElement) {\n return navigator.getVRDisplays().then(displays => {\n const vrDisplay = displays.length && displays[0];\n\n if (!vrDisplay) {\n return Promise.reject(new Error(\"No displays available.\"));\n }\n if (!vrDisplay.capabilities.canPresent) {\n return Promise.reject(new Error(\"Display lacking capability to present.\"));\n }\n\n return vrDisplay.requestPresent([{source: canvas}]).then(() => {\n const leftEye = vrDisplay.getEyeParameters(EYES.LEFT);\n const rightEye = vrDisplay.getEyeParameters(EYES.RIGHT);\n\n canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2;\n canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);\n\n this._setDisplay(vrDisplay);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setDisplay(vrDisplay: VRDisplay) {\n this._vrDisplay = vrDisplay;\n\n const layers = vrDisplay.getLayers();\n\n if (layers.length) {\n const layer = layers[0];\n\n this._leftBounds = layer.leftBounds as number[];\n this._rightBounds = layer.rightBounds as number[];\n }\n\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._vrDisplay = null;\n this._leftBounds = DEFAULT_LEFT_BOUNDS;\n this._rightBounds = DEFAULT_RIGHT_BOUNDS;\n this._yawOffset = 0;\n }\n}\n\nexport default VRManager;\n","import { mat4, glMatrix } from \"gl-matrix\";\nimport { XRFrame, XRLayer, XRReferenceSpace, XRSession, XRSessionInit } from \"webxr\";\n\nimport { IS_SAFARI_ON_DESKTOP } from \"../../utils/browser\";\nimport { merge } from \"../../utils/utils\";\n\nconst XR_REFERENCE_SPACE = \"local\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\nclass XRManager {\n private _xrSession: XRSession | null;\n private _xrLayer: XRLayer | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n private _yawOffset: number;\n private _presenting: boolean;\n\n public constructor(options: XRSessionOptions = {}) {\n this._clear();\n this._options = options;\n }\n\n public get context() { return this._xrSession; }\n\n public destroy = () => {\n const xrSession = this._xrSession;\n\n this.removeEndCallback(this.destroy);\n\n if (xrSession) {\n // Capture to avoid errors\n xrSession.end().then(() => void 0, () => void 0);\n }\n this._clear();\n };\n\n public canRender(frame: XRFrame) {\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n return Boolean(pose);\n }\n\n public beforeRender(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer!.framebuffer);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n public afterRender() {}\n\n public getEyeParams(gl: WebGLRenderingContext, frame: XRFrame) {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) {\n // Can't render\n return null;\n }\n\n const glLayer = session.renderState.baseLayer;\n\n return pose.views.map(view => {\n const viewport = glLayer!.getViewport(view);\n const mvMatrix = view.transform.inverse.matrix;\n\n if (IS_SAFARI_ON_DESKTOP) {\n mat4.rotateX(mvMatrix, mvMatrix, glMatrix.toRadian(180));\n }\n\n mat4.rotateY(mvMatrix, mvMatrix, this._yawOffset);\n\n return {\n viewport: [viewport.x, viewport.y, viewport.width, viewport.height],\n mvMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n public isPresenting() {\n return this._presenting;\n }\n\n public addEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.addEventListener(\"end\", callback);\n }\n\n public removeEndCallback(callback: (evt?: Event) => any) {\n this._xrSession?.removeEventListener(\"end\", callback);\n }\n\n public async requestPresent(canvas: HTMLCanvasElement, gl: WebGLRenderingContext) {\n const options = merge({\n requiredFeatures: [XR_REFERENCE_SPACE]\n }, this._options);\n\n const attributes = gl.getContextAttributes();\n if (attributes && (attributes as any).xrCompatible !== true) {\n await (gl as any).makeXRCompatible();\n }\n\n return (navigator as any).xr.requestSession(\"immersive-vr\", options).then(session => {\n const xrLayer = new (window as any).XRWebGLLayer(session, gl);\n\n session.updateRenderState({baseLayer: xrLayer});\n return session.requestReferenceSpace(XR_REFERENCE_SPACE)\n .then(refSpace => {\n this._setSession(session, xrLayer, refSpace);\n });\n });\n }\n\n public setYawOffset(offset: number) {\n this._yawOffset = offset;\n }\n\n private _setSession(session: XRSession, xrLayer: XRLayer, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrLayer = xrLayer;\n this._xrRefSpace = refSpace;\n this._presenting = true;\n this.addEndCallback(this.destroy);\n }\n\n private _clear() {\n this._xrSession = null;\n this._xrLayer = null;\n this._xrRefSpace = null;\n this._presenting = false;\n this._yawOffset = 0;\n this._options = {};\n }\n}\n\nexport default XRManager;\n","import { IS_SAFARI_ON_DESKTOP } from \"../utils/browser\";\n\nclass WebGLAnimator {\n private _callback: ((...args: any[]) => any) | null;\n private _context: any;\n private _rafId: number;\n private _rafTimer: number;\n\n public constructor() {\n this._callback = null;\n this._context = window;\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public setCallback(callback: (...args: any[]) => any) {\n this._callback = callback;\n }\n\n public setContext(context: any) {\n this._context = context;\n }\n\n public start() {\n const context = this._context;\n const callback = this._callback;\n\n // No context / callback set\n if (!context || !callback) return;\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n if (IS_SAFARI_ON_DESKTOP) {\n this._rafId = context.requestAnimationFrame(this._onLoopNextTick);\n } else {\n this._rafId = context.requestAnimationFrame(this._onLoop);\n }\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n /**\n * There can be more than 1 argument when we use XRSession's raf\n */\n private _onLoop = (...args: any[]) => {\n this._callback!(...args);\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n };\n\n /**\n * MacOS X Safari Bug Fix\n * This code guarantees that rendering should be occurred.\n *\n * In MacOS X(10.14.2), Safari (12.0.2)\n * The requestAnimationFrame(RAF) callback is called just after previous RAF callback without term\n * only if requestAnimationFrame is called for next frame while updating frame is delayed (~over 2ms)\n * So browser cannot render the frame and may be freezing.\n */\n private _onLoopNextTick = (...args: any[]) => {\n const before = performance.now();\n\n this._callback!(...args);\n\n const diff = performance.now() - before;\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n this._rafTimer = -1;\n }\n\n /* Use requestAnimationFrame only if current rendering could be possible over 60fps (1000/60) */\n if (diff < 16) {\n this._rafId = this._context.requestAnimationFrame(this._onLoop);\n } else {\n /* Otherwise, Call setTimeout instead of requestAnimationFrame to gaurantee renering should be occurred */\n this._rafTimer = window.setTimeout(this._onLoop, 0);\n }\n };\n}\n\nexport default WebGLAnimator;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport { XRFrame } from \"webxr\";\nimport Promise from \"promise-polyfill\";\nimport { glMatrix, vec3, mat3, mat4, quat } from \"gl-matrix\";\nimport ImReady, { OnReady } from \"@egjs/imready\";\n\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { devicePixelRatio, WEBXR_SUPPORTED } from \"../utils/browserFeature\";\nimport { PROJECTION_TYPE, STEREO_FORMAT } from \"../PanoViewer/consts\";\nimport { IS_IOS } from \"../utils/browser\";\nimport { CubemapConfig, ImageCandidate, ValueOf, VideoCandidate } from \"../types/internal\";\nimport YawPitchControl from \"../YawPitchControl/YawPitchControl\";\nimport { toImageElement, toVideoElement } from \"../utils/utils\";\n\nimport WebGLUtils from \"./WebGLUtils\";\nimport Renderer from \"./renderer/Renderer\";\nimport CubeRenderer from \"./renderer/CubeRenderer\";\nimport CubeStripRenderer from \"./renderer/CubeStripRenderer\";\nimport SphereRenderer from \"./renderer/SphereRenderer\";\nimport CylinderRenderer from \"./renderer/CylinderRenderer\";\nimport VRManager from \"./vr/VRManager\";\nimport XRManager from \"./vr/XRManager\";\nimport WebGLAnimator from \"./WebGLAnimator\";\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ImageType = PROJECTION_TYPE;\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nlet DEVICE_PIXEL_RATIO = devicePixelRatio || 1;\n\n// DEVICE_PIXEL_RATIO 가 2를 초과하는 경우는 리소스 낭비이므로 2로 맞춘다.\nif (DEVICE_PIXEL_RATIO > 2) {\n DEVICE_PIXEL_RATIO = 2;\n}\n\n// define custom events name\n/**\n * TODO: how to manage events/errortype with PanoViewer\n *\n * I think renderer events should be seperated from viewer events although it has same name.\n */\nconst EVENTS: {\n BIND_TEXTURE: \"bindTexture\";\n IMAGE_LOADED: \"imageLoaded\";\n ERROR: \"error\";\n RENDERING_CONTEXT_LOST: \"renderingContextLost\";\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\";\n} = {\n BIND_TEXTURE: \"bindTexture\",\n IMAGE_LOADED: \"imageLoaded\",\n ERROR: \"error\",\n RENDERING_CONTEXT_LOST: \"renderingContextLost\",\n RENDERING_CONTEXT_RESTORE: \"renderingContextRestore\"\n};\n\nconst ERROR_TYPE = {\n INVALID_DEVICE: 10,\n NO_WEBGL: 11,\n FAIL_IMAGE_LOAD: 12,\n RENDERER_ERROR: 13\n};\n\nclass PanoImageRenderer extends Component<{\n [EVENTS.ERROR]: {\n type: number;\n message: string;\n };\n [EVENTS.IMAGE_LOADED]: {\n content: HTMLElement;\n isVideo: boolean;\n projectionType: ValueOf;\n };\n [EVENTS.BIND_TEXTURE]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_LOST]: ComponentEvent;\n [EVENTS.RENDERING_CONTEXT_RESTORE]: ComponentEvent;\n}> {\n public static EVENTS = EVENTS;\n public static ERROR_TYPE = ERROR_TYPE;\n\n public sphericalConfig: {\n initialYaw: number;\n initialPitch: number;\n fieldOfView: number;\n imageType: ValueOf;\n stereoFormat: ValueOf;\n cubemapConfig: Partial;\n };\n\n public fieldOfView: number;\n public width: number;\n public height: number;\n\n public canvas: HTMLCanvasElement;\n public context: WebGLRenderingContext;\n public shaderProgram: WebGLProgram | null;\n public texture: WebGLTexture;\n\n public pMatrix: mat4;\n public mvMatrix: mat4;\n\n public textureCoordBuffer: WebGLBuffer | null = null;\n public vertexBuffer: WebGLBuffer | null = null;\n public indexBuffer: WebGLBuffer | null = null;\n\n private _wrapper: HTMLElement | null;\n private _wrapperOrigStyle: string | null;\n private _lastQuaternion: quat | null;\n private _lastYaw: number | null;\n private _lastPitch: number | null;\n private _lastFieldOfView: number | null;\n private _renderingContextAttributes?: WebGLContextAttributes;\n\n private _renderer: Renderer;\n private _contentLoader: ImReady | null;\n private _image: HTMLImageElement | HTMLImageElement[] | HTMLVideoElement | null;\n private _imageConfig: CubemapConfig | null;\n private _imageType: ValueOf;\n private _imageIsReady: boolean;\n private _isVideo: boolean;\n private _isCubeMap: boolean;\n private _shouldForceDraw: boolean;\n private _keepUpdate: boolean;\n private _hasExternalCanvas: boolean;\n\n private _yawPitchControl: YawPitchControl;\n private _animator: WebGLAnimator;\n private _vr: VRManager | XRManager | null;\n\n public constructor(\n image: ImageCandidate | VideoCandidate,\n width: number,\n height: number,\n isVideo: boolean,\n container: HTMLElement,\n canvasClass: string,\n sphericalConfig: PanoImageRenderer[\"sphericalConfig\"],\n renderingContextAttributes?: WebGLContextAttributes\n ) {\n // Super constructor\n super();\n\n this.sphericalConfig = sphericalConfig;\n this.fieldOfView = sphericalConfig.fieldOfView;\n\n this.width = width;\n this.height = height;\n\n this._lastQuaternion = null;\n this._lastYaw = null;\n this._lastPitch = null;\n this._lastFieldOfView = null;\n\n this.pMatrix = mat4.create();\n this.mvMatrix = mat4.create();\n\n // initialzie pMatrix\n mat4.perspective(this.pMatrix, glMatrix.toRadian(this.fieldOfView), width / height, 0.1, 100);\n\n this.textureCoordBuffer = null;\n this.vertexBuffer = null;\n this.indexBuffer = null;\n\n this.canvas = this._initCanvas(container, canvasClass, width, height);\n\n this._setDefaultCanvasStyle();\n this._wrapper = null; // canvas wrapper\n this._wrapperOrigStyle = null;\n\n this._renderingContextAttributes = renderingContextAttributes;\n this._image = null;\n this._imageConfig = null;\n this._imageIsReady = false;\n this._shouldForceDraw = false;\n this._keepUpdate = false; // Flag to specify 'continuous update' on video even when still.\n\n this._onContentLoad = this._onContentLoad.bind(this);\n this._onContentError = \tthis._onContentError.bind(this);\n\n this._animator = new WebGLAnimator();\n\n // VR/XR manager\n this._vr = null;\n\n if (image) {\n this.setImage({\n image,\n imageType: sphericalConfig.imageType,\n isVideo,\n cubemapConfig: sphericalConfig.cubemapConfig\n });\n }\n }\n\n // FIXME: Please refactor me to have more loose connection to yawpitchcontrol\n public setYawPitchControl(yawPitchControl: YawPitchControl) {\n this._yawPitchControl = yawPitchControl;\n }\n\n public getContent() {\n return this._image;\n }\n\n public setImage({\n image,\n imageType,\n isVideo = false,\n cubemapConfig\n }: {\n image: ImageCandidate | VideoCandidate;\n imageType: PanoImageRenderer[\"_imageType\"];\n isVideo: boolean;\n cubemapConfig: Partial;\n }) {\n this._imageIsReady = false;\n this._isVideo = isVideo;\n this._imageConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only */\n order: (imageType === ImageType.CUBEMAP) ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n },\n ...cubemapConfig\n };\n this._setImageType(imageType);\n\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._contentLoader = new ImReady()\n .on(\"ready\", this._onContentLoad)\n .on(\"error\", this._onContentError);\n\n if (isVideo) {\n this._image = toVideoElement(image as VideoCandidate);\n this._contentLoader.check([this._image]);\n this._keepUpdate = true;\n } else {\n this._image = toImageElement(image as ImageCandidate);\n this._contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n this._keepUpdate = false;\n }\n }\n\n public isImageLoaded() {\n return !!this._image && this._imageIsReady &&\n (!this._isVideo || (this._image as HTMLVideoElement).readyState >= 2 /* HAVE_CURRENT_DATA */);\n }\n\n public bindTexture() {\n return new Promise((res, rej) => {\n const contentLoader = this._contentLoader;\n\n if (!this._image) {\n return rej(\"Image is not defined\");\n }\n\n if (!contentLoader) {\n return rej(\"ImageLoader is not initialized\");\n }\n\n if (contentLoader.isReady()) {\n this._bindTexture();\n res();\n } else {\n contentLoader.check(Array.isArray(this._image) ? this._image : [this._image]);\n contentLoader.once(\"ready\", e => {\n if (e.errorCount > 0) {\n rej(\"Failed to load images.\");\n } else {\n this._bindTexture();\n res();\n }\n });\n }\n });\n }\n\n // 부모 엘리먼트에 canvas 를 붙임\n public attachTo(parentElement) {\n if (!this._hasExternalCanvas) {\n this.detach();\n parentElement.appendChild(this.canvas);\n }\n this._wrapper = parentElement;\n }\n\n public forceContextLoss() {\n if (this.hasRenderingContext()) {\n const loseContextExtension = this.context.getExtension(\"WEBGL_lose_context\");\n\n if (loseContextExtension) {\n loseContextExtension.loseContext();\n }\n }\n }\n\n // 부모 엘리먼트에서 canvas 를 제거\n public detach() {\n if (!this._hasExternalCanvas && this.canvas.parentElement) {\n this.canvas.parentElement.removeChild(this.canvas);\n }\n }\n\n public destroy() {\n if (this._contentLoader) {\n this._contentLoader.destroy();\n }\n\n this._animator.stop();\n this.detach();\n this.forceContextLoss();\n\n this.off();\n\n this.canvas.removeEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n this.canvas.removeEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n }\n\n public hasRenderingContext() {\n const ctx = this.context;\n if (\n !ctx\n || ctx.isContextLost()\n || !ctx.getProgramParameter(this.shaderProgram!, ctx.LINK_STATUS)) {\n return false;\n }\n return true;\n }\n\n public updateFieldOfView(fieldOfView) {\n this.fieldOfView = fieldOfView;\n this._updateViewport();\n }\n\n public updateViewportDimensions(width, height) {\n let viewPortChanged = false;\n\n this.width = width;\n this.height = height;\n\n const w = width * DEVICE_PIXEL_RATIO;\n const h = height * DEVICE_PIXEL_RATIO;\n\n if (w !== this.canvas.width) {\n this.canvas.width = w;\n viewPortChanged = true;\n }\n\n if (h !== this.canvas.height) {\n this.canvas.height = h;\n viewPortChanged = true;\n }\n\n if (!viewPortChanged) {\n return;\n }\n\n this._updateViewport();\n this._shouldForceDraw = true;\n }\n\n public keepUpdate(doUpdate) {\n if (doUpdate && this.isImageLoaded() === false) {\n // Force to draw a frame after image is loaded on render()\n this._shouldForceDraw = true;\n }\n\n this._keepUpdate = doUpdate;\n }\n\n public startRender() {\n this._animator.setCallback(this._render.bind(this));\n this._animator.start();\n }\n\n public stopRender() {\n this._animator.stop();\n }\n\n public renderWithQuaternion(quaternion, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastQuaternion && quat.exactEquals(this._lastQuaternion, quaternion) &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // updatefieldOfView only if fieldOfView is changed.\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n this.mvMatrix = mat4.fromQuat(mat4.create(), quaternion);\n\n this._draw();\n\n this._lastQuaternion = quat.clone(quaternion);\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n public renderWithYawPitch(yaw, pitch, fieldOfView) {\n if (!this.isImageLoaded()) {\n return;\n }\n\n if (this._keepUpdate === false &&\n this._lastYaw !== null && this._lastYaw === yaw &&\n this._lastPitch !== null && this._lastPitch === pitch &&\n this.fieldOfView && this.fieldOfView === fieldOfView &&\n this._shouldForceDraw === false) {\n return;\n }\n\n // fieldOfView 가 존재하면서 기존의 값과 다를 경우에만 업데이트 호출\n if (fieldOfView !== undefined && fieldOfView !== this.fieldOfView) {\n this.updateFieldOfView(fieldOfView);\n }\n\n mat4.identity(this.mvMatrix);\n mat4.rotateX(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(pitch));\n mat4.rotateY(this.mvMatrix, this.mvMatrix, -glMatrix.toRadian(yaw));\n\n this._draw();\n\n this._lastYaw = yaw;\n this._lastPitch = pitch;\n if (this._shouldForceDraw) {\n this._shouldForceDraw = false;\n }\n }\n\n /**\n * Returns projection renderer by each type\n */\n public getProjectionRenderer() {\n return this._renderer;\n }\n\n /**\n * @return Promise\n */\n public enterVR(options) {\n const vr = this._vr;\n\n if (!WEBXR_SUPPORTED && !(navigator as any).getVRDisplays) {\n return Promise.reject(\"VR is not available on this browser.\");\n }\n if (vr && vr.isPresenting()) {\n return Promise.resolve(\"VR already enabled.\");\n }\n\n return this._requestPresent(options);\n }\n\n public exitVR = () => {\n const vr = this._vr;\n const gl = this.context;\n const animator = this._animator;\n\n if (!vr) return;\n\n vr.removeEndCallback(this.exitVR);\n vr.destroy();\n this._vr = null;\n\n // Restore canvas & context on iOS\n if (IS_IOS) {\n this._restoreStyle();\n }\n this.updateViewportDimensions(this.width, this.height);\n this._updateViewport();\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n this._bindBuffers();\n this._shouldForceDraw = true;\n\n animator.stop();\n animator.setContext(window);\n animator.setCallback(this._render.bind(this));\n animator.start();\n };\n\n private _setImageType(imageType) {\n if (!imageType || this._imageType === imageType) {\n return;\n }\n\n this._imageType = imageType;\n this._isCubeMap = imageType === ImageType.CUBEMAP;\n\n if (this._renderer) {\n this._renderer.off();\n }\n\n switch (imageType) {\n case ImageType.CUBEMAP:\n this._renderer = new CubeRenderer();\n break;\n case ImageType.CUBESTRIP:\n this._renderer = new CubeStripRenderer();\n break;\n case ImageType.PANORAMA:\n this._renderer = new CylinderRenderer();\n break;\n case ImageType.STEREOSCOPIC_EQUI:\n this._renderer = new SphereRenderer(this.sphericalConfig.stereoFormat);\n break;\n default:\n this._renderer = new SphereRenderer(STEREO_FORMAT.NONE);\n break;\n }\n\n this._renderer.on(Renderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERER_ERROR,\n message: e.message\n }));\n });\n\n this._initWebGL();\n }\n\n private _initCanvas(container: HTMLElement, canvasClass: string, width: number, height: number) {\n const canvasInContainer = container.querySelector(`.${canvasClass}`);\n const canvas = canvasInContainer || this._createCanvas(canvasClass);\n\n this._hasExternalCanvas = !!canvasInContainer;\n\n canvas.width = width;\n canvas.height = height;\n\n this._onWebglcontextlost = this._onWebglcontextlost.bind(this);\n this._onWebglcontextrestored = this._onWebglcontextrestored.bind(this);\n\n canvas.addEventListener(\"webglcontextlost\", this._onWebglcontextlost);\n canvas.addEventListener(\"webglcontextrestored\", this._onWebglcontextrestored);\n\n return canvas;\n }\n\n private _createCanvas(className: string) {\n const canvas = document.createElement(\"canvas\");\n\n canvas.className = className;\n\n return canvas;\n }\n\n private _setDefaultCanvasStyle() {\n const canvas = this.canvas;\n\n canvas.style.bottom = \"0\";\n canvas.style.left = \"0\";\n canvas.style.right = \"0\";\n canvas.style.top = \"0\";\n canvas.style.margin = \"auto\";\n canvas.style.maxHeight = \"100%\";\n canvas.style.maxWidth = \"100%\";\n canvas.style.outline = \"none\";\n canvas.style.position = \"absolute\";\n }\n\n private _onContentError() {\n this._imageIsReady = false;\n this._image = null;\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_IMAGE_LOAD,\n message: \"failed to load image\"\n }));\n\n return false;\n }\n\n private _triggerContentLoad() {\n this.trigger(new ComponentEvent(EVENTS.IMAGE_LOADED, {\n content: this._image as HTMLElement,\n isVideo: this._isVideo,\n projectionType: this._imageType\n }));\n }\n\n private _onContentLoad(e: OnReady) {\n if (e.errorCount > 0) return;\n\n this._imageIsReady = true;\n\n this._triggerContentLoad();\n }\n\n private _initShaderProgram() {\n const gl = this.context;\n\n if (this.shaderProgram) {\n gl.deleteProgram(this.shaderProgram);\n this.shaderProgram = null;\n }\n\n const renderer = this._renderer;\n\n const vsSource = renderer.getVertexShaderSource();\n const fsSource = renderer.getFragmentShaderSource();\n\n const vertexShader = WebGLUtils.createShader(gl, gl.VERTEX_SHADER, vsSource)!;\n const fragmentShader = WebGLUtils.createShader(gl, gl.FRAGMENT_SHADER, fsSource)!;\n\n const shaderProgram = WebGLUtils.createProgram(gl, vertexShader, fragmentShader);\n\n if (!shaderProgram) {\n throw new Error(`Failed to initialize shaders: ${WebGLUtils.getErrorNameFromWebGLErrorCode(gl.getError())}`);\n }\n\n gl.useProgram(shaderProgram);\n (shaderProgram as any).vertexPositionAttribute = gl.getAttribLocation(shaderProgram, \"aVertexPosition\");\n (shaderProgram as any).pMatrixUniform = gl.getUniformLocation(shaderProgram, \"uPMatrix\");\n (shaderProgram as any).mvMatrixUniform = gl.getUniformLocation(shaderProgram, \"uMVMatrix\");\n (shaderProgram as any).samplerUniform = gl.getUniformLocation(shaderProgram, \"uSampler\");\n (shaderProgram as any).textureCoordAttribute = gl.getAttribLocation(shaderProgram, \"aTextureCoord\");\n (shaderProgram as any).uEye = gl.getUniformLocation(shaderProgram, \"uEye\");\n\n gl.enableVertexAttribArray((shaderProgram as any).vertexPositionAttribute);\n gl.enableVertexAttribArray((shaderProgram as any).textureCoordAttribute);\n\n // clear buffer\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);\n // Use TEXTURE0\n gl.uniform1i((shaderProgram as any).samplerUniform, 0);\n\n this.shaderProgram = shaderProgram;\n }\n\n private _onWebglcontextlost(e) {\n e.preventDefault();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_LOST));\n }\n\n private _onWebglcontextrestored() {\n this._initWebGL();\n this.trigger(new ComponentEvent(EVENTS.RENDERING_CONTEXT_RESTORE));\n }\n\n private _updateViewport() {\n mat4.perspective(\n this.pMatrix,\n glMatrix.toRadian(this.fieldOfView),\n this.canvas.width / this.canvas.height,\n 0.1,\n 100);\n\n this.context.viewport(0, 0, this.context.drawingBufferWidth, this.context.drawingBufferHeight);\n }\n\n private _initWebGL() {\n let gl: WebGLRenderingContext;\n\n // TODO: Following code does need to be executed only if width/height, cubicStrip property is changed.\n try {\n this._initRenderingContext();\n gl = this.context;\n\n this.updateViewportDimensions(this.width, this.height);\n this._initShaderProgram();\n } catch (e) {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n this.destroy();\n console.error(e); // eslint-disable-line no-console\n return;\n }\n // 캔버스를 투명으로 채운다.\n gl.clearColor(0, 0, 0, 0);\n const textureTarget = this._isCubeMap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\n\n if (this.texture) {\n gl.deleteTexture(this.texture);\n }\n\n this.texture = WebGLUtils.createTexture(gl, textureTarget)!;\n\n if (this._imageType === ImageType.CUBESTRIP) {\n // TODO: Apply following options on other projection type.\n gl.enable(gl.CULL_FACE);\n // gl.enable(gl.DEPTH_TEST);\n }\n }\n\n private _initRenderingContext() {\n if (this.hasRenderingContext()) {\n return;\n }\n\n if (!window.WebGLRenderingContext) {\n throw new Error(\"WebGLRenderingContext not available.\");\n }\n\n this.context = WebGLUtils.getWebglContext(this.canvas, this._renderingContextAttributes)!;\n\n if (!this.context) {\n throw new Error(\"Failed to acquire 3D rendering context\");\n }\n }\n\n private _initBuffers() {\n const image = this._image as HTMLImageElement | HTMLVideoElement;\n\n const vertexPositionData = this._renderer.getVertexPositionData();\n const indexData = this._renderer.getIndexData();\n const textureCoordData = this._renderer.getTextureCoordData({\n image,\n imageConfig: this._imageConfig!\n });\n const gl = this.context;\n\n this.vertexBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), 3,\n (this.shaderProgram as any).vertexPositionAttribute);\n\n this.indexBuffer = WebGLUtils.initBuffer(\n gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), 1);\n\n this.textureCoordBuffer = WebGLUtils.initBuffer(\n gl, gl.ARRAY_BUFFER, new Float32Array(textureCoordData), this._isCubeMap ? 3 : 2,\n (this.shaderProgram as any).textureCoordAttribute);\n\n this._bindBuffers();\n }\n\n private _bindTexture() {\n // Detect if it is EAC Format while CUBESTRIP mode.\n // We assume it is EAC if image is not 3/2 ratio.\n if (this._imageType === ImageType.CUBESTRIP) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const isEAC = width && height && width / height !== 1.5 ? 1 : 0;\n\n this.context.uniform1f(this.context.getUniformLocation(this.shaderProgram!, \"uIsEAC\"), isEAC);\n } else if (this._imageType === ImageType.PANORAMA) {\n const { width, height } = this._renderer.getDimension(this._image as HTMLImageElement | HTMLVideoElement);\n const imageAspectRatio = width && height && width / height;\n\n this._renderer.updateShaderData({imageAspectRatio});\n }\n\n // initialize shader buffers after image is loaded.(by updateShaderData)\n // because buffer may be differ by image size.(eg. CylinderRenderer)\n this._initBuffers();\n\n this._renderer.bindTexture(\n this.context,\n this.texture,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n this._shouldForceDraw = true;\n\n this.trigger(new ComponentEvent(EVENTS.BIND_TEXTURE));\n }\n\n private _updateTexture() {\n this._renderer.updateTexture(\n this.context,\n this._image as HTMLImageElement | HTMLVideoElement,\n this._imageConfig!,\n );\n }\n\n private _render() {\n const yawPitchControl = this._yawPitchControl;\n const fov = yawPitchControl.getFov();\n\n if (yawPitchControl.shouldRenderWithQuaternion()) {\n const quaternion = yawPitchControl.getQuaternion();\n\n this.renderWithQuaternion(quaternion, fov);\n } else {\n const yawPitch = yawPitchControl.getYawPitch();\n\n this.renderWithYawPitch(yawPitch.yaw, yawPitch.pitch, fov);\n }\n }\n\n private _renderStereo = (time: number, frame: XRFrame) => {\n const vr = this._vr;\n const gl = this.context;\n\n const eyeParams = vr!.getEyeParams(gl, frame);\n\n if (!eyeParams) return;\n\n vr!.beforeRender(gl, frame);\n\n // Render both eyes\n for (const eyeIndex of [0, 1]) {\n const eyeParam = eyeParams[eyeIndex];\n\n this.mvMatrix = eyeParam.mvMatrix;\n this.pMatrix = eyeParam.pMatrix;\n\n gl.viewport(...eyeParam.viewport as [number, number, number, number]);\n gl.uniform1f((this.shaderProgram as any).uEye, eyeIndex);\n\n this._bindBuffers();\n this._draw();\n }\n\n vr!.afterRender();\n };\n\n private _bindBuffers() {\n const gl = this.context;\n const program = this.shaderProgram;\n\n const vertexBuffer = this.vertexBuffer;\n const textureCoordBuffer = this.textureCoordBuffer;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray((program as any).vertexPositionAttribute);\n gl.vertexAttribPointer(\n (program as any).vertexPositionAttribute, (vertexBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);\n gl.enableVertexAttribArray((program as any).textureCoordAttribute);\n gl.vertexAttribPointer(\n (program as any).textureCoordAttribute, (textureCoordBuffer as any).itemSize, gl.FLOAT, false, 0, 0\n );\n }\n\n private _draw() {\n if (this._isVideo && this._keepUpdate) {\n this._updateTexture();\n }\n\n this._renderer.render({\n gl: this.context,\n shaderProgram: this.shaderProgram!,\n indexBuffer: this.indexBuffer!,\n mvMatrix: this.mvMatrix,\n pMatrix: this.pMatrix\n });\n }\n\n private _requestPresent(options) {\n const gl = this.context;\n const canvas = this.canvas;\n const animator = this._animator;\n\n this._vr = WEBXR_SUPPORTED ?\n new XRManager(options) :\n new VRManager();\n\n const vr = this._vr;\n\n animator.stop();\n return new Promise((resolve, reject) => {\n vr.requestPresent(canvas, gl)\n .then(() => {\n vr.addEndCallback(this.exitVR);\n animator.setContext(vr.context);\n animator.setCallback(this._onFirstVRFrame);\n\n if (IS_IOS) {\n this._setWrapperFullscreen();\n }\n\n this._shouldForceDraw = true;\n animator.start();\n\n resolve(\"success\");\n })\n .catch(e => {\n vr.destroy();\n this._vr = null;\n animator.start();\n\n reject(e);\n });\n });\n }\n\n private _onFirstVRFrame = (time, frame) => {\n const vr = this._vr!;\n const gl = this.context;\n const animator = this._animator;\n\n // If rendering is not ready, wait for next frame\n if (!vr.canRender(frame)) return;\n\n const minusZDir = vec3.fromValues(0, 0, -1);\n const eyeParam = vr.getEyeParams(gl, frame)![0];\n // Extract only rotation\n const mvMatrix = mat3.fromMat4(mat3.create(), eyeParam.mvMatrix);\n const pMatrix = mat3.fromMat4(mat3.create(), eyeParam.pMatrix);\n\n const mvInv = mat3.invert(mat3.create(), mvMatrix);\n const pInv = mat3.invert(mat3.create(), pMatrix);\n const viewDir = vec3.transformMat3(vec3.create(), minusZDir, pInv);\n\n vec3.transformMat3(viewDir, viewDir, mvInv);\n\n const yawOffset = mathUtil.yawOffsetBetween(viewDir, vec3.fromValues(0, 0, 1));\n\n if (yawOffset === 0) {\n // If the yawOffset is exactly 0, then device sensor is not ready\n // So read it again until it has any value in it\n return;\n }\n\n vr.setYawOffset(yawOffset);\n animator.setCallback(this._renderStereo);\n };\n\n private _setWrapperFullscreen() {\n const wrapper = this._wrapper;\n\n if (!wrapper) return;\n\n this._wrapperOrigStyle = wrapper.getAttribute(\"style\");\n const wrapperStyle = wrapper.style;\n\n wrapperStyle.width = \"100vw\";\n wrapperStyle.height = \"100vh\";\n wrapperStyle.position = \"fixed\";\n wrapperStyle.left = \"0\";\n wrapperStyle.top = \"0\";\n wrapperStyle.zIndex = \"9999\";\n }\n\n private _restoreStyle() {\n const wrapper = this._wrapper;\n const canvas = this.canvas;\n\n if (!wrapper) return;\n\n if (this._wrapperOrigStyle) {\n wrapper.setAttribute(\"style\", this._wrapperOrigStyle);\n } else {\n wrapper.removeAttribute(\"style\");\n }\n\n this._wrapperOrigStyle = null;\n\n // Restore canvas style\n canvas.removeAttribute(\"style\");\n this._setDefaultCanvasStyle();\n }\n}\n\nexport default PanoImageRenderer;\n","import Component from \"@egjs/component\";\n\nconst withMethods = (component: any, prototype: any, vanillaInstance: string) => {\n [Component.prototype, component.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto).filter(name => !prototype[name] && !name.startsWith(\"_\") && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[vanillaInstance], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return descriptor.get?.call(this[vanillaInstance]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[vanillaInstance], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Promise from \"promise-polyfill\";\nimport { quat } from \"gl-matrix\";\n\nimport { DeviceMotionEvent, checkXRSupport } from \"../utils/browserFeature\";\nimport YawPitchControl, { YawPitchControlOptions } from \"../YawPitchControl/YawPitchControl\";\nimport PanoImageRenderer from \"../PanoImageRenderer/PanoImageRenderer\";\nimport WebGLUtils from \"../PanoImageRenderer/WebGLUtils\";\nimport { util as mathUtil } from \"../utils/math-util\";\nimport { VERSION } from \"../version\";\nimport { CubemapConfig, ValueOf } from \"../types/internal\";\nimport { AnimationEndEvent, ReadyEvent, ViewChangeEvent, ErrorEvent } from \"../types/event\";\n\nimport { ERROR_TYPE, PANOVIEWER_EVENTS as EVENTS, GYRO_MODE, PROJECTION_TYPE, STEREO_FORMAT, DEFAULT_CANVAS_CLASS } from \"./consts\";\n\nexport interface PanoViewerOptions {\n image: string | HTMLElement;\n video: string | HTMLElement;\n projectionType: ValueOf;\n cubemapConfig: Partial;\n stereoFormat: ValueOf;\n width: number;\n height: number;\n yaw: number;\n pitch: number;\n fov: number;\n showPolePoint: boolean;\n useZoom: boolean;\n useKeyboard: boolean;\n gyroMode: ValueOf;\n yawRange: number[];\n pitchRange: number[];\n fovRange: number[];\n touchDirection: ValueOf;\n canvasClass: string;\n}\n\nexport interface PanoViewerEvent {\n ready: ReadyEvent;\n viewChange: ViewChangeEvent;\n animationEnd: AnimationEndEvent;\n error: ErrorEvent;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * PanoViewer\n */\nclass PanoViewer extends Component {\n /**\n * Check whether the current environment can execute PanoViewer\n * @ko 현재 브라우저 환경에서 PanoViewer 실행이 가능한지 여부를 반환합니다.\n * @return PanoViewer executable PanoViewer 실행가능 여부\n */\n public static isSupported(): boolean {\n return WebGLUtils.isWebGLAvailable() && WebGLUtils.isStableWebGL();\n }\n\n /**\n * Check whether the current environment supports the WebGL\n * @ko 현재 브라우저 환경이 WebGL 을 지원하는지 여부를 확인합니다.\n * @return WebGL support WebGL 지원여부\n */\n public static isWebGLAvailable(): boolean {\n return WebGLUtils.isWebGLAvailable();\n }\n\n /**\n * Check whether the current environment supports the gyro sensor.\n * @ko 현재 브라우저 환경이 자이로 센서를 지원하는지 여부를 확인합니다.\n * @param callback Function to take the gyro sensor availability as argument 자이로 센서를 지원하는지 여부를 인자로 받는 함수\n */\n public static isGyroSensorAvailable(callback: (isAvailable: boolean) => any) {\n if (!DeviceMotionEvent && callback) {\n callback(false);\n return;\n }\n\n let onDeviceMotionChange;\n\n const checkGyro = () => new Promise(res => {\n onDeviceMotionChange = deviceMotion => {\n const isGyroSensorAvailable = !(deviceMotion.rotationRate.alpha == null);\n\n res(isGyroSensorAvailable);\n };\n\n window.addEventListener(\"devicemotion\", onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n Promise.race([checkGyro(), timeout()]).then((isGyroSensorAvailable: boolean) => {\n window.removeEventListener(\"devicemotion\", onDeviceMotionChange);\n\n if (callback) {\n callback(isGyroSensorAvailable);\n }\n\n PanoViewer.isGyroSensorAvailable = fb => {\n if (fb) {\n fb(isGyroSensorAvailable);\n }\n return isGyroSensorAvailable;\n };\n });\n }\n\n private static _isValidTouchDirection(direction) {\n return direction === PanoViewer.TOUCH_DIRECTION.NONE ||\n direction === PanoViewer.TOUCH_DIRECTION.YAW ||\n direction === PanoViewer.TOUCH_DIRECTION.PITCH ||\n direction === PanoViewer.TOUCH_DIRECTION.ALL;\n }\n\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @name VERSION\n * @static\n * @type {String}\n * @example\n * eg.view360.PanoViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.PanoViewer\n */\n public static VERSION = VERSION;\n public static ERROR_TYPE = ERROR_TYPE;\n public static EVENTS = EVENTS;\n public static PROJECTION_TYPE = PROJECTION_TYPE;\n public static GYRO_MODE = GYRO_MODE;\n // This should be deprecated!\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public static ProjectionType = PROJECTION_TYPE;\n public static STEREO_FORMAT = STEREO_FORMAT;\n\n /**\n * Constant value for touch directions\n * @ko 터치 방향에 대한 상수 값.\n * @namespace\n * @name TOUCH_DIRECTION\n */\n public static TOUCH_DIRECTION = {\n /**\n * Constant value for none direction.\n * @ko none 방향에 대한 상수 값.\n * @name NONE\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 1\n */\n NONE: YawPitchControl.TOUCH_DIRECTION_NONE,\n /**\n * Constant value for horizontal(yaw) direction.\n * @ko horizontal(yaw) 방향에 대한 상수 값.\n * @name YAW\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 6\n */\n YAW: YawPitchControl.TOUCH_DIRECTION_YAW,\n /**\n * Constant value for vertical direction.\n * @ko vertical(pitch) 방향에 대한 상수 값.\n * @name PITCH\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 24\n */\n PITCH: YawPitchControl.TOUCH_DIRECTION_PITCH,\n /**\n * Constant value for all direction.\n * @ko all 방향에 대한 상수 값.\n * @name ALL\n * @memberof eg.view360.PanoViewer.TOUCH_DIRECTION\n * @constant\n * @type {Number}\n * @default 30\n */\n ALL: YawPitchControl.TOUCH_DIRECTION_ALL\n };\n\n private _container: HTMLElement;\n // Options\n private _image: ConstructorParameters[0];\n private _isVideo: boolean;\n private _projectionType: ValueOf;\n private _cubemapConfig: Partial;\n private _stereoFormat: ValueOf;\n private _width: number;\n private _height: number;\n private _yaw: number;\n private _pitch: number;\n private _fov: number;\n private _gyroMode: ValueOf;\n private _quaternion: quat | null;\n private _aspectRatio: number;\n private _isReady: boolean;\n private _canvasClass: string;\n\n // Internal Values\n private _photoSphereRenderer: PanoImageRenderer | null;\n private _yawPitchControl: YawPitchControl | null;\n\n /**\n * @classdesc 360 media viewer\n * @ko 360 미디어 뷰어\n *\n * @param container The container element for the renderer. 렌더러의 컨테이너 엘리먼트\n * @param options\n *\n * @param {String|HTMLImageElement} options.image Input image url or element (Use only image property or video property)입력 이미지 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String|HTMLVideoElement} options.video Input video url or element(Use only image property or video property)입력 비디오 URL 혹은 엘리먼트(image 와 video 둘 중 하나만 설정)\n * @param {String} [options.projectionType=equirectangular] The type of projection: equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}Projection 유형 : equirectangular, cubemap
{@link eg.view360.PanoViewer.PROJECTION_TYPE}
\n * @param {Object} options.cubemapConfig Config cubemap projection layout. It is applied when projectionType is {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} or {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP}cubemap projection type 의 레이아웃을 설정한다. 이 설정은 ProjectionType이 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP} 혹은 {@link eg.view360.PanoViewer.PROJECTION_TYPE.CUBESTRIP} 인 경우에만 적용된다.\n * @param {Object} [options.cubemapConfig.order = \"RLUDBF\"(ProjectionType === CUBEMAP) | \"RLUDFB\" (ProjectionType === CUBESTRIP)] Order of cubemap faces Cubemap 형태의 이미지가 배치된 순서\n * @param {Object} [options.cubemapConfig.tileConfig = { flipHorizontal:false, rotation: 0 }] Setting about rotation angle(degree) and whether to flip horizontal for each cubemap faces, if you put this object as a array, you can set each faces with different setting. For example, [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]각 Cubemap 면에 대한 회전 각도/좌우반전 여부 설정, 객체를 배열 형태로 지정하여 각 면에 대한 설정을 다르게 지정할 수도 있다. 예를 들어 [{flipHorizontal:false, rotation:90}, {flipHorizontal: true, rotation: 180}, ...]과 같이 지정할 수 있다.\n * @param {Number} [options.cubemapConfig.trim=0] A px distance to discard from each tile side. You can use this value to avoid graphical glitch at where tiles are connected. This option is available when there's only one texture.각 타일의 끝으로부터 폐기할 px 거리. 이 옵션을 사용하여 타일의 접합부에서 나타나는 그래픽 결함을 완화할 수 있습니다. 이 옵션은 한 개의 텍스쳐만 사용할 때 적용 가능합니다.\n * @param {String} [options.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection.
See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다.
{@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.
\n * @param {Number} [options.width=width of container] the viewer's width. (in px) 뷰어의 너비 (px 단위)\n * @param {Number} [options.height=height of container] the viewer's height.(in px) 뷰어의 높이 (px 단위)\n * @param {Number} [options.yaw=0] Initial Yaw of camera (in degree) 카메라의 초기 Yaw (degree 단위)\n * @param {Number} [options.pitch=0] Initial Pitch of camera (in degree) 카메라의 초기 Pitch (degree 단위)\n * @param {Number} [options.fov=65] Initial vertical field of view of camera (in degree) 카메라의 초기 수직 field of view (degree 단위)\n * @param {Boolean} [options.showPolePoint=false] If false, the pole is not displayed inside the viewport false 인 경우, 극점은 뷰포트 내부에 표시되지 않습니다\n * @param {Boolean} [options.useZoom=true] When true, enables zoom with the wheel and Pinch gesture true 일 때 휠 및 집기 제스춰로 확대 / 축소 할 수 있습니다.\n * @param {Boolean} [options.useKeyboard=true] When true, enables the keyboard move key control: awsd, arrow keys true 이면 키보드 이동 키 컨트롤을 활성화합니다: awsd, 화살표 키\n * @param {String} [options.gyroMode=yawPitch] Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE} 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")
{@link eg.view360.PanoViewer.GYRO_MODE}
\n * @param {Array} [options.yawRange=[-180, 180]] Range of controllable Yaw values 제어 가능한 Yaw 값의 범위\n * @param {Array} [options.pitchRange=[-90, 90]] Range of controllable Pitch values 제어 가능한 Pitch 값의 범위\n * @param {Array} [options.fovRange=[30, 110]] Range of controllable vertical field of view values 제어 가능한 수직 field of view 값의 범위\n * @param {Number} [options.touchDirection= {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}(6)] Direction of touch that can be controlled by user
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}사용자가 터치로 조작 가능한 방향
{@link eg.view360.PanoViewer.TOUCH_DIRECTION}
\n * @param {String} [options.canvasClass=\"view360-canvas\"] A class name for the canvas element inside the container element. PanoViewer will use the canvas that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 캔버스 엘리먼트의 클래스 이름. PanoViewer는 해당 클래스를 갖는 캔버스 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n *\n * @example\n * ```\n * // PanoViewer Creation\n * // create PanoViewer with option\n * var PanoViewer = eg.view360.PanoViewer;\n * // Area where the image will be displayed(HTMLElement)\n * var container = document.getElementById(\"myPanoViewer\");\n *\n * var panoViewer = new PanoViewer(container, {\n * // If projectionType is not specified, the default is \"equirectangular\".\n * // Specifies an image of the \"equirectangular\" type.\n * image: \"/path/to/image/image.jpg\"\n * });\n * ```\n *\n * @example\n * ```\n * // Cubemap Config Setting Example\n * // For support Youtube EAC projection, You should set cubemapConfig as follows.\n * cubemapConfig: {\n * order: \"LFRDBU\",\n * tileConfig: [{rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: 0}, {rotation: -90}, {rotation: 180}]\n * }\n * ```\n */\n public constructor(container: HTMLElement, options: Partial = {}) {\n super();\n\n // Raises the error event if webgl is not supported.\n if (!WebGLUtils.isWebGLAvailable()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.NO_WEBGL,\n message: \"no webgl support\"\n }));\n }, 0);\n return this;\n }\n\n if (!WebGLUtils.isStableWebGL()) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_DEVICE,\n message: \"blacklisted browser\"\n }));\n }, 0);\n\n return this;\n }\n\n if (!!options.image && !!options.video) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.INVALID_RESOURCE,\n message: \"Specifying multi resouces(both image and video) is not valid.\"\n }));\n }, 0);\n return this;\n }\n\n // Check XR support at not when imported, but when created.\n // This is intended to make polyfills easier to use.\n checkXRSupport();\n\n this._container = container;\n this._image = options.image! as HTMLImageElement || options.video! as HTMLVideoElement;\n this._isVideo = !!options.video;\n this._projectionType = options.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = {\n ...{\n /* RLUDBF is abnormal, we use it on CUBEMAP only for backward compatibility*/\n order: this._projectionType === PROJECTION_TYPE.CUBEMAP ? \"RLUDBF\" : \"RLUDFB\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...options.cubemapConfig\n };\n this._stereoFormat = options.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n\n // If the width and height are not provided, will use the size of the container.\n this._width = options.width || parseInt(window.getComputedStyle(container).width, 10);\n this._height = options.height || parseInt(window.getComputedStyle(container).height, 10);\n\n /**\n * Cache the direction for the performance in renderLoop\n *\n * This value should be updated by \"change\" event of YawPitchControl.\n */\n this._yaw = options.yaw || 0;\n this._pitch = options.pitch || 0;\n this._fov = options.fov || 65;\n\n this._gyroMode = options.gyroMode || GYRO_MODE.YAWPITCH;\n this._quaternion = null;\n\n this._aspectRatio = this._height !== 0 ? this._width / this._height : 1;\n\n this._canvasClass = options.canvasClass || DEFAULT_CANVAS_CLASS;\n\n const fovRange = options.fovRange || [30, 110];\n const touchDirection = PanoViewer._isValidTouchDirection(options.touchDirection) ?\n options.touchDirection : YawPitchControl.TOUCH_DIRECTION_ALL;\n const yawPitchConfig = {\n ...options,\n ...{\n element: container,\n yaw: this._yaw,\n pitch: this._pitch,\n fov: this._fov,\n gyroMode: this._gyroMode,\n fovRange,\n aspectRatio: this._aspectRatio,\n touchDirection\n }\n };\n\n this._isReady = false;\n\n this._initYawPitchControl(yawPitchConfig);\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n /**\n * Get the video element that the viewer is currently playing. You can use this for playback.\n * @ko 뷰어가 현재 사용 중인 비디오 요소를 얻습니다. 이 요소를 이용해 비디오의 컨트롤을 할 수 있습니다.\n * @return HTMLVideoElementHTMLVideoElement\n * @example\n * ```\n * var videoTag = panoViewer.getVideo();\n * videoTag.play(); // play the video!\n * ```\n */\n public getVideo() {\n if (!this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent() as HTMLVideoElement;\n }\n\n /**\n * Set the video information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLVideoElement|object} video Input video url or element or config object입력 비디오 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정)\n * @param {object} param\n * @param {string} [param.projectionType={@link eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR}(\"equirectangular\")] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 의 레이아웃 설정\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setVideo(\"/path/to/video/video.mp4\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.EQUIRECTANGULAR\n * });\n * ```\n */\n public setVideo(video: string | HTMLElement | { type: string; src: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n }> = {}) {\n if (video) {\n this.setImage(video, {\n projectionType: param.projectionType,\n isVideo: true,\n cubemapConfig: param.cubemapConfig,\n stereoFormat: param.stereoFormat\n });\n }\n\n return this;\n }\n\n /**\n * Get the image information that the viewer is currently using.\n * @ko 뷰어가 현재 사용하고있는 이미지 정보를 얻습니다.\n * @return Image Object이미지 객체\n * @example\n * var imageObj = panoViewer.getImage();\n */\n public getImage() {\n if (this._isVideo) {\n return null;\n }\n\n return this._photoSphereRenderer!.getContent();\n }\n\n /**\n * Set the image information to be used by the viewer.\n * @ko 뷰어가 사용할 이미지 정보를 설정합니다.\n * @param {string|HTMLElement|object} image Input image url or element or config object입력 이미지 URL 혹은 엘리먼트 혹은 설정객체를 활용(image 와 video 둘 중 하나만 설정한다.)\n * @param {object} param Additional information이미지 추가 정보\n * @param {string} [param.projectionType=\"equirectangular\"] Projection Type프로젝션 타입\n * @param {object} param.cubemapConfig config cubemap projection layout. cubemap projection type 레이아웃\n * @param {string} [param.stereoFormat=\"3dv\"] Contents format of the stereoscopic equirectangular projection. See {@link eg.view360.PanoViewer.STEREO_FORMAT}.Stereoscopic equirectangular projection type의 콘텐츠 포맷을 설정한다. {@link eg.view360.PanoViewer.STEREO_FORMAT} 참조.\n * @param {boolean} [param.isVideo=false] Whether the given `imaage` is video or not.이미지가 비디오인지 여부\n *\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setImage(\"/path/to/image/image.png\", {\n * projectionType: eg.view360.PanoViewer.PROJECTION_TYPE.CUBEMAP\n * });\n * ```\n */\n public setImage(image: string | HTMLElement | { src: string; type: string }, param: Partial<{\n projectionType: PanoViewer[\"_projectionType\"];\n cubemapConfig: PanoViewer[\"_cubemapConfig\"];\n stereoFormat: PanoViewer[\"_stereoFormat\"];\n isVideo: boolean;\n }> = {}) {\n const cubemapConfig = {\n ...{\n order: \"RLUDBF\",\n tileConfig: {\n flipHorizontal: false,\n rotation: 0\n },\n trim: 0\n }, ...param.cubemapConfig\n };\n const stereoFormat = param.stereoFormat || STEREO_FORMAT.TOP_BOTTOM;\n const isVideo = !!(param.isVideo);\n\n if (this._image && this._isVideo !== isVideo) {\n /* eslint-disable no-console */\n console.warn(\"PanoViewer is not currently supporting content type changes. (Image <--> Video)\");\n /* eslint-enable no-console */\n return this;\n }\n\n if (image) {\n this._deactivate();\n\n this._image = image as HTMLImageElement;\n this._isVideo = isVideo;\n this._projectionType = param.projectionType || PROJECTION_TYPE.EQUIRECTANGULAR;\n this._cubemapConfig = cubemapConfig;\n this._stereoFormat = stereoFormat;\n\n this._initRenderer(this._yaw, this._pitch, this._fov, this._projectionType, this._cubemapConfig);\n }\n\n return this;\n }\n\n /**\n * Set whether the renderer always updates the texture and renders.\n * @ko 렌더러가 항상 텍스쳐를 갱신하고 화면을 렌더링 할지 여부를 설정할 수 있습니다.\n * @param doUpdate When true viewer will always update texture and render, when false viewer will not update texture and render only camera config is changed.true면 항상 텍스쳐를 갱신하고 화면을 그리는 반면, false면 텍스쳐 갱신은 하지 않으며, 카메라 요소에 변화가 있을 때에만 화면을 그립니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public keepUpdate(doUpdate: boolean) {\n this._photoSphereRenderer!.keepUpdate(doUpdate);\n return this;\n }\n\n /**\n * Get the current projection type (equirectangular/cube)\n * @ko 현재 프로젝션 타입(Equirectangular 혹은 Cube)을 반환합니다.\n * @return {@link eg.view360.PanoViewer.PROJECTION_TYPE}\n */\n public getProjectionType() {\n return this._projectionType;\n }\n\n /**\n * Activate the device's motion sensor, and return the Promise whether the sensor is enabled\n * If it's iOS13+, this method must be used in the context of user interaction, like onclick callback on the button element.\n * @ko 디바이스의 모션 센서를 활성화하고, 활성화 여부를 담는 Promise를 리턴합니다.\n * iOS13+일 경우, 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * @return Promise containing nothing when resolved, or string of the rejected reason when rejected.Promise. resolve되었을 경우 아무것도 반환하지 않고, reject되었을 경우 그 이유를 담고있는 string을 반환한다.\n */\n public enableSensor() {\n return new Promise((resolve, reject) => {\n if (DeviceMotionEvent && typeof DeviceMotionEvent.requestPermission === \"function\") {\n DeviceMotionEvent.requestPermission().then(permissionState => {\n if (permissionState === \"granted\") {\n resolve();\n } else {\n reject(new Error(\"permission denied\"));\n }\n }).catch(e => {\n // This can happen when this method wasn't triggered by user interaction\n reject(e);\n });\n } else {\n resolve();\n }\n });\n }\n\n /**\n * Disable the device's motion sensor.\n * @ko 디바이스의 모션 센서를 비활성화합니다.\n * @deprecated\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public disableSensor() {\n return this;\n }\n\n /**\n * Switch to VR stereo rendering mode which uses WebXR / WebVR API (WebXR is preferred).\n * This method must be used in the context of user interaction, like onclick callback on the button element.\n * It can be rejected when an enabling device sensor fails or image/video is still loading(\"ready\" event not triggered).\n * @ko WebXR / WebVR API를 사용하는 VR 스테레오 렌더링 모드로 전환합니다. (WebXR을 더 선호합니다)\n * 이 메소드는 사용자 인터렉션에 의해서 호출되어야 합니다. 예로, 버튼의 onclick 콜백과 같은 콘텍스트에서 호출되어야 합니다.\n * 디바이스 센서 활성화에 실패시 혹은 아직 이미지/비디오가 로딩중인 경우(\"ready\"이벤트가 아직 트리거되지 않은 경우)에는 Promise가 reject됩니다.\n * @param {object} [options={}] Additional options for WebXR session, see {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}.WebXR용 추가 옵션, {@link https://developer.mozilla.org/en-US/docs/Web/API/XRSessionInit XRSessionInit}을 참조해주세요.\n * @return Promise containing either a string of resolved reason or an Error instance of rejected reason.Promise가 resolve된 이유(string) 혹은 reject된 이유(Error)\n */\n public enterVR(options: {\n requiredFeatures?: any[];\n optionalFeatures?: any[];\n [key: string]: any;\n } = {}): globalThis.Promise {\n if (!this._isReady) {\n return Promise.reject(new Error(\"PanoViewer is not ready to show image.\")) as any;\n }\n\n return new Promise((resolve, reject) => {\n this.enableSensor()\n .then(() => this._photoSphereRenderer!.enterVR(options))\n .then((res: string) => resolve(res))\n .catch(e => reject(e));\n }) as any;\n }\n\n /**\n * Exit VR stereo rendering mode.\n * @ko VR 스테레오 렌더링 모드에서 일반 렌더링 모드로 전환합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public exitVR() {\n this._photoSphereRenderer!.exitVR();\n return this;\n }\n\n /**\n * When set true, enables zoom with the wheel or pinch gesture. However, in the case of touch, pinch works only when the touchDirection setting is {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL}.\n * @ko true 로 설정 시 휠 혹은 집기 동작으로 확대/축소 할 수 있습니다. false 설정 시 확대/축소 기능을 비활성화 합니다. 단, 터치인 경우 touchDirection 설정이 {@link eg.view360.PanoViewer.TOUCH_DIRECTION.ALL} 인 경우에만 pinch 가 동작합니다.\n * @param useZoom\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseZoom(useZoom: boolean): this {\n if (typeof useZoom === \"boolean\") {\n this._yawPitchControl!.option(\"useZoom\", useZoom);\n }\n\n return this;\n }\n\n /**\n * When true, enables the keyboard move key control: awsd, arrow keys\n * @ko true이면 키보드 이동 키 컨트롤을 활성화합니다. (awsd, 화살표 키)\n * @param useKeyboard\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setUseKeyboard(useKeyboard: boolean): this {\n this._yawPitchControl!.option(\"useKeyboard\", useKeyboard);\n return this;\n }\n\n /**\n * Enables control through device motion. (\"none\", \"yawPitch\", \"VR\")\n * @ko 디바이스 움직임을 통한 컨트롤을 활성화 합니다. (\"none\", \"yawPitch\", \"VR\")\n * @param gyroMode {@link eg.view360.PanoViewer.GYRO_MODE}\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * panoViewer.setGyroMode(\"yawPitch\");\n * //equivalent\n * panoViewer.setGyroMode(eg.view360.PanoViewer.GYRO_MODE.YAWPITCH);\n * ```\n */\n public setGyroMode(gyroMode: PanoViewer[\"_gyroMode\"]) {\n this._yawPitchControl!.option(\"gyroMode\", gyroMode);\n return this;\n }\n\n /**\n * Set the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 설정합니다.\n * @param range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setFovRange([50, 90]);\n */\n public setFovRange(range: number[]) {\n this._yawPitchControl!.option(\"fovRange\", range);\n return this;\n }\n\n /**\n * Get the range of controllable FOV values\n * @ko 제어 가능한 FOV 구간을 반환합니다.\n * @return FOV range\n * @example\n * var range = panoViewer.getFovRange(); // [50, 90]\n */\n public getFovRange(): [number, number] {\n return this._yawPitchControl!.option(\"fovRange\") as [number, number];\n }\n\n /**\n * Update size of canvas element by it's container element's or specified size. If size is not specified, the size of the container area is obtained and updated to that size.\n * @ko 캔버스 엘리먼트의 크기를 컨테이너 엘리먼트의 크기나 지정된 크기로 업데이트합니다. 만약 size 가 지정되지 않으면 컨테이너 영역의 크기를 얻어와 해당 크기로 갱신합니다.\n * @param {object} [size]\n * @param {number} [size.width=width of the container]\n * @param {number} [size.height=height of the container]\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public updateViewportDimensions(size: Partial<{\n width: number;\n height: number;\n }> = {}): this {\n if (!this._isReady) {\n return this;\n }\n\n let containerSize;\n\n if (size.width === undefined || size.height === undefined) {\n containerSize = window.getComputedStyle(this._container);\n }\n\n const width = size.width || parseInt(containerSize.width, 10);\n const height = size.height || parseInt(containerSize.height, 10);\n\n // Skip if viewport is not changed.\n if (width === this._width && height === this._height) {\n return this;\n }\n\n this._width = width;\n this._height = height;\n\n this._aspectRatio = width / height;\n this._photoSphereRenderer!.updateViewportDimensions(width, height);\n this._yawPitchControl!.option(\"aspectRatio\", this._aspectRatio);\n this._yawPitchControl!.updatePanScale({height});\n\n this.lookAt({}, 0);\n return this;\n }\n\n /**\n * Get the current field of view(FOV)\n * @ko 현재 field of view(FOV) 값을 반환합니다.\n */\n public getFov(): number {\n return this._fov;\n }\n\n /**\n * Get current yaw value\n * @ko 현재 yaw 값을 반환합니다.\n */\n public getYaw() {\n return this._yaw;\n }\n\n /**\n * Get current pitch value\n * @ko 현재 pitch 값을 반환합니다.\n */\n public getPitch() {\n return this._pitch;\n }\n\n /**\n * Get the range of controllable Yaw values\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n */\n public getYawRange(): [number, number] {\n return this._yawPitchControl!.option(\"yawRange\") as [number, number];\n }\n\n /**\n * Get the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 가져옵니다.\n */\n public getPitchRange(): [number, number] {\n return this._yawPitchControl!.option(\"pitchRange\") as [number, number];\n }\n\n /**\n * Set the range of controllable yaw\n * @ko 컨트롤 가능한 Yaw 구간을 반환합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setYawRange([-90, 90]);\n */\n public setYawRange(yawRange: number[]) {\n this._yawPitchControl!.option(\"yawRange\", yawRange);\n return this;\n }\n\n /**\n * Set the range of controllable Pitch values\n * @ko 컨트롤 가능한 Pitch 구간을 설정합니다.\n * @param {number[]} range\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * panoViewer.setPitchRange([-40, 40]);\n */\n public setPitchRange(pitchRange: number[]) {\n this._yawPitchControl!.option(\"pitchRange\", pitchRange);\n return this;\n }\n\n /**\n * Specifies whether to display the pole by limiting the pitch range. If it is true, pole point can be displayed. If it is false, it is not displayed.\n * @ko pitch 범위를 제한하여 극점을 표시할지를 지정합니다. true 인 경우 극점까지 표현할 수 있으며 false 인 경우 극점까지 표시하지 않습니다.\n * @param showPolePoint\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public setShowPolePoint(showPolePoint: boolean) {\n this._yawPitchControl!.option(\"showPolePoint\", showPolePoint);\n return this;\n }\n\n /**\n * Set a new view by setting camera configuration. Any parameters not specified remain the same.\n * @ko 카메라 설정을 지정하여 화면을 갱신합니다. 지정되지 않은 매개 변수는 동일하게 유지됩니다.\n * @param {object} orientation\n * @param {number} orientation.yaw Target yaw in degree 목표 yaw (degree 단위)\n * @param {number} orientation.pitch Target pitch in degree 목표 pitch (degree 단위)\n * @param {number} orientation.fov Target vertical fov in degree 목표 수직 fov (degree 단위)\n * @param {number} duration Animation duration in milliseconds 애니메이션 시간 (밀리 초)\n * @return PanoViewer instancePanoViewer 인스턴스\n * @example\n * ```\n * // Change the yaw angle (absolute angle) to 30 degrees for one second.\n * panoViewer.lookAt({yaw: 30}, 1000);\n * ```\n */\n public lookAt(orientation: Partial<{\n yaw: number;\n pitch: number;\n fov: number;\n }>, duration: number = 0) {\n if (!this._isReady) {\n return this;\n }\n\n const yaw = orientation.yaw !== undefined ? orientation.yaw : this._yaw;\n const pitch = orientation.pitch !== undefined ? orientation.pitch : this._pitch;\n const pitchRange = this._yawPitchControl!.option(\"pitchRange\");\n const verticalAngleOfImage = pitchRange[1] - pitchRange[0];\n let fov = orientation.fov !== undefined ? orientation.fov : this._fov;\n\n if (verticalAngleOfImage < fov) {\n fov = verticalAngleOfImage;\n }\n\n this._yawPitchControl!.lookAt({yaw, pitch, fov}, duration);\n\n if (duration === 0) {\n this._photoSphereRenderer!.renderWithYawPitch(yaw, pitch, fov);\n }\n return this;\n }\n\n /**\n * Set touch direction by which user can control.\n * @ko 사용자가 조작가능한 터치 방향을 지정합니다.\n * @param direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @return PanoViewer instance\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Limit the touch direction to the yaw direction only.\n * panoViewer.setTouchDirection(eg.view360.PanoViewer.TOUCH_DIRECTION.YAW);\n * ```\n */\n public setTouchDirection(direction: number): this {\n if (PanoViewer._isValidTouchDirection(direction)) {\n this._yawPitchControl!.option(\"touchDirection\", direction);\n }\n\n return this;\n }\n\n /**\n * Returns touch direction by which user can control\n * @ko 사용자가 조작가능한 터치 방향을 반환한다.\n * @return direction of the touch. {@link eg.view360.PanoViewer.TOUCH_DIRECTION}컨트롤 가능한 방향 {@link eg.view360.PanoViewer.TOUCH_DIRECTION}\n * @example\n * ```\n * panoViewer = new PanoViewer(el);\n * // Returns the current touch direction.\n * var dir = panoViewer.getTouchDirection();\n * ```\n */\n public getTouchDirection(): number {\n return this._yawPitchControl!.option(\"touchDirection\") ;\n }\n\n /**\n * Destroy viewer. Remove all registered event listeners and remove viewer canvas.\n * @ko 뷰어 인스턴스를 해제합니다. 모든 등록된 이벤트리스너를 제거하고 뷰어 캔버스를 삭제합니다.\n * @return PanoViewer instancePanoViewer 인스턴스\n */\n public destroy(): this {\n this._deactivate();\n\n if (this._yawPitchControl) {\n this._yawPitchControl.destroy();\n this._yawPitchControl = null;\n }\n\n return this;\n }\n\n // TODO: Remove parameters as they're just using private values\n private _initRenderer(\n yaw: number,\n pitch: number,\n fov: number,\n projectionType: PanoViewer[\"_projectionType\"],\n cubemapConfig: PanoViewer[\"_cubemapConfig\"]\n ) {\n this._photoSphereRenderer = new PanoImageRenderer(\n this._image,\n this._width,\n this._height,\n this._isVideo,\n this._container,\n this._canvasClass,\n {\n initialYaw: yaw,\n initialPitch: pitch,\n fieldOfView: fov,\n imageType: projectionType,\n cubemapConfig,\n stereoFormat: this._stereoFormat\n },\n );\n this._photoSphereRenderer.setYawPitchControl(this._yawPitchControl!);\n\n this._bindRendererHandler();\n\n this._photoSphereRenderer\n .bindTexture()\n .then(() => this._activate())\n .catch(() => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.FAIL_BIND_TEXTURE,\n message: \"failed to bind texture\"\n }));\n });\n }\n\n /**\n * @private\n * update values of YawPitchControl if needed.\n * For example, In Panorama mode, initial fov and pitchRange is changed by aspect ratio of image.\n *\n * This function should be called after isReady status is true.\n */\n private _updateYawPitchIfNeeded() {\n if (this._projectionType === PanoViewer.ProjectionType.PANORAMA) {\n // update fov by aspect ratio\n const image = this._photoSphereRenderer!.getContent()! as HTMLImageElement;\n let imageAspectRatio = image.naturalWidth / image.naturalHeight;\n let yawSize;\n let maxFov;\n\n // If height is larger than width, then we assume it's rotated by 90 degree.\n if (imageAspectRatio < 1) {\n // So inverse the aspect ratio.\n imageAspectRatio = 1 / imageAspectRatio;\n }\n\n if (imageAspectRatio < 6) {\n yawSize = mathUtil.toDegree(imageAspectRatio);\n // 0.5 means ratio of half height of cylinder(0.5) and radius of cylider(1). 0.5/1 = 0.5\n maxFov = mathUtil.toDegree(Math.atan(0.5)) * 2;\n } else {\n yawSize = 360;\n maxFov = (360 / imageAspectRatio); // Make it 5 fixed as axes does.\n }\n\n // console.log(\"_updateYawPitchIfNeeded\", maxFov, \"aspectRatio\", image.naturalWidth, image.naturalHeight, \"yawSize\", yawSize);\n const minFov = (this._yawPitchControl!.option(\"fovRange\"))[0];\n\n // this option should be called after fov is set.\n this._yawPitchControl!.option({\n \"fov\": maxFov, /* parameter for internal validation for pitchrange */\n \"yawRange\": [-yawSize / 2, yawSize / 2],\n \"pitchRange\": [-maxFov / 2, maxFov / 2],\n \"fovRange\": [minFov, maxFov]\n });\n this.lookAt({fov: maxFov});\n }\n }\n\n private\t_bindRendererHandler() {\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.ERROR, e => {\n this.trigger(new ComponentEvent(EVENTS.ERROR, e));\n });\n\n this._photoSphereRenderer!.on(PanoImageRenderer.EVENTS.RENDERING_CONTEXT_LOST, () => {\n this._deactivate();\n this.trigger(new ComponentEvent(EVENTS.ERROR, {\n type: ERROR_TYPE.RENDERING_CONTEXT_LOST,\n message: \"webgl rendering context lost\"\n }));\n });\n }\n\n private _initYawPitchControl(yawPitchConfig: Partial) {\n this._yawPitchControl = new YawPitchControl(yawPitchConfig);\n\n this._yawPitchControl.on(EVENTS.ANIMATION_END, e => {\n this.trigger(new ComponentEvent(EVENTS.ANIMATION_END, e));\n });\n\n this._yawPitchControl.on(\"change\", e => {\n this._yaw = e.yaw;\n this._pitch = e.pitch;\n this._fov = e.fov;\n this._quaternion = e.quaternion;\n\n this.trigger(new ComponentEvent(EVENTS.VIEW_CHANGE, {\n yaw: e.yaw,\n pitch: e.pitch,\n fov: e.fov,\n quaternion: e.quaternion,\n isTrusted: e.isTrusted\n }));\n });\n }\n\n private _activate() {\n this._photoSphereRenderer!.attachTo(this._container);\n this._yawPitchControl!.enable();\n\n this.updateViewportDimensions();\n\n this._isReady = true;\n\n // update yawPitchControl after isReady status is true.\n this._updateYawPitchIfNeeded();\n\n this.trigger(new ComponentEvent(EVENTS.READY));\n this._photoSphereRenderer!.startRender();\n }\n\n /**\n * Destroy webgl context and block user interaction and stop rendering\n */\n private _deactivate() {\n // Turn off the video if it has one\n const video = this.getVideo();\n if (video) {\n video.pause();\n }\n\n if (this._isReady) {\n this._photoSphereRenderer!.stopRender();\n this._yawPitchControl!.disable();\n this._isReady = false;\n }\n\n if (this._photoSphereRenderer) {\n this._photoSphereRenderer.destroy();\n this._photoSphereRenderer = null;\n }\n }\n}\n\nexport default PanoViewer;\n\n","import { SpinViewerOptions, SpinViewerEvent } from \"./SpinViewer\";\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport const SPINVIEWER_OPTIONS: { [key in keyof SpinViewerOptions]: true } = {\n imageUrl: true,\n rowCount: true,\n colCount: true,\n width: true,\n height: true,\n autoHeight: true,\n colRow: true,\n scale: true,\n frameIndex: true,\n wrapperClass: true,\n imageClass: true\n};\n\nexport const SPINVIEWER_EVENTS: {\n [key: string]: keyof SpinViewerEvent;\n} = {\n LOAD: \"load\",\n IMAGE_ERROR: \"imageError\",\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n};\n\nexport const DEFAULT_WRAPPER_CLASS = \"view360-wrapper\";\nexport const DEFAULT_IMAGE_CLASS = \"view360-image\";\n","import Component, { ComponentEvent } from \"@egjs/component\";\n\nimport { TRANSFORM, SUPPORT_WILLCHANGE } from \"../utils/browserFeature\";\nimport { VERSION } from \"../version\";\n\nimport { SpinViewerOptions } from \"./SpinViewer\";\nimport { DEFAULT_IMAGE_CLASS, DEFAULT_WRAPPER_CLASS } from \"./consts\";\n\nexport interface SpriteImageEvent {\n /**\n * Events that occur when component loading is complete\n * @ko 컴포넌트 로딩이 완료되면 발생하는 이벤트\n * @name eg.view360.SpriteImage#load\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {HTMLElement} param.target The target element for which to display the image 이미지를 보여줄 대상 엘리먼트\n * @param {HTMLElement} param.bgElement Generated background image element 생성된 background 이미지 엘리먼트\n *\n * @example\n *\n * sprites.on({\n * \"load\" : function(evt) {\n * console.log(\"load event fired - e.target\", e.target, \"e.bgElement\", e.bgElement);\n * }\n * });\n */\n load: {\n target: HTMLElement;\n bgElement: HTMLDivElement;\n };\n /**\n * An event that occurs when the image index is changed by the user's left / right panning\n * @ko 사용자의 좌우 Panning 에 의해 이미지 인덱스가 변경되었을때 발생하는 이벤트\n * @name eg.view360.SpriteImage#imageError\n * @event\n * @param {Object} param The object of data to be sent to an event 이벤트에 전달되는 데이터 객체\n * @param {String} param.imageUrl User-specified image URL 사용자가 지정한 이미지 URL\n *\n * @example\n *\n * sprites.on({\n * \"imageError\" : function(evt) {\n * // Error handling\n * console.log(e.imageUrl);\n * }\n * });\n */\n imageError: {\n imageUrl?: string;\n };\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpriteImage\n */\nclass SpriteImage extends Component {\n private static _createBgDiv(wrapperInContainer: HTMLDivElement | null, img: HTMLImageElement, rowCount: number, colCount: number, autoHeight: boolean) {\n const el = wrapperInContainer || document.createElement(\"div\");\n\n el.style.position = \"relative\";\n el.style.overflow = \"hidden\";\n\n img.style.position = \"absolute\";\n img.style.width = `${colCount * 100}%`;\n img.style.height = `${rowCount * 100}%`;\n\n /** Prevent image from being dragged on IE10, IE11, Safari especially */\n img.ondragstart = () => (false); // img.style.pointerEvents = \"none\";\n // Use hardware accelerator if available\n if (SUPPORT_WILLCHANGE) {\n (img.style.willChange = \"transform\");\n }\n\n el.appendChild(img);\n\n const unitWidth = img.naturalWidth / colCount;\n const unitHeight = img.naturalHeight / rowCount;\n\n if (autoHeight) {\n const r = unitHeight / unitWidth;\n\n el.style.paddingBottom = `${r * 100}%`;\n } else {\n el.style.height = \"100%\";\n }\n\n return el;\n }\n\n private static _getSizeString(size) {\n if (typeof size === \"number\") {\n return `${size}px`;\n }\n\n return size;\n }\n\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _rowCount: number;\n private _colCount: number;\n private _totalCount: number;\n private _width: number | string;\n private _height: number | string;\n private _autoHeight: boolean;\n private _colRow: number[];\n private _image: HTMLImageElement;\n private _bg: HTMLDivElement;\n private _autoPlayReservedInfo: { interval: number; playCount: number } | null;\n private _autoPlayTimer: number;\n\n /**\n * @class eg.view360.SpriteImage\n * @classdesc A module that displays a single or continuous image of any one of the \"sprite images\". SpinViewer internally uses SpriteImage to show each frame of the sprite image.\n * @ko 스프라이트 이미지 중 임의의 한 프레임을 단발성 혹은 연속적으로 보여주는 컴포넌트입니다. SpinViewer 는 내부적으로 SpriteImage 를 사용하여 스프라이트 이미지의 각 프레임을 보여줍니다.\n * @extends eg.Component\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.frameIndex=0] frameIndex specifies the index of the frame to be displayed in the \"Sprite image\". The frameIndex order is zero-based and indexed in Z form (left-to-right, top-to-bottom, and newline again from left to right).
- colRow is equivalent to frameIndex. However, if colRow is specified at the same time, colRow takes precedence.스프라이트 이미지 중에서 보여질 프레임의 인덱스를 지정합니다. frameIndex 순서는 0부터 시작하며 Z 형태(왼쪽에서 오른쪽, 위에서 아래, 개행 시 다시 왼쪽 부터)로 인덱싱합니다.
- colRow 는 frameIndex 와 동일한 기능을 합니다. 단, colRow 가 동시에 지정된 경우 colRow 가 우선합니다.
\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n *\n * // Initialize SpriteImage\n *\n * var el = document.getElementById(\"image-div\");\n * var sprites = new eg.view360.SpriteImage(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24\n * });\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n const opt = options || {};\n\n this._el = element;\n this._rowCount = opt.rowCount || 1;\n this._colCount = opt.colCount || 1;\n this._totalCount = this._rowCount * this._colCount; // total frames\n this._width = opt.width || \"auto\";\n this._height = opt.height || \"auto\";\n this._autoHeight = opt.autoHeight != null ? opt.autoHeight : true; // If autoHeight is specified, _height will be overwritten.\n this._colRow = [0, 0];\n\n if (opt.colRow) {\n this._colRow = opt.colRow;\n } else if (opt.frameIndex) {\n this.setFrameIndex(opt.frameIndex);\n }\n\n this._el.style.width = SpriteImage._getSizeString(this._width);\n this._el.style.height = SpriteImage._getSizeString(this._height);\n\n const wrapperClass = opt.wrapperClass || DEFAULT_WRAPPER_CLASS;\n const imageClass = opt.imageClass || DEFAULT_IMAGE_CLASS;\n\n if (!opt.imageUrl) {\n setTimeout(() => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n }, 0);\n return;\n }\n\n const imageInContainer = element.querySelector(`.${imageClass}`);\n const wrapperInContainer = element.querySelector(`.${wrapperClass}`);\n\n if (wrapperInContainer && imageInContainer) {\n // Set it to invisible to prevent wrapper being resized\n imageInContainer.style.display = \"none\";\n }\n\n this._image = imageInContainer || new Image();\n /**\n * Event\n */\n\n const image = this._image;\n\n image.onload = () => {\n if (wrapperInContainer && imageInContainer) {\n imageInContainer.style.display = \"\";\n }\n\n this._bg = SpriteImage._createBgDiv(\n wrapperInContainer,\n image,\n this._rowCount,\n this._colCount,\n this._autoHeight\n );\n this._el.appendChild(this._bg);\n this.setColRow(this._colRow[0], this._colRow[1]);\n\n this.trigger(new ComponentEvent(\"load\", {\n target: this._el,\n bgElement: this._bg\n }));\n\n if (this._autoPlayReservedInfo) {\n this.play(this._autoPlayReservedInfo);\n this._autoPlayReservedInfo = null;\n }\n };\n\n image.onerror = () => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: opt.imageUrl\n }));\n };\n\n image.src = opt.imageUrl;\n }\n\n /**\n * Specifies the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 frameIndex 값을 지정\n * @method eg.view360.SpriteImage#setFrameIndex\n * @param {Number} frameIndex frame index of a frame프레임의 인덱스\n *\n * @example\n *\n * sprites.setFrameIndex(0, 1);// col = 0, row = 1\n */\n public setFrameIndex(index: number) {\n const colRow = this.toColRow(index);\n\n this.setColRow(colRow[0], colRow[1]);\n }\n\n /**\n * Returns the frameIndex of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 index 값을 반환\n * @method eg.view360.SpriteImage#getFrameIndex\n * @return {Number} frame index frame 인덱스\n *\n * @example\n *\n * var frameIndex = sprites.getFrameIndex(); // eg. frameIndex = 1\n *\n */\n public getFrameIndex() {\n return this._colRow[1] * this._colCount + this._colRow[0];\n }\n\n /**\n * Specifies the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여질 프레임의 col, row 값을 지정\n * @method eg.view360.SpriteImage#setColRow\n * @param {Number} col Column number of a frame프레임의 행값\n * @param {Number} row Row number of a frame프레임의 열값\n *\n * @example\n *\n * sprites.setlColRow(1, 2); // col = 1, row = 2\n */\n public setColRow(col: number, row: number) {\n if (row > this._rowCount - 1 || col > this._colCount - 1) {\n return;\n }\n\n if (this._image && TRANSFORM) {\n // NOTE: Currently, do not apply translate3D for using layer hack. Do we need layer hack for old browser?\n this._image.style[TRANSFORM] = `translate(${-(col / this._colCount * 100)}%, ${-(row / this._rowCount * 100)}%)`;\n }\n\n this._colRow = [col, row];\n }\n\n /**\n * Returns the col and row values of the frame to be shown in the sprite image.\n * @ko 스프라이트 이미지 중 보여지는 프레임의 col, row 값을환반환\n * @method eg.view360.SpriteImage#gelColRow\n * @return {Number[]} Array containing col, rowcol, row 정보를 담는 배열\n *\n * @example\n *\n * var colRow = sprites.getlColRow();\n * // colRow = [1, 2] - index of col is 1, index of row is 2\n *\n */\n public getColRow() {\n return this._colRow;\n }\n\n /**\n * Stop playing\n * @ko play 되고 있던 프레임 재생을 중지합니다.\n * @method eg.view360.SpriteImage#stop\n *\n * @example\n *\n * viewer.stop();\n *\n */\n public stop() {\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n }\n\n /**\n * Switches frames sequentially in the 'interval' starting from the currently displayed frame and plays all frames by 'playCount'.\n * @ko 현재 보여지고 있는 프레임을 시작으로 'interval' 간격으로 순차적으로 프레임을 전환하며 모든 프레임을 'playCount' 만큼 재생한다.\n * @method eg.view360.SpriteImage#play\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.interval=1000 / totalFrameCount] Interframe Interval - in milliseconds프레임간 간격 - 밀리세컨드 단위\n * @param {Number} [param.playCount=0] PlayCount = 1 in which all frames are reproduced once, and playCount = n in which all frames are repeated n times. playCount = 0 in which all frames are repeated infinitely모든 프레임을 1회씩 재생한 것이 playCount = 1, 모든 프레임을 n 회 재상한 것이 playCount = n 이 된다. 0 dms 무한반복\n *\n * @example\n *\n * viewer.play({angle: 16, playCount: 1});\n *\n */\n public play({ interval, playCount } = { interval: 1000 / this._totalCount, playCount: 0 }) {\n if (!this._bg) {\n this._autoPlayReservedInfo = {interval, playCount};\n return;\n }\n\n if (this._autoPlayTimer) {\n clearInterval(this._autoPlayTimer);\n this._autoPlayTimer = -1;\n }\n\n let frameIndex = this.getFrameIndex();\n let count = 0;\n let frameCount = 0; // for checking 1 cycle\n\n this._autoPlayTimer = window.setInterval(() => {\n frameIndex %= this._totalCount;\n const colRow = this.toColRow(frameIndex);\n\n this.setColRow(colRow[0], colRow[1]);\n frameIndex++;\n\n // Done 1 Cycle?\n if (++frameCount === this._totalCount) {\n frameCount = 0;\n count++;\n }\n\n if (playCount > 0 && count === playCount) {\n clearInterval(this._autoPlayTimer);\n }\n }, interval);\n }\n\n public toColRow(frameIndex: number) {\n const colCount = this._colCount;\n const rowCount = this._rowCount;\n\n if (frameIndex < 0) {\n return [0, 0];\n } else if (frameIndex >= this._totalCount) {\n return [colCount - 1, rowCount - 1];\n }\n\n const col = frameIndex % colCount;\n const row = Math.floor(frameIndex / colCount);\n\n // console.log(frameIndex, col, row);\n return [col, row];\n }\n}\n\nexport default SpriteImage;\n","import Component, { ComponentEvent } from \"@egjs/component\";\nimport Axes, { PanInput } from \"@egjs/axes\";\n\nimport { VERSION } from \"../version\";\nimport { AnimationEndEvent, ChangeEvent, ImageErrorEvent, LoadEvent } from \"../types/event\";\n\nimport SpriteImage from \"./SpriteImage\";\n\nconst DEFAULT_PAN_SCALE = 0.21;\n\nexport interface SpinViewerEvent {\n load: LoadEvent;\n imageError: ImageErrorEvent;\n change: ChangeEvent;\n animationEnd: AnimationEndEvent;\n}\n\nexport interface SpinViewerOptions {\n imageUrl: string;\n rowCount: number;\n colCount: number;\n width: number | string;\n height: number | string;\n autoHeight: boolean;\n colRow: number[];\n scale: number;\n frameIndex: number;\n wrapperClass: string;\n imageClass: string;\n}\n\n/**\n * @memberof eg.view360\n * @extends eg.Component\n * SpinViewer\n */\nclass SpinViewer extends Component {\n /**\n * Version info string\n * @ko 버전정보 문자열\n * @static\n * @example\n * eg.view360.SpinViewer.VERSION; // ex) 3.0.1\n * @memberof eg.view360.SpinViewer\n */\n public static VERSION = VERSION;\n\n private _el: HTMLElement;\n private _sprites: SpriteImage;\n private _axes: Axes;\n private _panInput: PanInput;\n\n private _scale: number;\n private _panScale: number;\n private _frameCount: number;\n\n /**\n * @classdesc A module used to displays each image sequentially according to the direction of the user's touch movement (left / right) of the sprite image that is collected by rotating the object.\n * @ko 물체 주위를 회전하여 촬영한 이미지들을 모은 스프라이트 이미지를 사용자의 터치 이동 방향(좌 / 우) 에 따라 각 이미지들을 순차적으로 보여주는 컴포넌트입니다.\n *\n * @param {HTMLElement} element The element to show the image 이미지를 보여줄 대상 요소\n * @param {Object} options The option object파라미터 객체\n * @param {String} options.imageUrl The url of the sprite image 스프라이트 이미지의 url\n * @param {Number} [options.rowCount=1] Number of horizontal frames in the sprite image 스프라이트 이미지의 가로 프레임 갯수\n * @param {Number} [options.colCount=1] Number of vertical frames in the sprite image 스프라이트 이미지의 세로 프레임 갯수\n * @param {Number|String} [options.width=\"auto\"] The width of the target element to show the image 이미지를 보여줄 대상 요소의 너비\n * @param {Number|String} [options.height=\"auto\"] The height of the target element to show the image 이미지를 보여줄 대상 요소의 높이\n * @param {Boolean} [options.autoHeight=true] Whether to automatically set the height of the image area to match the original image's proportion 원본 이미지 비율에 맞게 이미지 영역의 높이를 자동으로 설정할지 여부\n * @param {Number[]} [options.colRow=[0, 0]] The column, row coordinates of the first frame of the sprite image (based on 0 index) 스프라이트 이미지 중 처음 보여줄 프레임의 (column, row) 좌표 (0 index 기반)\n * @param {Number} [options.scale=1] Spin scale (The larger the spin, the more).Spin 배율 (클 수록 더 많이 움직임)\n * @param {Number} [options.frameIndex] The frameIndex of the frame to be shown in the sprite image스프라이트 이미지 중 보여질 프레임의 frameIndex 값\n * @param {String} [options.wrapperClass=\"view360-wrapper\"] A class name for the parent element of the image element inside the container element. SpinViewer will use the element that has this class instead of creating one if it exists이미지 엘리먼트의 부모 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @param {String} [options.imageClass=\"view360-image\"] A class name for the image element inside the container element. SpinViewer will use the image element that has this class instead of creating one if it exists콘테이너 엘리먼트 내부의 이미지 엘리먼트의 클래스 이름. SpinViewer는 해당 클래스를 갖는 이미지 엘리먼트가 콘테이너 엘리먼트 내부에 존재할 경우, 새로 생성하는 대신 그 엘리먼트를 사용할 것입니다\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\", \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n * @example\n * ```\n * // Initialize SpinViewer\n * var el = document.getElementById(\"product-360\");\n * var viewer = new eg.view360.SpinViewer(el, {\n * \timageUrl: \"/img/bag360.jpg\", // required\n * \trowCount: 24 //required\n * });\n * ```\n */\n public constructor(element: HTMLElement, options: Partial = {}) {\n super();\n\n this._el = element;\n\n const opt = {...options};\n const colCount = opt.colCount || 1;\n const rowCount = opt.rowCount || 1;\n\n this._scale = (opt.scale || 1);\n this._panScale = this._scale * DEFAULT_PAN_SCALE;\n\n this._frameCount = colCount * rowCount;\n\n // Init SpriteImage\n this._sprites = new SpriteImage(element, opt).on({\n \"load\": evt => {\n this.trigger(new ComponentEvent(\"load\", evt));\n },\n \"imageError\": evt => {\n this.trigger(new ComponentEvent(\"imageError\", {\n imageUrl: evt.imageUrl\n }));\n }\n });\n\n // Init Axes\n this._panInput = new PanInput(this._el, {\n scale: [this._panScale, this._panScale]\n });\n this._axes = new Axes({\n angle: {\n range: [0, 359],\n circular: true\n }\n }).on({\n \"change\": evt => {\n const curr = Math.floor(evt.pos.angle / (360 / this._frameCount));\n const frameIndex = this._frameCount - curr - 1;\n\n this._sprites.setFrameIndex(frameIndex);\n\n this.trigger(new ComponentEvent(\"change\", {\n frameIndex,\n colRow: this._sprites.getColRow(),\n angle: evt.pos.angle\n }));\n },\n \"animationEnd\": evt => {\n this.trigger(new ComponentEvent(\"animationEnd\", {\n isTrusted: evt.isTrusted\n }));\n }\n });\n\n this._axes.connect(\"angle\", this._panInput);\n }\n\n /**\n * Set spin scale\n * @ko scale 을 조정할 수 있는 함수\n * @param {Number} scale Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.setScale(2);// It moves twice as much.\n */\n public setScale(scale: number) {\n if (isNaN(scale) || scale < 0) {\n return this;\n }\n\n this._scale = scale;\n this._panScale = scale * DEFAULT_PAN_SCALE;\n this._panInput.options.scale = [this._panScale, this._panScale];\n\n return this;\n }\n\n /**\n * Get spin scale\n * @ko scale 값을 반환한다.\n *\n * @return {Number} Rotation multiples at spin, the larger the rotationSpin 시 회전 배수값, 커질 수록 더 많이 회전\n *\n * @example\n * viewer.getScale();// It returns number\n */\n public getScale() {\n return this._scale;\n }\n\n /**\n * It gives the effect of rotating for a certain duration by the specified angle based on the current rotation angle.\n * @ko 현재 회전 각도를 기준으로 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle상대적 회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinBy(720, {duration: 500});\n */\n public spinBy(angle = 0, param = {duration: 0}) {\n this._axes.setBy({angle}, param.duration);\n return this;\n }\n\n /**\n * It gives the effect of rotating for a certain duration (duration) by the specified angle (angle).\n * @ko 지정된 각도(angle)만큼 일정 시간동안(duration) 회전하는 효과를 준다.\n * @param {Number} [angle = 0] angle회전 각도\n * @param {Object} param The parameter object파라미터 객체\n * @param {Number} [param.duration = 0] duration회전할 시간 - 밀리세컨드 단위\n *\n * @return {Object} Instance of SpinViewer SpinViewer 인스턴스\n *\n * @example\n * viewer.spinTo(30, {duration:100});\n */\n public spinTo(angle = 0, param = {duration: 0}) {\n this._axes.setTo({angle}, param.duration);\n return this;\n }\n\n /**\n * Returns current angles\n * @ko 현재 각도를 반환한다.\n *\n * @return {Number} Current angle 현재 각도\n */\n public getAngle() {\n return this._axes.get().angle || 0;\n }\n}\n\nexport default SpinViewer;\n","import PanoViewer, { PanoViewerOptions } from \"../PanoViewer/PanoViewer\";\n\nexport default (panoViewer: PanoViewer, newProps: Partial, prevProps: Partial) => {\n if (isPropChanged(newProps.image, prevProps.image)) {\n panoViewer.setImage(newProps.image, {\n projectionType: newProps.projectionType,\n cubemapConfig: newProps.cubemapConfig,\n stereoFormat: newProps.stereoFormat,\n isVideo: false\n });\n } else if (isPropChanged(newProps.video, prevProps.video)) {\n panoViewer.setVideo(newProps.video, {\n projectionType: newProps.projectionType,\n cubemapConfig: newProps.cubemapConfig,\n stereoFormat: newProps.stereoFormat\n });\n }\n\n const singleUpdateOptions: Array = [\n \"fovRange\",\n \"gyroMode\",\n \"pitchRange\",\n \"showPolePoint\",\n \"touchDirection\",\n \"useKeyboard\",\n \"useZoom\",\n \"yawRange\"\n ];\n\n singleUpdateOptions.forEach(optionName => {\n updateOption(panoViewer, optionName, newProps, prevProps);\n });\n};\n\nconst isPropChanged = (val: any, prevVal: any): val is true => val != null && val !== prevVal;\nconst updateOption = (panoViewer: PanoViewer, optionName: string, newProps: Partial, prevProps: Partial) => {\n if (isPropChanged(newProps[optionName], prevProps[optionName])) {\n panoViewer[`set${optionName[0].toUpperCase()}${optionName.slice(1)}`](newProps[optionName]);\n }\n};\n","import { PanoViewer } from \"../PanoViewer\";\n\nimport withMethods from \"./withMethods\";\n\nconst withPanoViewerMethods = (prototype: any, name: string) => {\n withMethods(PanoViewer, prototype, name);\n};\n\nexport default withPanoViewerMethods;\n","import { SpinViewer } from \"../SpinViewer\";\n\nimport withMethods from \"./withMethods\";\n\nconst withSpinViewerMethods = (prototype: any, name: string) => {\n withMethods(SpinViewer, prototype, name);\n};\n\nexport default withSpinViewerMethods;\n","export const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n\nexport const generateCanvasKey = (oldKey: number) => {\n let newKey: number;\n\n do {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n newKey = array[0];\n } while (newKey === oldKey);\n\n return newKey;\n};\n","/*\n * Copyright (c) 2017 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport * as PanoViewer from \"./PanoViewer\";\nimport * as SpinViewer from \"./SpinViewer\";\nimport * as CFC from \"./cfc\";\nimport { merge } from \"./utils/utils\";\n\nconst View360: any = {};\n\nmerge(View360, PanoViewer);\nmerge(View360, SpinViewer);\nmerge(View360, CFC);\n\nexport default View360;\n"],"names":["VERSION","win","window","Math","self","Function","doc","document","nav","navigator","agent","getAgent","osName","os","name","browserName","browser","IS_IOS","IS_SAFARI_ON_DESKTOP","Float32Array","Array","getComputedStyle","userAgent","SUPPORT_TOUCH","SUPPORT_DEVICEMOTION","DeviceMotionEvent","devicePixelRatio","TRANSFORM","docStyle","documentElement","style","target","i","len","length","SUPPORT_WILLCHANGE","CSS","supports","WEBXR_SUPPORTED","checkXRSupport","xr","isSessionSupported","then","res","catch","supportsSession","toDegree","a","PI","util","n","extractPitchFromQuat","quaternion","baseV","vec3","atan2","sqrt","pow","hypot","x","y","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","angleBetweenVec2","v1","v2","det","yawOffsetBetween","viewDir","targetDir","viewDirXZ","vec2","targetDirXZ","sign","Number","getRotationDelta","prevQ","curQ","rotateKind","prevQuaternion","quat","curQuaternion","prevPoint","curPoint","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","distance","abs","projectedPrevPoint","trigonometricRatio","theta","acos","crossVec","thetaDirection","version","branch","build","match","exec","parseInt","r","CHROME_VERSION","IS_CHROME_WITHOUT_DEVICE_MOTION","IS_ANDROID","test","MC_BIND_SCALE","GYRO_MODE","NONE","YAWPITCH","VR","MathUtil","degToRad","radToDeg","Vector2","prototype","constructor","set","this","copy","v","subVectors","b","Vector3","z","normalize","scalar","invScalar","multiplyScalar","applyQuaternion","q","qx","qy","qz","qw","w","ix","iy","iz","iw","dot","crossVectors","ax","ay","az","bx","by","bz","Quaternion","undefined","setFromEulerXYZ","c1","cos","c2","c3","s1","sin","s2","s3","setFromEulerYXZ","setFromAxisAngle","axis","angle","halfAngle","s","multiply","multiplyQuaternions","qax","qay","qaz","qaw","qbx","qby","qbz","qbw","inverse","l","slerp","qb","t","cosHalfTheta","halfTheta","sinHalfTheta","ratioA","ratioB","setFromUnitVectors","vFrom","vTo","isIOS","isWebViewAndroid","isSafari","isFirefoxAndroid","isR7","piOver180","rad45","defaultOrientation","defaultPosition","Util","updateEyeMatrices","projection","view","pose","parameters","vrDisplay","out","fov","fieldOfView","near","depthNear","far","depthFar","upTan","tan","upDegrees","downTan","downDegrees","leftTan","leftDegrees","rightTan","rightDegrees","xScale","yScale","a00","a01","a03","a10","a11","a12","a13","a20","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b04","b05","b07","b08","b09","b10","b11","orientation","position","xx","x2","xy","y2","xz","z2","yy","yz","zz","wx","wy","wz","offset","a02","a21","b06","MIN_TIMESTEP","MAX_TIMESTEP","base64","mimeType","clamp","value","min","max","lerp","platform","indexOf","isLandscapeMode","rtn","isTimestampDeltaValid","timestampDeltaS","isNaN","getScreenWidth","screen","width","height","getScreenHeight","requestFullscreen","element","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","exitFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","getFullscreenElement","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","linkProgram","gl","vertexSource","fragmentSource","attribLocationMap","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","attribName","program","createProgram","attachShader","bindAttribLocation","deleteShader","getProgramUniforms","uniforms","uniformCount","getProgramParameter","ACTIVE_UNIFORMS","uniformName","getActiveUniform","replace","getUniformLocation","orthoMatrix","left","right","bottom","top","lr","bt","nf","copyArray","source","dest","isMobile","check","vendor","opera","substr","extend","src","key","hasOwnProperty","safariCssSizeWorkaround","canvas","width_1","height_1","setTimeout","isDebug","getQueryParameter","results","RegExp","location","search","decodeURIComponent","frameDataFromPose","frameData","timestamp","leftProjectionMatrix","leftViewMatrix","getEyeParameters","rightProjectionMatrix","rightViewMatrix","isInsideCrossDomainIFrame","isFramed","refDomain","getDomainFromUrl","referrer","thisDomain","href","url","domain","split","predictionTimeS","previousQ","previousTimestampS","deltaQ","outQ","currentQ","gyro","timestampS","angularSpeed","console","log","toFixed","predictAngle","_super","_this","_onDeviceMotion","bind","_onDeviceOrientation","_onChromeWithoutDeviceMotion","isWithoutDeviceMotion","isAndroid","stillGyroVec","rawGyroVec","adjustedGyroVec","_timer","lastDevicemotionTimestamp","_isEnabled","enable","__extends","addEventListener","removeEventListener","e","alpha","beta","gamma","trigger","ComponentEvent","inputEvent","deviceorientation","clearTimeout","Date","getTime","devicemotionEvent","isGyroSensorAvailable","rotationRate","isGravitySensorAvailable","accelerationIncludingGravity","interval","__assign","timeStamp","type","acceleration","adjustedRotationRate","Component","sample","sensorSample","kFilter","vector","currentGyroMeasurement","deltaT","previousGyroMeasurement","run_","currentAccelMeasurement","SensorSample","filterQ","previousFilterQ","accelQ","isOrientationInitialized","estimatedGravity","measuredGravity","gyroIntegralQ","accelToQuaternion_","gyroDeltaQ","gyroToQuaternionDelta_","invFilterQ","getQuaternionAngle","targetQ","accel","normAccel","dt","ComplementaryFilter","isFilterQuaternionInitialized","getOrientation","deviceMotion","DeviceMotion","accelerometer","gyroscope","_onDeviceMotionChange","_onScreenOrientationChange","filter","posePredictor","PosePredictor","filterToWorldQ","isChromeUsingDegrees","inverseWorldToScreenQ","worldToScreenQ","originalPoseAdjustQ","_setScreenTransform","resetQ","on","isEnabled","disable","_deviceOrientationQ","deviceOrientationFixQ","_alpha","outQuat","_convertFusionToPredicted","_prevOrientation","predictedQ","getPrediction","_a","accGravity","rotRate","_triggerChange","addAccelMeasurement","addGyroMeasurement","el","options","_prevQuaternion","_quaternion","fusionPoseSensor","scale","threshold","_onPoseChange","axes","observer","FusionPoseSensor","_attachEvent","_dettachEvent","destroy","disconnect","event","prvQ","change","yawDeltaByYaw","reduce","acc","off","screenRotationAngleInst","refCount","_onOrientationChange","_spinR","_screenOrientationAngle","glMatrix","betaR","gammaR","_useRotation","_screenRotationAngle","setUseRotation","useRotation","_userDirection","Axes","DIRECTION_ALL","unref","ScreenRotationAngle","_direction","DIRECTION_HORIZONTAL","connect","properties","useDirection","_getOffset","newOffset","getRadian","cosTheta","sinTheta","DIRECTION_VERTICAL","PanInput","Y_AXIS_VECTOR","_fusionPoseSensor","isTrusted","yaw","yawQ","conj","DEFAULT_YAW_RANGE","DEFAULT_PITCH_RANGE","CIRCULAR_PITCH_RANGE","opt","pitch","showPolePoint","useZoom","useKeyboard","gyroMode","touchDirection","TOUCH_DIRECTION_YAW","yawRange","pitchRange","fovRange","aspectRatio","_element","_initialFov","_enabled","_isAnimating","_deviceQuaternion","_initAxes","option","param","_axes","get","areaHeight","_axesPanInput","deceleration","newValue","_getOptions","newOptions","changedKeyList","push","Object","keys","_setOptions","_getValidatedOptions","_applyOptions","updatePanScale","persistOrientation","_resetOrientation","duration","pos","p","f","maximumDuration","Infinity","setBy","yawPitch","getCombinedQuaternion","_axesWheelInput","_axesTiltMotionInput","_axesPinchInput","_axesMoveKeyInput","yRange","_updateYawRange","pRange","_updatePitchRange","RotationPanInput","WheelInput","PinchInput","MoveKeyInput","range","circular","_isCircular","bounce","hold","evt","delta","_updateControlScale","release","animationEnd","_getValidYawRange","_getValidPitchRange","arguments","prevFov","nextFov","isVR","isYawPitch","some","setTo","_initDeviceQuaternion","TiltMotionInput","_togglePinchInputByOption","_enableTouch","_inputs","direction","yawEnabled","pitchEnabled","DeviceQuaternion","newYawRange","newFov","newAspectRatio","ratio","_adjustAspectRatio","horizontalFov","newPitchRange","changeEvt","verticalAngle","halfFov","concat","halfHorizontalFov","mathUtil","targetElement","input","inputRange","outputRange","rangeIdx","inputA","inputB","outputA","outputB","_lerp","fraction","YawPitchControl","ERROR_TYPE","INVALID_DEVICE","NO_WEBGL","FAIL_IMAGE_LOAD","FAIL_BIND_TEXTURE","INVALID_RESOURCE","RENDERING_CONTEXT_LOST","PANOVIEWER_EVENTS","READY","VIEW_CHANGE","ANIMATION_END","ERROR","PROJECTION_TYPE","EQUIRECTANGULAR","CUBEMAP","CUBESTRIP","PANORAMA","STEREOSCOPIC_EQUI","STEREO_FORMAT","TOP_BOTTOM","LEFT_RIGHT","DEFAULT_CANVAS_CLASS","merge","_i","srcs","forEach","isArray","appendSourceElement","video","videoUrl","videoSrc","videoType","sourceElement","createElement","appendChild","WEBGL_ERROR_CODE","webglAvailability","WebGLUtils","shader","getShaderParameter","COMPILE_STATUS","error","getShaderInfoLog","LINK_STATUS","deleteProgram","data","itemSize","attr","buffer","createBuffer","bindBuffer","bufferData","STATIC_DRAW","numItems","enableVertexAttribArray","vertexAttribPointer","FLOAT","userContextAttributes","context","contextAttributes","preserveDrawingBuffer","antialias","onWebglcontextcreationerror","statusMessage","webglIdentifiers_1","__values","identifier","getContext","textureTarget","texture","createTexture","bindTexture","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","loseContextExtension","webglContext","getWebglContext","getExtension","loseContext","agentInfo","isStableWebgl","parseFloat","code","pixels","texImage2D","RGBA","UNSIGNED_BYTE","getParameter","MAX_TEXTURE_SIZE","isIE11","majorVersion","EVENTS","_forceDimension","_pixelCanvas","_pixelContext","shaderProgram","indexBuffer","mvMatrix","pMatrix","uniformMatrix4fv","pMatrixUniform","mvMatrixUniform","drawElements","TRIANGLES","UNSIGNED_SHORT","pixelSource","naturalWidth","videoWidth","naturalHeight","videoHeight","image","forceDimension","HTMLVideoElement","getDimension","contentDimension","textureDimension","drawImage","imageConfig","tileConfig","map","config","flipHorizontal","rotation","message","Renderer","CubeRenderer","order","_VERTEX_POSITION_DATA","_INDEX_DATA","indexData","vertexPositionData","getVertexPositionData","extractOrder","base","_extractTileConfig","trim","face","floor","ordermap","shift","unshift","pop","tileVertex","slice","elemSize","tileTemp","j","splice","coord","_shrinkCoord","faceCoords","val","coords","orderMap","surfaceIdx","tileIdx","TEXTURE_CUBE_MAP_POSITIVE_X","maxCubeMapTextureSize","getMaxCubeMapTextureSize","tile","extractTileFromImage","_triggerError","TEXTURE_CUBE_MAP","updateTexture","inputTextureSize","outputTextureSize","getSourceTileSize","tilePerRow","MAX_CUBE_MAP_TEXTURE_SIZE","imageWidth","isPowerOfTwo","coordData","SHRINK_MULTIPLIER","axisMultipliers","axisIndex","axisDir","notSameDir","_vertices","textureSize","rows","c","tileConfigs","_transformCoord","index","TEXTURE_2D","_getPixelSource","size","maxSize","getMaxTextureSize","_initPixelSource","activeTexture","TEXTURE0","pixelStorei","UNPACK_FLIP_Y_WEBGL","newCoord","_flipHorizontalCoord","_rotateCoord","SHRINK_Y","SHRINK_X","rotationAngle","moved","shiftCount","ANGLE_CORRECTION_FOR_CENTER_ALIGN","textureCoordData","latIdx","lngIdx","phi","sinPhi","u","format","_stereoFormat","ctx","leftEyeScaleOffset","rightEyeScaleOffset","uTexScaleOffset","uniform4fv","render","SphereRenderer","_TEXTURE_COORD_DATA","CylinderRenderer","resizeDimension","rotated","cylinderMaxRadian","_b","imageAspectRatio","halfCylinderY","CYLIDER_Y","startAngleForCenterAlign","yIdx","yLength","VR_DISPLAY_PRESENT_CHANGE","DEFAULT_LEFT_BOUNDS","DEFAULT_RIGHT_BOUNDS","EYES","_vrDisplay","removeEndCallback","isPresenting","exitPresent","_clear","_frameData","VRFrameData","Boolean","bindFramebuffer","FRAMEBUFFER","submitFrame","display","halfWidth","drawingBufferWidth","drawingBufferHeight","getFrameData","leftMVMatrix","rightMVMatrix","mat4","_yawOffset","viewport","callback","getVRDisplays","displays","capabilities","canPresent","requestPresent","leftEye","rightEye","renderWidth","renderHeight","_setDisplay","Promise","reject","Error","layers","getLayers","layer","_leftBounds","leftBounds","_rightBounds","rightBounds","addEndCallback","xrSession","_xrSession","end","_options","frame","getViewerPose","_xrRefSpace","baseLayer","session","renderState","framebuffer","glLayer","views","getViewport","transform","matrix","projectionMatrix","_presenting","requiredFeatures","attributes","getContextAttributes","xrCompatible","makeXRCompatible","requestSession","xrLayer","XRWebGLLayer","updateRenderState","requestReferenceSpace","refSpace","_setSession","_xrLayer","args","_callback","_rafId","_context","requestAnimationFrame","_onLoop","before","performance","now","diff","_rafTimer","_onLoopNextTick","cancelAnimationFrame","ImageType","DEVICE_PIXEL_RATIO","withMethods","component","vanillaInstance","proto","getOwnPropertyNames","startsWith","getterDescriptor","descriptor","getOwnPropertyDescriptor","defineProperty","call","BIND_TEXTURE","IMAGE_LOADED","RENDERING_CONTEXT_RESTORE","RENDERER_ERROR","isVideo","container","canvasClass","sphericalConfig","renderingContextAttributes","vr","_vr","animator","_animator","exitVR","_restoreStyle","updateViewportDimensions","_updateViewport","_bindBuffers","_shouldForceDraw","stop","setContext","setCallback","_render","start","time","eyeParams","getEyeParams","beforeRender","eyeIndex","eyeParam","uniform1f","uEye","_draw","afterRender","minusZDir","canRender","mat3","mvInv","pInv","yawOffset","setYawOffset","_renderStereo","_lastQuaternion","_lastYaw","_lastPitch","_lastFieldOfView","textureCoordBuffer","vertexBuffer","_initCanvas","_setDefaultCanvasStyle","_wrapper","_wrapperOrigStyle","_renderingContextAttributes","_image","_imageConfig","_imageIsReady","_keepUpdate","_onContentLoad","_onContentError","WebGLAnimator","setImage","imageType","cubemapConfig","yawPitchControl","_yawPitchControl","_isVideo","_setImageType","_contentLoader","ImReady","videoCandidate","video_1","setAttribute","querySelectorAll","readyState","load","toVideoElement","parsedImages","img","imgEl","Image","crossOrigin","toImageElement","rej","contentLoader","isReady","_bindTexture","once","errorCount","parentElement","_hasExternalCanvas","detach","hasRenderingContext","removeChild","forceContextLoss","_onWebglcontextlost","_onWebglcontextrestored","isContextLost","viewPortChanged","h","doUpdate","isImageLoaded","updateFieldOfView","_renderer","resolve","_requestPresent","_imageType","_isCubeMap","CubeStripRenderer","stereoFormat","_initWebGL","canvasInContainer","querySelector","_createCanvas","className","margin","maxHeight","maxWidth","outline","content","projectionType","_triggerContentLoad","renderer","vsSource","getVertexShaderSource","fsSource","getFragmentShaderSource","getErrorNameFromWebGLErrorCode","getError","useProgram","vertexPositionAttribute","getAttribLocation","samplerUniform","textureCoordAttribute","clear","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","STENCIL_BUFFER_BIT","uniform1i","preventDefault","_initRenderingContext","_initShaderProgram","clearColor","deleteTexture","CULL_FACE","WebGLRenderingContext","getIndexData","getTextureCoordData","initBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","Uint16Array","isEAC","updateShaderData","_initBuffers","getFov","shouldRenderWithQuaternion","getQuaternion","renderWithQuaternion","getYawPitch","renderWithYawPitch","_updateTexture","XRManager","VRManager","_onFirstVRFrame","_setWrapperFullscreen","wrapper","getAttribute","wrapperStyle","zIndex","removeAttribute","PanoImageRenderer","isWebGLAvailable","isStableWebGL","_container","_projectionType","_cubemapConfig","_width","_height","_yaw","_pitch","_fov","_gyroMode","_aspectRatio","_canvasClass","PanoViewer","_isValidTouchDirection","TOUCH_DIRECTION_ALL","yawPitchConfig","_isReady","_initYawPitchControl","_initRenderer","onDeviceMotionChange","race","fb","TOUCH_DIRECTION","YAW","PITCH","ALL","_photoSphereRenderer","getContent","warn","_deactivate","keepUpdate","requestPermission","permissionState","enableSensor","enterVR","containerSize","lookAt","verticalAngleOfImage","initialYaw","initialPitch","setYawPitchControl","_bindRendererHandler","_activate","yawSize","maxFov","minFov","ProjectionType","atan","attachTo","_updateYawPitchIfNeeded","startRender","getVideo","pause","stopRender","TOUCH_DIRECTION_NONE","TOUCH_DIRECTION_PITCH","DEFAULT_WRAPPER_CLASS","DEFAULT_IMAGE_CLASS","_el","_rowCount","rowCount","_colCount","colCount","_totalCount","_autoHeight","autoHeight","_colRow","colRow","frameIndex","setFrameIndex","SpriteImage","_getSizeString","wrapperClass","imageClass","imageUrl","imageInContainer","wrapperInContainer","onload","_bg","_createBgDiv","setColRow","bgElement","_autoPlayReservedInfo","play","onerror","overflow","ondragstart","willChange","unitWidth","unitHeight","paddingBottom","toColRow","col","row","_autoPlayTimer","clearInterval","count","frameCount","playCount","getFrameIndex","setInterval","_scale","_panScale","_frameCount","_sprites","_panInput","curr","getColRow","SpinViewer","LOAD","IMAGE_ERROR","CHANGE","isPropChanged","prevVal","updateOption","panoViewer","optionName","newProps","prevProps","toUpperCase","setVideo","propsObj","props","propName","oldKey","newKey","array","Uint32Array","crypto","getRandomValues","View360","CFC"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index a8d401546..3ebf6910f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@egjs/view360", - "version": "3.6.2-snapshot", + "version": "3.6.3", "description": "360 integrated viewing solution from inside-out view to outside-in view. It provides user-friendly service by rotating 360 degrees through various user interaction such as motion sensor and touch.", "main": "dist/view360.js", "module": "dist/view360.esm.js",