view360-canex
Version:
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.
1,746 lines (1,502 loc) • 504 kB
JavaScript
/*
Copyright (c) 2017 NAVER Corp.
name: view360-canex
license: MIT
author: Canex
repository: https://github.com/Can-ExploreInc/egjs-view360
version: 3.4.9
*/
(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';
/*! *****************************************************************************
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 __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: 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$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.");
}
/*
* Copyright (c) 2015 NAVER Corp.
* egjs projects are licensed under the MIT license
*/
function isUndefined(value) {
return typeof value === "undefined";
}
/**
* A class used to manage events in a component
* @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스
* @alias eg.Component
*/
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() {
/**
* @deprecated
* @private
*/
this.options = {};
this._eventHandler = {};
}
/**
* Triggers a custom event.
* @ko 커스텀 이벤트를 발생시킨다
* @param {string} eventName The name of the custom event to be triggered <ko>발생할 커스텀 이벤트의 이름</ko>
* @param {object} customEvent Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko>
* @param {any[]} restParam Additional parameters when triggering a custom event <ko>커스텀 이벤트가 발생할 때 필요시 추가적으로 전달할 데이터</ko>
* @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. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">Ref</a> <ko>이벤트 발생 여부. 커스텀 이벤트 핸들러에서 stop() 메서드를 호출하면 'false'를 반환하고 이벤트 발생을 중단한다. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">참고</a></ko>
* @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 <ko>등록할 이벤트의 이름</ko>
* @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
* @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
* @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(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 <ko>등록 여부를 확인할 이벤트의 이름</ko>
* @return {boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko>
* @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 <ko>등록할 이벤트의 이름</ko>
* @param {function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
* @return An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
* @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(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.
* @ko 컴포넌트에 등록된 이벤트를 해제한다
* @param {string} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko>
* @param {function} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko>
* @return An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko>
* @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(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);
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;
}();
/**
* @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(fn) {
if (!(this instanceof Promise))
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<!Function>} */
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._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) {
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._immediateFn(function() {
if (!self._handled) {
Promise._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.prototype['catch'] = function(onRejected) {
return this.then(null, onRejected);
};
Promise.prototype.then = function(onFulfilled, onRejected) {
// @ts-ignore
var prom = new this.constructor(noop);
handle(this, new Handler(onFulfilled, onRejected, prom));
return prom;
};
Promise.prototype['finally'] = finallyConstructor;
Promise.all = function(arr) {
return new Promise(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.allSettled = allSettled;
Promise.resolve = function(value) {
if (value && typeof value === 'object' && value.constructor === Promise) {
return value;
}
return new Promise(function(resolve) {
resolve(value);
});
};
Promise.reject = function(value) {
return new Promise(function(resolve, reject) {
reject(value);
});
};
Promise.race = function(arr) {
return new Promise(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.resolve(arr[i]).then(resolve, reject);
}
});
};
// Use polyfill for setImmediate for performance gains
Promise._immediateFn =
// @ts-ignore
(typeof setImmediate === 'function' &&
function(fn) {
// @ts-ignore
setImmediate(fn);
}) ||
function(fn) {
setTimeoutFunc(fn, 0);
};
Promise._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 <ko>파싱할 유저에이전트 문자열</ko>
* @return - agent Info <ko> 에이전트 정보 </ko>
* @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.
* egjs projects are licensed under the MIT license
*/
/* 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 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";
/**
* Copyright (c) 2015 NAVER Corp.
* egjs projects are licensed under the MIT license
*/
win.Float32Array = typeof win.Float32Array !== "undefined" ? win.Float32Array : win.Array;
var Float32Array$1 = win.Float32Array;
var getComputedStyle = win.getComputedStyle;
var userAgent = 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 docStyle = doc.documentElement.style;
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 () {}); // tslint:disable-line no-empty
} else if (navigator.xr.supportsSession) {
navigator.xr.supportsSession("immersive-vr").then(function (res) {
WEBXR_SUPPORTED = res;
}).catch(function () {}); // tslint:disable-line no-empty
}
};
/*! Hammer.JS - v2.0.17-rc - 2019-12-16
* http://naver.github.io/egjs
*
* Forked By Naver egjs
* Copyright (c) hammerjs
* Licensed under the MIT license */
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
/**
* @private
* extend object.
* means that properties in dest will be overwritten by the ones in src.
* @param {Object} target
* @param {...Object} objects_to_assign
* @returns {Object} target
*/
var assign;
if (typeof Object.assign !== 'function') {
assign = function assign(target) {
if (target === undefined || target === null) {
throw new TypeError('Cannot convert undefined or null to object');
}
var output = Object(target);
for (var index = 1; index < arguments.length; index++) {
var source = arguments[index];
if (source !== undefined && source !== null) {
for (var nextKey in source) {
if (source.hasOwnProperty(nextKey)) {
output[nextKey] = source[nextKey];
}
}
}
}
return output;
};
} else {
assign = Object.assign;
}
var assign$1 = assign;
var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
var TEST_ELEMENT = typeof document === "undefined" ? {
style: {}
} : document.createElement('div');
var TYPE_FUNCTION = 'function';
var round = Math.round,
abs = Math.abs;
var now = Date.now;
/**
* @private
* get the prefixed property
* @param {Object} obj
* @param {String} property
* @returns {String|Undefined} prefixed
*/
function prefixed(obj, property) {
var prefix;
var prop;
var camelProp = property[0].toUpperCase() + property.slice(1);
var i = 0;
while (i < VENDOR_PREFIXES.length) {
prefix = VENDOR_PREFIXES[i];
prop = prefix ? prefix + camelProp : property;
if (prop in obj) {
return prop;
}
i++;
}
return undefined;
}
/* eslint-disable no-new-func, no-nested-ternary */
var win$1;
if (typeof window === "undefined") {
// window is undefined in node.js
win$1 = {};
} else {
win$1 = window;
}
var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
function getTouchActionProps() {
if (!NATIVE_TOUCH_ACTION) {
return false;
}
var touchMap = {};
var cssSupports = win$1.CSS && win$1.CSS.supports;
['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
// If css.supports is not supported but there is native touch-action assume it supports
// all values. This is the case for IE 10 and 11.
return touchMap[val] = cssSupports ? win$1.CSS.supports('touch-action', val) : true;
});
return touchMap;
}
var TOUCH_ACTION_COMPUTE = 'compute';
var TOUCH_ACTION_AUTO = 'auto';
var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
var TOUCH_ACTION_NONE = 'none';
var TOUCH_ACTION_PAN_X = 'pan-x';
var TOUCH_ACTION_PAN_Y = 'pan-y';
var TOUCH_ACTION_MAP = getTouchActionProps();
var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
var SUPPORT_TOUCH$1 = 'ontouchstart' in win$1;
var SUPPORT_POINTER_EVENTS = prefixed(win$1, 'PointerEvent') !== undefined;
var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH$1 && MOBILE_REGEX.test(navigator.userAgent);
var INPUT_TYPE_TOUCH = 'touch';
var INPUT_TYPE_PEN = 'pen';
var INPUT_TYPE_MOUSE = 'mouse';
var INPUT_TYPE_KINECT = 'kinect';
var COMPUTE_INTERVAL = 25;
var INPUT_START = 1;
var INPUT_MOVE = 2;
var INPUT_END = 4;
var INPUT_CANCEL = 8;
var DIRECTION_NONE = 1;
var DIRECTION_LEFT = 2;
var DIRECTION_RIGHT = 4;
var DIRECTION_UP = 8;
var DIRECTION_DOWN = 16;
var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
var PROPS_XY = ['x', 'y'];
var PROPS_CLIENT_XY = ['clientX', 'clientY'];
/**
* @private
* walk objects and arrays
* @param {Object} obj
* @param {Function} iterator
* @param {Object} context
*/
function each(obj, iterator, context) {
var i;
if (!obj) {
return;
}
if (obj.forEach) {
obj.forEach(iterator, context);
} else if (obj.length !== undefined) {
i = 0;
while (i < obj.length) {
iterator.call(context, obj[i], i, obj);
i++;
}
} else {
for (i in obj) {
obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
}
}
}
/**
* @private
* let a boolean value also be a function that must return a boolean
* this first item in args will be used as the context
* @param {Boolean|Function} val
* @param {Array} [args]
* @returns {Boolean}
*/
function boolOrFn(val, args) {
if (typeof val === TYPE_FUNCTION) {
return val.apply(args ? args[0] || undefined : undefined, args);
}
return val;
}
/**
* @private
* small indexOf wrapper
* @param {String} str
* @param {String} find
* @returns {Boolean} found
*/
function inStr(str, find) {
return str.indexOf(find) > -1;
}
/**
* @private
* when the touchActions are collected they are not a valid value, so we need to clean things up. *
* @param {String} actions
* @returns {*}
*/
function cleanTouchActions(actions) {
// none
if (inStr(actions, TOUCH_ACTION_NONE)) {
return TOUCH_ACTION_NONE;
}
var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers
// for different directions, e.g. horizontal pan but vertical swipe?)
// we need none (as otherwise with pan-x pan-y combined none of these
// recognizers will work, since the browser would handle all panning
if (hasPanX && hasPanY) {
return TOUCH_ACTION_NONE;
} // pan-x OR pan-y
if (hasPanX || hasPanY) {
return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
} // manipulation
if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
return TOUCH_ACTION_MANIPULATION;
}
return TOUCH_ACTION_AUTO;
}
/**
* @private
* Touch Action
* sets the touchAction property or uses the js alternative
* @param {Manager} manager
* @param {String} value
* @constructor
*/
var TouchAction =
/*#__PURE__*/
function () {
function TouchAction(manager, value) {
this.manager = manager;
this.set(value);
}
/**
* @private
* set the touchAction value on the element or enable the polyfill
* @param {String} value
*/
var _proto = TouchAction.prototype;
_proto.set = function set(value) {
// find out the touch-action by the event handlers
if (value === TOUCH_ACTION_COMPUTE) {
value = this.compute();
}
if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
}
this.actions = value.toLowerCase().trim();
};
/**
* @private
* just re-set the touchAction value
*/
_proto.update = function update() {
this.set(this.manager.options.touchAction);
};
/**
* @private
* compute the value for the touchAction property based on the recognizer's settings
* @returns {String} value
*/
_proto.compute = function compute() {
var actions = [];
each(this.manager.recognizers, function (recognizer) {
if (boolOrFn(recognizer.options.enable, [recognizer])) {
actions = actions.concat(recognizer.getTouchAction());
}
});
return cleanTouchActions(actions.join(' '));
};
/**
* @private
* this method is called on each input cycle and provides the preventing of the browser behavior
* @param {Object} input
*/
_proto.preventDefaults = function preventDefaults(input) {
var srcEvent = input.srcEvent;
var direction = input.offsetDirection; // if the touch action did prevented once this session
if (this.manager.session.prevented) {
srcEvent.preventDefault();
return;
}
var actions = this.actions;
var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
if (hasNone) {
// do not prevent defaults if this is a tap gesture
var isTapPointer = input.pointers.length === 1;
var isTapMovement = input.distance < 2;
var isTapTouchTime = input.deltaTime < 250;
if (isTapPointer && isTapMovement && isTapTouchTime) {
return;
}
}
if (hasPanX && hasPanY) {
// `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
return;
}
if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) {
return this.preventSrc(srcEvent);
}
};
/**
* @private
* call preventDefault to prevent the browser's default behavior (scrolling in most cases)
* @param {Object} srcEvent
*/
_proto.preventSrc = function preventSrc(srcEvent) {
this.manager.session.prevented = true;
srcEvent.preventDefault();
};
return TouchAction;
}();
/**
* @private
* find if a node is in the given parent
* @method hasParent
* @param {HTMLElement} node
* @param {HTMLElement} parent
* @return {Boolean} found
*/
function hasParent(node, parent) {
while (node) {
if (node === parent) {
return true;
}
node = node.parentNode;
}
return false;
}
/**
* @private
* get the center of all the pointers
* @param {Array} pointers
* @return {Object} center contains `x` and `y` properties
*/
function getCenter(pointers) {
var pointersLength = pointers.length; // no need to loop when only one touch
if (pointersLength === 1) {
return {
x: round(pointers[0].clientX),
y: round(pointers[0].clientY)
};
}
var x = 0;
var y = 0;
var i = 0;
while (i < pointersLength) {
x += pointers[i].clientX;
y += pointers[i].clientY;
i++;
}
return {
x: round(x / pointersLength),
y: round(y / pointersLength)
};
}
/**
* @private
* create a simple clone from the input used for storage of firstInput and firstMultiple
* @param {Object} input
* @returns {Object} clonedInputData
*/
function simpleCloneInputData(input) {
// make a simple copy of the pointers because we will get a reference if we don't
// we only need clientXY for the calculations
var pointers = [];
var i = 0;
while (i < input.pointers.length) {
pointers[i] = {
clientX: round(input.pointers[i].clientX),
clientY: round(input.pointers[i].clientY)
};
i++;
}
return {
timeStamp: now(),
pointers: pointers,
center: getCenter(pointers),
deltaX: input.deltaX,
deltaY: input.deltaY
};
}
/**
* @private
* calculate the absolute distance between two points
* @param {Object} p1 {x, y}
* @param {Object} p2 {x, y}
* @param {Array} [props] containing x and y keys
* @return {Number} distance
*/
function getDistance(p1, p2, props) {
if (!props) {
props = PROPS_XY;
}
var x = p2[props[0]] - p1[props[0]];
var y = p2[props[1]] - p1[props[1]];
return Math.sqrt(x * x + y * y);
}
/**
* @private
* calculate the angle between two coordinates
* @param {Object} p1
* @param {Object} p2
* @param {Array} [props] containing x and y keys
* @return {Number} angle
*/
function getAngle(p1, p2, props) {
if (!props) {
props = PROPS_XY;
}
var x = p2[props[0]] - p1[props[0]];
var y = p2[props[1]] - p1[props[1]];
return Math.atan2(y, x) * 180 / Math.PI;
}
/**
* @private
* get the direction between two points
* @param {Number} x
* @param {Number} y
* @return {Number} direction
*/
function getDirection(x, y) {
if (x === y) {
return DIRECTION_NONE;
}
if (abs(x) >= abs(y)) {
return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
}
return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
}
function computeDeltaXY(session, input) {
var center = input.center; // let { offsetDelta:offset = {}, prevDelta = {}, prevInput = {} } = session;
// jscs throwing error on defalut destructured values and without defaults tests fail
var offset = session.offsetDelta || {};
var prevDelta = session.prevDelta || {};
var prevInput = session.prevInput || {};
if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
prevDelta = session.prevDelta = {
x: prevInput.deltaX || 0,
y: prevInput.deltaY || 0
};
offset = session.offsetDelta = {
x: center.x,
y: center.y
};
}
input.deltaX = prevDelta.x + (center.x - offset.x);
input.deltaY = prevDelta.y + (center.y - offset.y);
}
/**
* @private
* calculate the velocity between two points. unit is in px per ms.
* @param {Number} deltaTime
* @param {Number} x
* @param {Number} y
* @return {Object} velocity `x` and `y`
*/
function getVelocity(deltaTime, x, y) {
return {
x: x / deltaTime || 0,
y: y / deltaTime || 0
};
}
/**
* @private
* calculate the scale factor between two pointersets
* no scale is 1, and goes