uix-kit
Version:
A free web kits for fast web design and development, compatible with Bootstrap v5.
1,788 lines (1,480 loc) • 1.36 MB
JavaScript
/*!
* pixi.js - v5.2.0
* Compiled Wed, 06 Nov 2019 02:32:43 UTC
*
* pixi.js is licensed under the MIT License.
* http://www.opensource.org/licenses/mit-license
*/
var PIXI = (function (exports) {
'use strict';
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function commonjsRequire () {
throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');
}
function unwrapExports (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
function getCjsExportFromNamespace (n) {
return n && n['default'] || n;
}
var promise = createCommonjsModule(function (module, exports) {
(function(global){
//
// Check for native Promise and it has correct interface
//
var NativePromise = global['Promise'];
var nativePromiseSupported =
NativePromise &&
// Some of these methods are missing from
// Firefox/Chrome experimental implementations
'resolve' in NativePromise &&
'reject' in NativePromise &&
'all' in NativePromise &&
'race' in NativePromise &&
// Older version of the spec had a resolver object
// as the arg rather than a function
(function(){
var resolve;
new NativePromise(function(r){ resolve = r; });
return typeof resolve === 'function';
})();
//
// export if necessary
//
if ('object' !== 'undefined' && exports)
{
// node.js
exports.Promise = nativePromiseSupported ? NativePromise : Promise;
exports.Polyfill = Promise;
}
else
{
// AMD
if (typeof undefined == 'function' && undefined.amd)
{
undefined(function(){
return nativePromiseSupported ? NativePromise : Promise;
});
}
else
{
// in browser add to global
if (!nativePromiseSupported)
{ global['Promise'] = Promise; }
}
}
//
// Polyfill
//
var PENDING = 'pending';
var SEALED = 'sealed';
var FULFILLED = 'fulfilled';
var REJECTED = 'rejected';
var NOOP = function(){};
function isArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
// async calls
var asyncSetTimer = typeof setImmediate !== 'undefined' ? setImmediate : setTimeout;
var asyncQueue = [];
var asyncTimer;
function asyncFlush(){
// run promise callbacks
for (var i = 0; i < asyncQueue.length; i++)
{ asyncQueue[i][0](asyncQueue[i][1]); }
// reset async asyncQueue
asyncQueue = [];
asyncTimer = false;
}
function asyncCall(callback, arg){
asyncQueue.push([callback, arg]);
if (!asyncTimer)
{
asyncTimer = true;
asyncSetTimer(asyncFlush, 0);
}
}
function invokeResolver(resolver, promise) {
function resolvePromise(value) {
resolve(promise, value);
}
function rejectPromise(reason) {
reject(promise, reason);
}
try {
resolver(resolvePromise, rejectPromise);
} catch(e) {
rejectPromise(e);
}
}
function invokeCallback(subscriber){
var owner = subscriber.owner;
var settled = owner.state_;
var value = owner.data_;
var callback = subscriber[settled];
var promise = subscriber.then;
if (typeof callback === 'function')
{
settled = FULFILLED;
try {
value = callback(value);
} catch(e) {
reject(promise, e);
}
}
if (!handleThenable(promise, value))
{
if (settled === FULFILLED)
{ resolve(promise, value); }
if (settled === REJECTED)
{ reject(promise, value); }
}
}
function handleThenable(promise, value) {
var resolved;
try {
if (promise === value)
{ throw new TypeError('A promises callback cannot return that same promise.'); }
if (value && (typeof value === 'function' || typeof value === 'object'))
{
var then = value.then; // then should be retrived only once
if (typeof then === 'function')
{
then.call(value, function(val){
if (!resolved)
{
resolved = true;
if (value !== val)
{ resolve(promise, val); }
else
{ fulfill(promise, val); }
}
}, function(reason){
if (!resolved)
{
resolved = true;
reject(promise, reason);
}
});
return true;
}
}
} catch (e) {
if (!resolved)
{ reject(promise, e); }
return true;
}
return false;
}
function resolve(promise, value){
if (promise === value || !handleThenable(promise, value))
{ fulfill(promise, value); }
}
function fulfill(promise, value){
if (promise.state_ === PENDING)
{
promise.state_ = SEALED;
promise.data_ = value;
asyncCall(publishFulfillment, promise);
}
}
function reject(promise, reason){
if (promise.state_ === PENDING)
{
promise.state_ = SEALED;
promise.data_ = reason;
asyncCall(publishRejection, promise);
}
}
function publish(promise) {
var callbacks = promise.then_;
promise.then_ = undefined;
for (var i = 0; i < callbacks.length; i++) {
invokeCallback(callbacks[i]);
}
}
function publishFulfillment(promise){
promise.state_ = FULFILLED;
publish(promise);
}
function publishRejection(promise){
promise.state_ = REJECTED;
publish(promise);
}
/**
* @class
*/
function Promise(resolver){
if (typeof resolver !== 'function')
{ throw new TypeError('Promise constructor takes a function argument'); }
if (this instanceof Promise === false)
{ throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); }
this.then_ = [];
invokeResolver(resolver, this);
}
Promise.prototype = {
constructor: Promise,
state_: PENDING,
then_: null,
data_: undefined,
then: function(onFulfillment, onRejection){
var subscriber = {
owner: this,
then: new this.constructor(NOOP),
fulfilled: onFulfillment,
rejected: onRejection
};
if (this.state_ === FULFILLED || this.state_ === REJECTED)
{
// already resolved, call callback async
asyncCall(invokeCallback, subscriber);
}
else
{
// subscribe
this.then_.push(subscriber);
}
return subscriber.then;
},
'catch': function(onRejection) {
return this.then(null, onRejection);
}
};
Promise.all = function(promises){
var Class = this;
if (!isArray(promises))
{ throw new TypeError('You must pass an array to Promise.all().'); }
return new Class(function(resolve, reject){
var results = [];
var remaining = 0;
function resolver(index){
remaining++;
return function(value){
results[index] = value;
if (!--remaining)
{ resolve(results); }
};
}
for (var i = 0, promise; i < promises.length; i++)
{
promise = promises[i];
if (promise && typeof promise.then === 'function')
{ promise.then(resolver(i), reject); }
else
{ results[i] = promise; }
}
if (!remaining)
{ resolve(results); }
});
};
Promise.race = function(promises){
var Class = this;
if (!isArray(promises))
{ throw new TypeError('You must pass an array to Promise.race().'); }
return new Class(function(resolve, reject) {
for (var i = 0, promise; i < promises.length; i++)
{
promise = promises[i];
if (promise && typeof promise.then === 'function')
{ promise.then(resolve, reject); }
else
{ resolve(promise); }
}
});
};
Promise.resolve = function(value){
var Class = this;
if (value && typeof value === 'object' && value.constructor === Class)
{ return value; }
return new Class(function(resolve){
resolve(value);
});
};
Promise.reject = function(reason){
var Class = this;
return new Class(function(resolve, reject){
reject(reason);
});
};
})(typeof window != 'undefined' ? window : typeof commonjsGlobal != 'undefined' ? commonjsGlobal : typeof self != 'undefined' ? self : commonjsGlobal);
});
var promise_1 = promise.Promise;
var promise_2 = promise.Polyfill;
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
'use strict';
/* eslint-disable no-unused-vars */
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
function toObject(val) {
if (val === null || val === undefined) {
throw new TypeError('Object.assign cannot be called with null or undefined');
}
return Object(val);
}
function shouldUseNative() {
try {
if (!Object.assign) {
return false;
}
// Detect buggy property enumeration order in older V8 versions.
// https://bugs.chromium.org/p/v8/issues/detail?id=4118
var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
test1[5] = 'de';
if (Object.getOwnPropertyNames(test1)[0] === '5') {
return false;
}
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
var test2 = {};
for (var i = 0; i < 10; i++) {
test2['_' + String.fromCharCode(i)] = i;
}
var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
return test2[n];
});
if (order2.join('') !== '0123456789') {
return false;
}
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
var test3 = {};
'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
test3[letter] = letter;
});
if (Object.keys(Object.assign({}, test3)).join('') !==
'abcdefghijklmnopqrst') {
return false;
}
return true;
} catch (err) {
// We don't expect any of the above to throw, but better to be safe.
return false;
}
}
var objectAssign = shouldUseNative() ? Object.assign : function (target, source) {
var arguments$1 = arguments;
var from;
var to = toObject(target);
var symbols;
for (var s = 1; s < arguments.length; s++) {
from = Object(arguments$1[s]);
for (var key in from) {
if (hasOwnProperty.call(from, key)) {
to[key] = from[key];
}
}
if (getOwnPropertySymbols) {
symbols = getOwnPropertySymbols(from);
for (var i = 0; i < symbols.length; i++) {
if (propIsEnumerable.call(from, symbols[i])) {
to[symbols[i]] = from[symbols[i]];
}
}
}
}
return to;
};
/*!
* @pixi/polyfill - v5.2.0
* Compiled Wed, 06 Nov 2019 02:32:43 UTC
*
* @pixi/polyfill is licensed under the MIT License.
* http://www.opensource.org/licenses/mit-license
*/
// Support for IE 9 - 11 which does not include Promises
if (!window.Promise)
{
window.Promise = promise_2;
}
// References:
if (!Object.assign)
{
Object.assign = objectAssign;
}
var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
// References:
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// https://gist.github.com/1579671
// http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision
// https://gist.github.com/timhall/4078614
// https://github.com/Financial-Times/polyfill-service/tree/master/polyfills/requestAnimationFrame
// Expected to be used with Browserfiy
// Browserify automatically detects the use of `global` and passes the
// correct reference of `global`, `self`, and finally `window`
var ONE_FRAME_TIME = 16;
// Date.now
if (!(Date.now && Date.prototype.getTime))
{
Date.now = function now()
{
return new Date().getTime();
};
}
// performance.now
if (!(commonjsGlobal$1.performance && commonjsGlobal$1.performance.now))
{
var startTime = Date.now();
if (!commonjsGlobal$1.performance)
{
commonjsGlobal$1.performance = {};
}
commonjsGlobal$1.performance.now = function () { return Date.now() - startTime; };
}
// requestAnimationFrame
var lastTime = Date.now();
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !commonjsGlobal$1.requestAnimationFrame; ++x)
{
var p = vendors[x];
commonjsGlobal$1.requestAnimationFrame = commonjsGlobal$1[(p + "RequestAnimationFrame")];
commonjsGlobal$1.cancelAnimationFrame = commonjsGlobal$1[(p + "CancelAnimationFrame")] || commonjsGlobal$1[(p + "CancelRequestAnimationFrame")];
}
if (!commonjsGlobal$1.requestAnimationFrame)
{
commonjsGlobal$1.requestAnimationFrame = function (callback) {
if (typeof callback !== 'function')
{
throw new TypeError((callback + "is not a function"));
}
var currentTime = Date.now();
var delay = ONE_FRAME_TIME + lastTime - currentTime;
if (delay < 0)
{
delay = 0;
}
lastTime = currentTime;
return setTimeout(function () {
lastTime = Date.now();
callback(performance.now());
}, delay);
};
}
if (!commonjsGlobal$1.cancelAnimationFrame)
{
commonjsGlobal$1.cancelAnimationFrame = function (id) { return clearTimeout(id); };
}
// References:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
if (!Math.sign)
{
Math.sign = function mathSign(x)
{
x = Number(x);
if (x === 0 || isNaN(x))
{
return x;
}
return x > 0 ? 1 : -1;
};
}
// References:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
if (!Number.isInteger)
{
Number.isInteger = function numberIsInteger(value)
{
return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
};
}
if (!window.ArrayBuffer)
{
window.ArrayBuffer = Array;
}
if (!window.Float32Array)
{
window.Float32Array = Array;
}
if (!window.Uint32Array)
{
window.Uint32Array = Array;
}
if (!window.Uint16Array)
{
window.Uint16Array = Array;
}
if (!window.Uint8Array)
{
window.Uint8Array = Array;
}
if (!window.Int32Array)
{
window.Int32Array = Array;
}
var isMobile_min = createCommonjsModule(function (module) {
!function(e){var n=/iPhone/i,t=/iPod/i,r=/iPad/i,a=/\bAndroid(?:.+)Mobile\b/i,p=/Android/i,b=/\bAndroid(?:.+)SD4930UR\b/i,l=/\bAndroid(?:.+)(?:KF[A-Z]{2,4})\b/i,f=/Windows Phone/i,s=/\bWindows(?:.+)ARM\b/i,u=/BlackBerry/i,c=/BB10/i,h=/Opera Mini/i,v=/\b(CriOS|Chrome)(?:.+)Mobile/i,w=/Mobile(?:.+)Firefox\b/i;function m(e,i){return e.test(i)}function i(e){var i=e||("undefined"!=typeof navigator?navigator.userAgent:""),o=i.split("[FBAN");void 0!==o[1]&&(i=o[0]),void 0!==(o=i.split("Twitter"))[1]&&(i=o[0]);var d={apple:{phone:m(n,i)&&!m(f,i),ipod:m(t,i),tablet:!m(n,i)&&m(r,i)&&!m(f,i),device:(m(n,i)||m(t,i)||m(r,i))&&!m(f,i)},amazon:{phone:m(b,i),tablet:!m(b,i)&&m(l,i),device:m(b,i)||m(l,i)},android:{phone:!m(f,i)&&m(b,i)||!m(f,i)&&m(a,i),tablet:!m(f,i)&&!m(b,i)&&!m(a,i)&&(m(l,i)||m(p,i)),device:!m(f,i)&&(m(b,i)||m(l,i)||m(a,i)||m(p,i))||m(/\bokhttp\b/i,i)},windows:{phone:m(f,i),tablet:m(s,i),device:m(f,i)||m(s,i)},other:{blackberry:m(u,i),blackberry10:m(c,i),opera:m(h,i),firefox:m(w,i),chrome:m(v,i),device:m(u,i)||m(c,i)||m(h,i)||m(w,i)||m(v,i)}};return d.any=d.apple.device||d.android.device||d.windows.device||d.other.device,d.phone=d.apple.phone||d.android.phone||d.windows.phone,d.tablet=d.apple.tablet||d.android.tablet||d.windows.tablet,d}"undefined"!='object'&&module.exports&&"undefined"==typeof window?module.exports=i:"undefined"!='object'&&module.exports&&"undefined"!=typeof window?(module.exports=i(),module.exports.isMobile=i):"function"==typeof undefined&&undefined.amd?undefined([],e.isMobile=i()):e.isMobile=i();}(commonjsGlobal);
});
var isMobile_min_1 = isMobile_min.isMobile;
/*!
* @pixi/settings - v5.2.0
* Compiled Wed, 06 Nov 2019 02:32:43 UTC
*
* @pixi/settings is licensed under the MIT License.
* http://www.opensource.org/licenses/mit-license
*/
/**
* The maximum recommended texture units to use.
* In theory the bigger the better, and for desktop we'll use as many as we can.
* But some mobile devices slow down if there is to many branches in the shader.
* So in practice there seems to be a sweet spot size that varies depending on the device.
*
* In v4, all mobile devices were limited to 4 texture units because for this.
* In v5, we allow all texture units to be used on modern Apple or Android devices.
*
* @private
* @param {number} max
* @returns {number}
*/
function maxRecommendedTextures(max)
{
var allowMax = true;
if (isMobile_min.tablet || isMobile_min.phone)
{
allowMax = false;
if (isMobile_min.apple.device)
{
var match = (navigator.userAgent).match(/OS (\d+)_(\d+)?/);
if (match)
{
var majorVersion = parseInt(match[1], 10);
// All texture units can be used on devices that support ios 11 or above
if (majorVersion >= 11)
{
allowMax = true;
}
}
}
if (isMobile_min.android.device)
{
var match$1 = (navigator.userAgent).match(/Android\s([0-9.]*)/);
if (match$1)
{
var majorVersion$1 = parseInt(match$1[1], 10);
// All texture units can be used on devices that support Android 7 (Nougat) or above
if (majorVersion$1 >= 7)
{
allowMax = true;
}
}
}
}
return allowMax ? max : 4;
}
/**
* Uploading the same buffer multiple times in a single frame can cause performance issues.
* Apparent on iOS so only check for that at the moment
* This check may become more complex if this issue pops up elsewhere.
*
* @private
* @returns {boolean}
*/
function canUploadSameBuffer()
{
return !isMobile_min.apple.device;
}
/**
* User's customizable globals for overriding the default PIXI settings, such
* as a renderer's default resolution, framerate, float precision, etc.
* @example
* // Use the native window resolution as the default resolution
* // will support high-density displays when rendering
* PIXI.settings.RESOLUTION = window.devicePixelRatio;
*
* // Disable interpolation when scaling, will make texture be pixelated
* PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
* @namespace PIXI.settings
*/
var settings = {
/**
* If set to true WebGL will attempt make textures mimpaped by default.
* Mipmapping will only succeed if the base texture uploaded has power of two dimensions.
*
* @static
* @name MIPMAP_TEXTURES
* @memberof PIXI.settings
* @type {PIXI.MIPMAP_MODES}
* @default PIXI.MIPMAP_MODES.POW2
*/
MIPMAP_TEXTURES: 1,
/**
* Default anisotropic filtering level of textures.
* Usually from 0 to 16
*
* @static
* @name ANISOTROPIC_LEVEL
* @memberof PIXI.settings
* @type {number}
* @default 0
*/
ANISOTROPIC_LEVEL: 0,
/**
* Default resolution / device pixel ratio of the renderer.
*
* @static
* @name RESOLUTION
* @memberof PIXI.settings
* @type {number}
* @default 1
*/
RESOLUTION: 1,
/**
* Default filter resolution.
*
* @static
* @name FILTER_RESOLUTION
* @memberof PIXI.settings
* @type {number}
* @default 1
*/
FILTER_RESOLUTION: 1,
/**
* The maximum textures that this device supports.
*
* @static
* @name SPRITE_MAX_TEXTURES
* @memberof PIXI.settings
* @type {number}
* @default 32
*/
SPRITE_MAX_TEXTURES: maxRecommendedTextures(32),
// TODO: maybe change to SPRITE.BATCH_SIZE: 2000
// TODO: maybe add PARTICLE.BATCH_SIZE: 15000
/**
* The default sprite batch size.
*
* The default aims to balance desktop and mobile devices.
*
* @static
* @name SPRITE_BATCH_SIZE
* @memberof PIXI.settings
* @type {number}
* @default 4096
*/
SPRITE_BATCH_SIZE: 4096,
/**
* The default render options if none are supplied to {@link PIXI.Renderer}
* or {@link PIXI.CanvasRenderer}.
*
* @static
* @name RENDER_OPTIONS
* @memberof PIXI.settings
* @type {object}
* @property {HTMLCanvasElement} view=null
* @property {number} resolution=1
* @property {boolean} antialias=false
* @property {boolean} forceFXAA=false
* @property {boolean} autoDensity=false
* @property {boolean} transparent=false
* @property {number} backgroundColor=0x000000
* @property {boolean} clearBeforeRender=true
* @property {boolean} preserveDrawingBuffer=false
* @property {number} width=800
* @property {number} height=600
* @property {boolean} legacy=false
*/
RENDER_OPTIONS: {
view: null,
antialias: false,
forceFXAA: false,
autoDensity: false,
transparent: false,
backgroundColor: 0x000000,
clearBeforeRender: true,
preserveDrawingBuffer: false,
width: 800,
height: 600,
legacy: false,
},
/**
* Default Garbage Collection mode.
*
* @static
* @name GC_MODE
* @memberof PIXI.settings
* @type {PIXI.GC_MODES}
* @default PIXI.GC_MODES.AUTO
*/
GC_MODE: 0,
/**
* Default Garbage Collection max idle.
*
* @static
* @name GC_MAX_IDLE
* @memberof PIXI.settings
* @type {number}
* @default 3600
*/
GC_MAX_IDLE: 60 * 60,
/**
* Default Garbage Collection maximum check count.
*
* @static
* @name GC_MAX_CHECK_COUNT
* @memberof PIXI.settings
* @type {number}
* @default 600
*/
GC_MAX_CHECK_COUNT: 60 * 10,
/**
* Default wrap modes that are supported by pixi.
*
* @static
* @name WRAP_MODE
* @memberof PIXI.settings
* @type {PIXI.WRAP_MODES}
* @default PIXI.WRAP_MODES.CLAMP
*/
WRAP_MODE: 33071,
/**
* Default scale mode for textures.
*
* @static
* @name SCALE_MODE
* @memberof PIXI.settings
* @type {PIXI.SCALE_MODES}
* @default PIXI.SCALE_MODES.LINEAR
*/
SCALE_MODE: 1,
/**
* Default specify float precision in vertex shader.
*
* @static
* @name PRECISION_VERTEX
* @memberof PIXI.settings
* @type {PIXI.PRECISION}
* @default PIXI.PRECISION.HIGH
*/
PRECISION_VERTEX: 'highp',
/**
* Default specify float precision in fragment shader.
* iOS is best set at highp due to https://github.com/pixijs/pixi.js/issues/3742
*
* @static
* @name PRECISION_FRAGMENT
* @memberof PIXI.settings
* @type {PIXI.PRECISION}
* @default PIXI.PRECISION.MEDIUM
*/
PRECISION_FRAGMENT: isMobile_min.apple.device ? 'highp' : 'mediump',
/**
* Can we upload the same buffer in a single frame?
*
* @static
* @name CAN_UPLOAD_SAME_BUFFER
* @memberof PIXI.settings
* @type {boolean}
*/
CAN_UPLOAD_SAME_BUFFER: canUploadSameBuffer(),
/**
* Enables bitmap creation before image load. This feature is experimental.
*
* @static
* @name CREATE_IMAGE_BITMAP
* @memberof PIXI.settings
* @type {boolean}
* @default false
*/
CREATE_IMAGE_BITMAP: false,
/**
* If true PixiJS will Math.floor() x/y values when rendering, stopping pixel interpolation.
* Advantages can include sharper image quality (like text) and faster rendering on canvas.
* The main disadvantage is movement of objects may appear less smooth.
*
* @static
* @constant
* @memberof PIXI.settings
* @type {boolean}
* @default false
*/
ROUND_PIXELS: false,
};
var eventemitter3 = createCommonjsModule(function (module) {
'use strict';
var has = Object.prototype.hasOwnProperty
, prefix = '~';
/**
* Constructor to create a storage for our `EE` objects.
* An `Events` instance is a plain object whose properties are event names.
*
* @constructor
* @private
*/
function Events() {}
//
// We try to not inherit from `Object.prototype`. In some engines creating an
// instance in this way is faster than calling `Object.create(null)` directly.
// If `Object.create(null)` is not supported we prefix the event names with a
// character to make sure that the built-in object properties are not
// overridden or used as an attack vector.
//
if (Object.create) {
Events.prototype = Object.create(null);
//
// This hack is needed because the `__proto__` property is still inherited in
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
//
if (!new Events().__proto__) { prefix = false; }
}
/**
* Representation of a single event listener.
*
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
* @constructor
* @private
*/
function EE(fn, context, once) {
this.fn = fn;
this.context = context;
this.once = once || false;
}
/**
* Add a listener for a given event.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} context The context to invoke the listener with.
* @param {Boolean} once Specify if the listener is a one-time listener.
* @returns {EventEmitter}
* @private
*/
function addListener(emitter, event, fn, context, once) {
if (typeof fn !== 'function') {
throw new TypeError('The listener must be a function');
}
var listener = new EE(fn, context || emitter, once)
, evt = prefix ? prefix + event : event;
if (!emitter._events[evt]) { emitter._events[evt] = listener, emitter._eventsCount++; }
else if (!emitter._events[evt].fn) { emitter._events[evt].push(listener); }
else { emitter._events[evt] = [emitter._events[evt], listener]; }
return emitter;
}
/**
* Clear event by name.
*
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
* @param {(String|Symbol)} evt The Event name.
* @private
*/
function clearEvent(emitter, evt) {
if (--emitter._eventsCount === 0) { emitter._events = new Events(); }
else { delete emitter._events[evt]; }
}
/**
* Minimal `EventEmitter` interface that is molded against the Node.js
* `EventEmitter` interface.
*
* @constructor
* @public
*/
function EventEmitter() {
this._events = new Events();
this._eventsCount = 0;
}
/**
* Return an array listing the events for which the emitter has registered
* listeners.
*
* @returns {Array}
* @public
*/
EventEmitter.prototype.eventNames = function eventNames() {
var names = []
, events
, name;
if (this._eventsCount === 0) { return names; }
for (name in (events = this._events)) {
if (has.call(events, name)) { names.push(prefix ? name.slice(1) : name); }
}
if (Object.getOwnPropertySymbols) {
return names.concat(Object.getOwnPropertySymbols(events));
}
return names;
};
/**
* Return the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Array} The registered listeners.
* @public
*/
EventEmitter.prototype.listeners = function listeners(event) {
var evt = prefix ? prefix + event : event
, handlers = this._events[evt];
if (!handlers) { return []; }
if (handlers.fn) { return [handlers.fn]; }
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
ee[i] = handlers[i].fn;
}
return ee;
};
/**
* Return the number of listeners listening to a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Number} The number of listeners.
* @public
*/
EventEmitter.prototype.listenerCount = function listenerCount(event) {
var evt = prefix ? prefix + event : event
, listeners = this._events[evt];
if (!listeners) { return 0; }
if (listeners.fn) { return 1; }
return listeners.length;
};
/**
* Calls each of the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Boolean} `true` if the event had listeners, else `false`.
* @public
*/
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
var arguments$1 = arguments;
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) { return false; }
var listeners = this._events[evt]
, len = arguments.length
, args
, i;
if (listeners.fn) {
if (listeners.once) { this.removeListener(event, listeners.fn, undefined, true); }
switch (len) {
case 1: return listeners.fn.call(listeners.context), true;
case 2: return listeners.fn.call(listeners.context, a1), true;
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
}
for (i = 1, args = new Array(len -1); i < len; i++) {
args[i - 1] = arguments$1[i];
}
listeners.fn.apply(listeners.context, args);
} else {
var length = listeners.length
, j;
for (i = 0; i < length; i++) {
if (listeners[i].once) { this.removeListener(event, listeners[i].fn, undefined, true); }
switch (len) {
case 1: listeners[i].fn.call(listeners[i].context); break;
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
default:
if (!args) { for (j = 1, args = new Array(len -1); j < len; j++) {
args[j - 1] = arguments$1[j];
} }
listeners[i].fn.apply(listeners[i].context, args);
}
}
}
return true;
};
/**
* Add a listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.on = function on(event, fn, context) {
return addListener(this, event, fn, context, false);
};
/**
* Add a one-time listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.once = function once(event, fn, context) {
return addListener(this, event, fn, context, true);
};
/**
* Remove the listeners of a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn Only remove the listeners that match this function.
* @param {*} context Only remove the listeners that have this context.
* @param {Boolean} once Only remove one-time listeners.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) { return this; }
if (!fn) {
clearEvent(this, evt);
return this;
}
var listeners = this._events[evt];
if (listeners.fn) {
if (
listeners.fn === fn &&
(!once || listeners.once) &&
(!context || listeners.context === context)
) {
clearEvent(this, evt);
}
} else {
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
if (
listeners[i].fn !== fn ||
(once && !listeners[i].once) ||
(context && listeners[i].context !== context)
) {
events.push(listeners[i]);
}
}
//
// Reset the array, or remove it completely if we have no more listeners.
//
if (events.length) { this._events[evt] = events.length === 1 ? events[0] : events; }
else { clearEvent(this, evt); }
}
return this;
};
/**
* Remove all listeners, or those of the specified event.
*
* @param {(String|Symbol)} [event] The event name.
* @returns {EventEmitter} `this`.
* @public
*/
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
var evt;
if (event) {
evt = prefix ? prefix + event : event;
if (this._events[evt]) { clearEvent(this, evt); }
} else {
this._events = new Events();
this._eventsCount = 0;
}
return this;
};
//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;
//
// Allow `EventEmitter` to be imported as module namespace.
//
EventEmitter.EventEmitter = EventEmitter;
//
// Expose the module.
//
if ('undefined' !== 'object') {
module.exports = EventEmitter;
}
});
'use strict';
var earcut_1 = earcut;
var default_1 = earcut;
function earcut(data, holeIndices, dim) {
dim = dim || 2;
var hasHoles = holeIndices && holeIndices.length,
outerLen = hasHoles ? holeIndices[0] * dim : data.length,
outerNode = linkedList(data, 0, outerLen, dim, true),
triangles = [];
if (!outerNode || outerNode.next === outerNode.prev) { return triangles; }
var minX, minY, maxX, maxY, x, y, invSize;
if (hasHoles) { outerNode = eliminateHoles(data, holeIndices, outerNode, dim); }
// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
if (data.length > 80 * dim) {
minX = maxX = data[0];
minY = maxY = data[1];
for (var i = dim; i < outerLen; i += dim) {
x = data[i];
y = data[i + 1];
if (x < minX) { minX = x; }
if (y < minY) { minY = y; }
if (x > maxX) { maxX = x; }
if (y > maxY) { maxY = y; }
}
// minX, minY and invSize are later used to transform coords into integers for z-order calculation
invSize = Math.max(maxX - minX, maxY - minY);
invSize = invSize !== 0 ? 1 / invSize : 0;
}
earcutLinked(outerNode, triangles, dim, minX, minY, invSize);
return triangles;
}
// create a circular doubly linked list from polygon points in the specified winding order
function linkedList(data, start, end, dim, clockwise) {
var i, last;
if (clockwise === (signedArea(data, start, end, dim) > 0)) {
for (i = start; i < end; i += dim) { last = insertNode(i, data[i], data[i + 1], last); }
} else {
for (i = end - dim; i >= start; i -= dim) { last = insertNode(i, data[i], data[i + 1], last); }
}
if (last && equals(last, last.next)) {
removeNode(last);
last = last.next;
}
return last;
}
// eliminate colinear or duplicate points
function filterPoints(start, end) {
if (!start) { return start; }
if (!end) { end = start; }
var p = start,
again;
do {
again = false;
if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
removeNode(p);
p = end = p.prev;
if (p === p.next) { break; }
again = true;
} else {
p = p.next;
}
} while (again || p !== end);
return end;
}
// main ear slicing loop which triangulates a polygon (given as a linked list)
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
if (!ear) { return; }
// interlink polygon nodes in z-order
if (!pass && invSize) { indexCurve(ear, minX, minY, invSize); }
var stop = ear,
prev, next;
// iterate through ears, slicing them one by one
while (ear.prev !== ear.next) {
prev = ear.prev;
next = ear.next;
if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
// cut off the triangle
triangles.push(prev.i / dim);
triangles.push(ear.i / dim);
triangles.push(next.i / dim);
removeNode(ear);
// skipping the next vertex leads to less sliver triangles
ear = next.next;
stop = next.next;
continue;
}
ear = next;
// if we looped through the whole remaining polygon and can't find any more ears
if (ear === stop) {
// try filtering points and slicing again
if (!pass) {
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
// if this didn't work, try curing all small self-intersections locally
} else if (pass === 1) {
ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
// as a last resort, try splitting the remaining polygon into two
} else if (pass === 2) {
splitEarcut(ear, triangles, dim, minX, minY, invSize);
}
break;
}
}
}
// check whether a polygon node forms a valid ear with adjacent nodes
function isEar(ear) {
var a = ear.prev,
b = ear,
c = ear.next;
if (area(a, b, c) >= 0) { return false; } // reflex, can't be an ear
// now make sure we don't have other points inside the potential ear
var p = ear.next.next;
while (p !== ear.prev) {
if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) { return false; }
p = p.next;
}
return true;
}
function isEarHashed(ear, minX, minY, invSize) {
var a = ear.prev,
b = ear,
c = ear.next;
if (area(a, b, c) >= 0) { return false; } // reflex, can't be an ear
// triangle bbox; min & max are calculated like this for speed
var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),
minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),
maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),
maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);
// z-order range for the current triangle bbox;
var minZ = zOrder(minTX, minTY, minX, minY, invSize),
maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);
var p = ear.prevZ,
n = ear.nextZ;
// look for points inside the triangle in both directions
while (p && p.z >= minZ && n && n.z <= maxZ) {
if (p !== ear.prev && p !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) { return false; }
p = p.prevZ;
if (n !== ear.prev && n !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&
area(n.prev, n, n.next) >= 0) { return false; }
n = n.nextZ;
}
// look for remaining points in decreasing z-order
while (p && p.z >= minZ) {
if (p !== ear.prev && p !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&
area(p.prev, p, p.next) >= 0) { return false; }
p = p.prevZ;
}
// look for remaining points in increasing z-order
while (n && n.z <= maxZ) {
if (n !== ear.prev && n !== ear.next &&
pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) &&
area(n.prev, n, n.next) >= 0) { return false; }
n = n.nextZ;
}
return true;
}
// go through all polygon nodes and cure small local self-intersections
function cureLocalIntersections(start, triangles, dim) {
var p = start;
do {
var a = p.prev,
b = p.next.next;
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
triangles.push(a.i / dim);
triangles.push(p.i / dim);
triangles.push(b.i / dim);
// remove two nodes involved
removeNode(p);
removeNode(p.next);
p = start = b;
}
p = p.next;
} while (p !== start);
return filterPoints(p);
}
// try splitting polygon into two and triangulate them independently
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
// look for a valid diagonal that divides the polygon into two
var a = start;
do {
var b = a.next.next;
while (b !== a.prev) {
if (a.i !== b.i && isValidDiagonal(a, b)) {
// split the polygon in two by the diagonal
var c = splitPolygon(a, b);
// filter colinear points around the cuts
a = filterPoints(a, a.next);
c = filterPoints(c, c.next);
// run earcut on each half
earcutLinked(a, triangles, dim, minX, minY, invSize);
earcutLinked(c, triangles, dim, minX, minY, invSize);
return;
}
b = b.next;
}
a = a.next;
} while (a !== start);
}
// link every hole into the outer loop, producing a single-ring polygon without holes
function eliminateHoles(data, holeIndices, outerNode, dim) {
var queue = [],
i, len, start, end, list;
for (i = 0, len = holeIndices.length; i < len; i++) {
start = holeIndices[i] * dim;
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
list = linkedList(data, start, end, dim, false);
if (list === list.next) { list.steiner = true; }
queue.push(getLeftmost(list));
}
queue.sort(compareX);
// process holes from left to right
for (i = 0; i < queue.length; i++) {
eliminateHole(queue[i], outerNode);
outerNode = filterPoints(outerNode, outerNode.next);
}
return outerNode;
}
function compareX(a, b) {
return a.x - b.x;
}
// find a bridge between vertices that connects hole with an outer ring and and link it
function eliminateHole(hole, outerNode) {
outerNode = findHoleBridge(hole, outerNode);
if (outerNode) {
var b = splitPolygon(outerNode, hole);
filterPoints(b, b.next);
}
}
// David Eberly's algorithm for finding a bridge between hole and outer polygon
function findHoleBridge(hole, outerNode) {
var p = outerNode,
hx = hole.x,
hy = hole.y,
qx = -Infinity,
m;
// find a segment intersected by a ray from the hole's leftmost point to the left;
// segment's endpoint with lesser x will be potential connection point
do {
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
if (x <= hx && x > qx) {
qx = x;
if (x === hx) {
if (hy === p.y) { return p; }
if (hy === p.next.y) { return p.next; }
}
m = p.x < p.next.x ? p : p.next;
}
}
p = p.next;
} while (p !== outerNode);
if (!m) { return null; }
if (hx === qx) { return m; } // hole touches outer segment; pick leftmost endpoint
// look for points inside the triangle of hole point, segment intersection and endpoint;
// if there are no points found, we have a valid connection;
// otherwise choose the point of the minimum angle with the ray as connection point
var stop = m,
mx = m.x,
my = m.y,
tanMin = Infinity,
tan;
p = m;
do {
if (hx >= p.x && p.x >= mx && hx !== p.x &&
pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
if (locallyInside(p, hole) &&
(tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {
m = p;
tanMin = tan;
}
}
p = p.next;
} while (p !== stop);
return m;
}
// whether sector in vertex m contains sector in vertex p in the same coordinates
function sectorContainsSector(m, p) {
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
}
// interlink polygon nodes in z-order
function indexCurve(start, minX, minY, invSize) {
var p = start;
do {
if (p.z === null) { p.z = zOrder(p.x, p.y, minX, minY, invSize); }
p.prevZ = p.prev;
p.nextZ = p.next;
p = p.next;
} while (p !== start);
p.prevZ.nextZ = null;
p.prevZ = null;
sortLinked(p);
}
// Simon Tatham's linked list merge sort algorithm
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
function sortLinked(list) {
var i, p, q, e, tail, numMerges, pSize, qSize,
inSize = 1;
do {
p = list;
list = null;
tail = null;
numMerges = 0;
while (p) {
numMerges++;
q = p;
pSize = 0;
for (i = 0; i < inSize; i++) {
pSize++;
q = q.nextZ;
if (!q) { break; }
}
qSize = inSize;
while (pSize > 0 || (qSize > 0 && q)) {
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
e = p;
p = p.nextZ;
pSize--;
} else {
e = q;
q = q.nextZ;
qSize--;
}
if (tail) { tail.nextZ = e; }
else { list = e; }
e.prevZ = tail;
tail = e;
}
p = q;
}
tail.nextZ = null;
inSize *= 2;
} while (numMerges > 1);
return list;
}
// z-order of a point given coords and inverse of the longer side of data bbox
function zOrder(x, y, minX, minY, invSize) {
// coords are transformed into non-negative 15-bit integer range
x = 32767 * (x - minX) * invSize;
y = 32767 * (y - minY) * invSize;
x = (x | (x << 8)) & 0x00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F;
x = (x | (x << 2)) & 0x33333333;
x = (x | (x << 1)) & 0x55555555;
y = (y | (y << 8)) & 0x00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F;
y = (y | (y << 2)) & 0x33333333;
y = (y | (y << 1)) & 0x55555555;
return x | (y << 1);
}
// find the leftmost node of a polygon ring
function getLeftmost(start) {
var p = start,
leftmost = start;
do {
if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) { leftmost = p; }
p = p.next;
} while (p !== start);
return leftmost;
}
// check if a point lies within a convex triangle
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
(ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
(bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
}
// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
function isValidDiagonal(a, b) {
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
(locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
(area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case
}
// signed area of a triangle
function area(p, q, r) {
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
}
// check if two points are equal
function equals(p1, p2) {
return p1.x === p2.x && p1.y === p2.y;
}
// check if two segments intersect
function intersects(p1, q1, p2, q2) {
var o1 = sign(area(p1, q1, p2));
var o2 = sign(area(p1, q1, q2));
var o3 = sign(area(p2, q2, p1));
var o4 = sign(area(p2, q2, q1));
if (o1 !== o2 && o3 !== o4) { return true; } // general case
if (o1 === 0 && onSegment(p1, p2, q1)) { return true; } // p1, q1 and p2 are collinear and p2 l