@frdr/amandes
Version:
A 360° media viewer for the modern web
1,374 lines (1,373 loc) • 407 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var __privateWrapper = (obj, member, setter, getter) => {
return {
set _(value) {
__privateSet(obj, member, value, setter);
},
get _() {
return __privateGet(obj, member, getter);
}
};
};
var __privateMethod = (obj, member, method) => {
__accessCheck(obj, member, "access private method");
return method;
};
var _queue, _delay, _paused, _currentTask, _lastFinished, _start, start_fn, _finish, finish_fn, _cancel, cancel_fn, _next, next_fn, _renderers, _widthProp, _heightProp, _element, _capacity, _buckets, _size, _stack, _visited, _vertices, _clear, clear_fn, _capacity2, _keys, _values, _start2, _size2, _fallbackOnly, _geometry, _width, _yaw, _pitch, _roll, _fov, _width2, _height, _projectionCenterX, _projectionCenterY, _limiter, _projMatrix, _invProjMatrix, _frustum, _projectionChanged, _params, _fovs, _tmpVec, _resetParams, resetParams_fn, _update, update_fn, _normalize, normalize_fn, _normalizeCoordinates, normalizeCoordinates_fn, _updateProjection, updateProjection_fn, _matrixToFrustum, matrixToFrustum_fn, _x, _y, _zoom, _mediaAspectRatio, _width3, _height2, _limiter2, _projMatrix2, _invProjMatrix2, _frustum2, _projectionChanged2, _params2, _vec, _resetParams2, resetParams_fn2, _update2, update_fn2, _zoomX, zoomX_fn, _zoomY, zoomY_fn, _updateProjection2, updateProjection_fn2, _concurrency, _paused2, _pool, _next2, _loadPool, _retryDelay, _retryMap, _sourceFromTile, _asset, _timestamp, _capacity3, _keyBuckets, _valBuckets, _size3, _capacity4, _elements, _start3, _size4, _index, index_fn, _id, _store, _tile, _asset2, _texture, _changeHandler, _cancel2, _source, _stage, _state, _delimCount, _itemMap, _visible, _previouslyVisible, _pinMap, _newVisible, _noLongerVisible, _visibleAgain, _evicted, _update3, update_fn3, _loadTile, loadTile_fn, _unloadTile, unloadTile_fn, _source2, _geometry2, _view, _textureStore, _effects, _fixedLevelIndex, _viewChangeHandler, _textureStoreChangeHandler, _selectLevel, selectLevel_fn, _stage2, _running, _rendering, _requestHandle, _boundLoop, _renderInvalidHandler, _loop, loop_fn, _keyCode, _parameter, _velocity, _friction, _element2, _keydownHandler, _keyupHandler, _blurHandler, _dynamics, _pressing, _handlePress, handlePress_fn, _handleRelease, handleRelease_fn, _handleBlur, handleBlur_fn, _managers, _refCount, _createManager, createManager_fn, _manager, _element3, _type, _hammerGestures, _eventHandlers, _element4, _opts, _startEvent, _lastEvent, _active, _dynamics2, _hammer, _handleHammerEvent, handleHammerEvent_fn, _handleStart, handleStart_fn, _handleMove, handleMove_fn, _handleEnd, handleEnd_fn, _updateDynamicsMove, updateDynamicsMove_fn, _updateDynamicsRelease, updateDynamicsRelease_fn, _element5, _opts2, _active2, _dynamics3, _hammer2, _handleStart2, handleStart_fn2, _handleMove2, handleMove_fn2, _handleRelease2, handleRelease_fn2, _updateDynamics, updateDynamics_fn, _element6, _opts3, _dynamics4, _eventList, _wheelListener, _lastEvent2, _active3, _dynamics5, _hammer3, _handleStart3, handleStart_fn3, _handleEnd2, handleEnd_fn2, _handleEvent, handleEvent_fn, _parameter2, _dynamics6, _element7, _pressHandler, _releaseHandler, _parameter3, _velocity2, _friction2, _dynamics7, _pressing2, _handlePress2, handlePress_fn2, _handleRelease3, handleRelease_fn3, _methods, _parameters, _now, _composedOffsets, _composeReturn, _indexOfInstance, indexOfInstance_fn, _updateDynamics2, updateDynamics_fn2, _resetComposedOffsets, resetComposedOffsets_fn, _methods2, _methodGroups, _composer, _enabled, _activeCount, _attachedRenderLoop, _beforeRenderHandler, _changeHandler2, _listen, listen_fn, _unlisten, unlisten_fn, _handleActive, handleActive_fn, _handleInactive, handleInactive_fn, _incrementActiveCount, incrementActiveCount_fn, _decrementActiveCount, decrementActiveCount_fn, _checkActiveCount, checkActiveCount_fn, _updateComposer, updateComposer_fn, _updateViewsWithControls, updateViewsWithControls_fn, _domElement, _parentDomElement, _view2, _coords, _perspective, _visible2, _position, _setEmbeddedPosition, setEmbeddedPosition_fn, _setPosition, setPosition_fn, _parentDomElement2, _stage3, _view3, _renderLoop, _hotspots, _visible3, _rect, _visibilityOrRectChanged, _stageWidth, _stageHeight, _tmpRect, _hotspotContainerWrapper, _hotspotContainer, _updateHandler, _update4, update_fn4, _viewer, _view4, _layers, _hotspotContainer2, _movement, _movementStartTime, _movementStep, _movementParams, _movementCallback, _updateMovementHandler, _updateHotspotContainerHandler, _viewChangeHandler2, _updateMovement, updateMovement_fn, _updateHotspotContainer, updateHotspotContainer_fn, _element8, _controls, _id2, _attached, _setActiveCursor, _setInactiveCursor, _setDisabledCursor, _setOriginalCursor, _updateAttachmentHandler, _updateAttachment, updateAttachment_fn, _attachToControlMethod, attachToControlMethod_fn, _detachFromControlMethod, detachFromControlMethod_fn, _setCursor, setCursor_fn, _domElement2, _stage4, _size5, _updateSizeListener, _renderLoop2, _controls2, _controlMethods, _dragCursor, _scenes, _currentScene, _replacedScene, _cancelCurrentTween, _layerChangeHandler, _viewChangeHandler3, _idleTimer, _resetIdleTimerHandler, _triggerIdleTimerHandler, _stopMovementHandler, _idleMovement, _updateSceneLayers, updateSceneLayers_fn, _addLayerToStage, addLayerToStage_fn, _removeLayerFromStage, removeLayerFromStage_fn, _addSceneEventListeners, addSceneEventListeners_fn, _removeSceneEventListeners, removeSceneEventListeners_fn, _resetIdleTimer, resetIdleTimer_fn, _triggerIdleTimer, triggerIdleTimer_fn;
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
function EventEmitter() {
}
EventEmitter.prototype.addEventListener = function(name, fn) {
var eventMap = this.__events = this.__events || {};
var handlerList = eventMap[name] = eventMap[name] || [];
if (handlerList.indexOf(fn) < 0) {
handlerList.push(fn);
}
};
EventEmitter.prototype.removeEventListener = function(name, fn) {
var eventMap = this.__events = this.__events || {};
var handlerList = eventMap[name];
if (handlerList) {
var index = handlerList.indexOf(fn);
if (index >= 0) {
handlerList.splice(index, 1);
}
}
};
EventEmitter.prototype.emit = function(name, var_args) {
var eventMap = this.__events = this.__events || {};
var handlerList = eventMap[name];
var args = Array.prototype.slice.call(arguments, 1);
if (handlerList) {
for (var i = 0; i < handlerList.length; i++) {
var fn = handlerList[i];
fn.apply(this, args);
}
}
};
function eventEmitter(ctor) {
for (var prop in EventEmitter.prototype) {
if (EventEmitter.prototype.hasOwnProperty(prop)) {
ctor.prototype[prop] = EventEmitter.prototype[prop];
}
}
}
var minimalEventEmitter = eventEmitter;
function getNow() {
if (typeof performance !== "undefined" && performance.now) {
return function performanceNow() {
return performance.now();
};
}
return function dateNow() {
return Date.now();
};
}
var now = getNow();
class WorkTask {
constructor(fn, cb) {
__publicField(this, "fn");
__publicField(this, "cb");
__publicField(this, "cfn");
this.fn = fn;
this.cb = cb;
this.cfn = null;
}
}
class WorkQueue {
constructor(opts) {
__privateAdd(this, _start);
__privateAdd(this, _finish);
__privateAdd(this, _cancel);
__privateAdd(this, _next);
__privateAdd(this, _queue, void 0);
__privateAdd(this, _delay, void 0);
__privateAdd(this, _paused, void 0);
__privateAdd(this, _currentTask, void 0);
__privateAdd(this, _lastFinished, void 0);
__privateSet(this, _queue, []);
__privateSet(this, _delay, opts && opts.delay || 0);
__privateSet(this, _paused, opts && !!opts.paused || false);
__privateSet(this, _currentTask, null);
__privateSet(this, _lastFinished, null);
}
length() {
return __privateGet(this, _queue).length;
}
push(fn, cb) {
const task = new WorkTask(fn, cb);
const cancel = __privateMethod(this, _cancel, cancel_fn).bind(this, task);
__privateGet(this, _queue).push(task);
__privateMethod(this, _next, next_fn).call(this);
return cancel;
}
pause() {
if (!__privateGet(this, _paused)) {
__privateSet(this, _paused, true);
}
}
resume() {
if (__privateGet(this, _paused)) {
__privateSet(this, _paused, false);
__privateMethod(this, _next, next_fn).call(this);
}
}
}
_queue = new WeakMap();
_delay = new WeakMap();
_paused = new WeakMap();
_currentTask = new WeakMap();
_lastFinished = new WeakMap();
_start = new WeakSet();
start_fn = function(task) {
if (__privateGet(this, _currentTask)) {
throw new Error("WorkQueue: called start while running task");
}
__privateSet(this, _currentTask, task);
const finish = __privateMethod(this, _finish, finish_fn).bind(this, task);
task.cfn = task.fn(finish);
if (typeof task.cfn !== "function") {
throw new Error("WorkQueue: function is not cancellable");
}
};
_finish = new WeakSet();
finish_fn = function(task) {
const args = Array.prototype.slice.call(arguments, 1);
if (__privateGet(this, _currentTask) !== task) {
throw new Error("WorkQueue: called finish on wrong task");
}
task.cb.apply(null, args);
__privateSet(this, _currentTask, null);
__privateSet(this, _lastFinished, now());
__privateMethod(this, _next, next_fn).call(this);
};
_cancel = new WeakSet();
cancel_fn = function(task) {
const args = Array.prototype.slice.call(arguments, 1);
if (__privateGet(this, _currentTask) === task) {
task.cfn.apply(null, args);
} else {
const pos = __privateGet(this, _queue).indexOf(task);
if (pos >= 0) {
__privateGet(this, _queue).splice(pos, 1);
task.cb.apply(null, args);
}
}
};
_next = new WeakSet();
next_fn = function() {
if (__privateGet(this, _paused)) {
return;
}
if (!__privateGet(this, _queue).length) {
return;
}
if (__privateGet(this, _currentTask)) {
return;
}
if (__privateGet(this, _lastFinished) != null) {
const elapsed = now() - __privateGet(this, _lastFinished);
const remaining = __privateGet(this, _delay) - elapsed;
if (remaining > 0) {
setTimeout(__privateMethod(this, _next, next_fn).bind(this), remaining);
return;
}
}
const task = __privateGet(this, _queue).shift();
__privateMethod(this, _start, start_fn).call(this, task);
};
function calcRect(totalWidth, totalHeight, spec, result) {
result = result || {};
let width;
if (spec != null && spec.absoluteWidth != null) {
width = spec.absoluteWidth / totalWidth;
} else if (spec != null && spec.relativeWidth != null) {
width = spec.relativeWidth;
} else {
width = 1;
}
let height;
if (spec && spec.absoluteHeight != null) {
height = spec.absoluteHeight / totalHeight;
} else if (spec != null && spec.relativeHeight != null) {
height = spec.relativeHeight;
} else {
height = 1;
}
let x;
if (spec != null && spec.absoluteX != null) {
x = spec.absoluteX / totalWidth;
} else if (spec != null && spec.relativeX != null) {
x = spec.relativeX;
} else {
x = 0;
}
let y;
if (spec != null && spec.absoluteY != null) {
y = spec.absoluteY / totalHeight;
} else if (spec != null && spec.relativeY != null) {
y = spec.relativeY;
} else {
y = 0;
}
result.x = x;
result.y = y;
result.width = width;
result.height = height;
return result;
}
function async(fn) {
return function asynced(done) {
var err, ret;
try {
ret = fn();
} catch (e) {
err = e;
} finally {
if (err) {
done(err);
} else {
done(null, ret);
}
}
};
}
function once(fn) {
let called = false;
let value;
return function onced(...args) {
if (!called) {
called = true;
value = fn(...args);
}
return value;
};
}
function cancelize(fn) {
return function cancelized() {
if (!arguments.length) {
throw new Error("cancelized: expected at least one argument");
}
var args = Array.prototype.slice.call(arguments, 0);
var done = args[args.length - 1] = once(args[args.length - 1]);
function cancel() {
done.apply(null, arguments);
}
fn.apply(null, args);
return cancel;
};
}
function clearOwnProperties(obj) {
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
obj[prop] = void 0;
}
}
}
class RendererRegistry {
constructor() {
__privateAdd(this, _renderers, void 0);
__privateSet(this, _renderers, {});
}
set(geometryType, viewType, Renderer) {
if (!__privateGet(this, _renderers)[geometryType]) {
__privateGet(this, _renderers)[geometryType] = {};
}
__privateGet(this, _renderers)[geometryType][viewType] = Renderer;
}
get(geometryType, viewType) {
const Renderer = __privateGet(this, _renderers)[geometryType] && __privateGet(this, _renderers)[geometryType][viewType];
return Renderer || null;
}
}
_renderers = new WeakMap();
function forwardTileCmp(t1, t2) {
return t1.cmp(t2);
}
function reverseTileCmp(t1, t2) {
return -t1.cmp(t2);
}
class Stage {
constructor(opts) {
__publicField(this, "_progressive");
__publicField(this, "_layers");
__publicField(this, "_renderers");
__publicField(this, "_tilesToLoad");
__publicField(this, "_tilesToRender");
__publicField(this, "_tmpVisible");
__publicField(this, "_tmpChildren");
__publicField(this, "_width");
__publicField(this, "_height");
__publicField(this, "_tmpRect");
__publicField(this, "_tmpSize");
__publicField(this, "_createTextureWorkQueue");
__publicField(this, "_rendererRegistry");
__publicField(this, "type", "stage");
__publicField(this, "TextureClass", null);
this._progressive = !!(opts && opts.progressive);
this._layers = [];
this._renderers = [];
this._tilesToLoad = [];
this._tilesToRender = [];
this._tmpVisible = [];
this._tmpChildren = [];
this._width = 0;
this._height = 0;
this._tmpRect = { x: 0, y: 0, width: 0, height: 0 };
this._tmpSize = { width: 0, height: 0 };
this._createTextureWorkQueue = new WorkQueue();
this._emitRenderInvalid = this._emitRenderInvalid.bind(this);
this._rendererRegistry = new RendererRegistry();
}
destroy() {
this.removeAllLayers();
clearOwnProperties(this);
}
registerRenderer(geometryType, viewType, Renderer2) {
return this._rendererRegistry.set(geometryType, viewType, Renderer2);
}
domElement() {
throw new Error("Stage implementation must override domElement");
}
width() {
return this._width;
}
height() {
return this._height;
}
size(size) {
size = size || { width: 0, height: 0 };
size.width = this._width;
size.height = this._height;
return size;
}
setSize(size) {
this._width = size.width;
this._height = size.height;
this.setSizeForType();
this.emit("resize");
this._emitRenderInvalid();
}
emit(_arg0, _arg1) {
throw new Error("Method not implemented.");
}
setSizeForType(_size6) {
throw new Error("Stage implementation must override setSizeForType");
}
loadImage(_url, _rect2, _cb) {
throw new Error("Stage implementation must override loadImage");
}
validateLayer(_layer) {
throw new Error("Stage implementation must override validateLayer");
}
listLayers() {
return [...this._layers];
}
hasLayer(layer) {
return this._layers.indexOf(layer) >= 0;
}
addLayer(layer, i) {
if (this._layers.indexOf(layer) >= 0) {
throw new Error("Layer already in stage");
}
if (i == null) {
i = this._layers.length;
}
if (i < 0 || i > this._layers.length) {
throw new Error("Invalid layer position");
}
this.validateLayer(layer);
var geometryType = layer.geometry().type;
var viewType = layer.view().type;
var rendererClass = this._rendererRegistry.get(geometryType, viewType);
if (!rendererClass) {
throw new Error("No " + this.type + " renderer avaiable for " + geometryType + " geometry and " + viewType + " view");
}
var renderer = this.createRenderer(rendererClass);
this._layers.splice(i, 0, layer);
this._renderers.splice(i, 0, renderer);
layer.addEventListener("viewChange", this._emitRenderInvalid);
layer.addEventListener("effectsChange", this._emitRenderInvalid);
layer.addEventListener("fixedLevelChange", this._emitRenderInvalid);
layer.addEventListener("textureStoreChange", this._emitRenderInvalid);
this._emitRenderInvalid();
}
createRenderer(_rendererClass) {
throw new Error("Method not implemented.");
}
moveLayer(layer, i) {
var index = this._layers.indexOf(layer);
if (index < 0) {
throw new Error("No such layer in stage");
}
if (i < 0 || i >= this._layers.length) {
throw new Error("Invalid layer position");
}
layer = this._layers.splice(index, 1)[0];
var renderer = this._renderers.splice(index, 1)[0];
this._layers.splice(i, 0, layer);
this._renderers.splice(i, 0, renderer);
this._emitRenderInvalid();
}
removeLayer(layer) {
var index = this._layers.indexOf(layer);
if (index < 0) {
throw new Error("No such layer in stage");
}
var removedLayer = this._layers.splice(index, 1)[0];
var renderer = this._renderers.splice(index, 1)[0];
this.destroyRenderer(renderer);
removedLayer.removeEventListener("viewChange", this._emitRenderInvalid);
removedLayer.removeEventListener("effectsChange", this._emitRenderInvalid);
removedLayer.removeEventListener("fixedLevelChange", this._emitRenderInvalid);
removedLayer.removeEventListener("textureStoreChange", this._emitRenderInvalid);
this._emitRenderInvalid();
}
destroyRenderer(_renderer) {
throw new Error("Method not implemented.");
}
removeAllLayers() {
while (this._layers.length > 0) {
this.removeLayer(this._layers[0]);
}
}
startFrame() {
throw new Error("Stage implementation must override startFrame");
}
endFrame() {
throw new Error("Stage implementation must override endFrame");
}
render() {
var i, j;
var tilesToLoad = this._tilesToLoad;
var tilesToRender = this._tilesToRender;
var stableStage = true;
var stableLayer;
var width = this._width;
var height = this._height;
var rect = this._tmpRect;
var size = this._tmpSize;
if (width <= 0 || height <= 0) {
return;
}
this.startFrame();
for (i = 0; i < this._layers.length; i++) {
this._layers[i].textureStore().startFrame();
}
for (i = 0; i < this._layers.length; i++) {
var layer = this._layers[i];
var effects = layer.effects();
var view = layer.view();
var textureStore = layer.textureStore();
var renderer = this._renderers[i];
var depth = this._layers.length - i;
var tile2, texture;
calcRect(width, height, effects == null ? void 0 : effects.rect, rect);
if (rect.width <= 0 || rect.height <= 0) {
continue;
}
size.width = rect.width * this._width;
size.height = rect.height * this._height;
view.setSize(size);
renderer.startLayer(layer, rect);
stableLayer = this._collectTiles(layer, textureStore);
for (j = 0; j < tilesToLoad.length; j++) {
tile2 = tilesToLoad[j];
textureStore.markTile(tile2);
}
for (j = 0; j < tilesToRender.length; j++) {
tile2 = tilesToRender[j];
texture = textureStore.texture(tile2);
renderer.renderTile(tile2, texture, layer, depth);
}
layer.emit("renderComplete", stableLayer);
if (!stableLayer) {
stableStage = false;
}
renderer.endLayer(layer, rect);
}
for (i = 0; i < this._layers.length; i++) {
this._layers[i].textureStore().endFrame();
}
this.endFrame();
this.emit("renderComplete", stableStage);
}
_collectTiles(layer, textureStore) {
var tilesToLoad = this._tilesToLoad;
var tilesToRender = this._tilesToRender;
var tmpVisible = this._tmpVisible;
tilesToLoad.length = 0;
tilesToRender.length = 0;
tmpVisible.length = 0;
layer.visibleTiles(tmpVisible);
var isStable = true;
for (var i = 0; i < tmpVisible.length; i++) {
var tile2 = tmpVisible[i];
var needsFallback;
this._collectTileToLoad(tile2);
if (textureStore.texture(tile2)) {
needsFallback = false;
this._collectTileToRender(tile2);
} else {
needsFallback = this._collectChildren(tile2, textureStore);
isStable = false;
}
this._collectParents(tile2, textureStore, needsFallback);
}
tilesToLoad.sort(forwardTileCmp);
tilesToRender.sort(reverseTileCmp);
return isStable;
}
_collectChildren(tile2, textureStore) {
var tmpChildren = this._tmpChildren;
var needsFallback = true;
do {
tmpChildren.length = 0;
if (!tile2.children(tmpChildren)) {
break;
}
needsFallback = false;
for (var i = 0; i < tmpChildren.length; i++) {
tile2 = tmpChildren[i];
if (textureStore.texture(tile2)) {
this._collectTileToLoad(tile2);
this._collectTileToRender(tile2);
} else {
needsFallback = true;
}
}
} while (needsFallback && tmpChildren.length === 1);
return needsFallback;
}
_collectParents(tile2, textureStore, needsFallback) {
var needsLoading = this._progressive;
while ((needsLoading || needsFallback) && (tile2 = tile2.parent()) != null) {
if (needsFallback) {
if (textureStore.texture(tile2)) {
this._collectTileToRender(tile2);
needsFallback = false;
} else if (!this._progressive) {
continue;
}
}
if (!this._collectTileToLoad(tile2)) {
needsLoading = false;
}
}
return needsFallback;
}
_collectTileToLoad(tile2) {
return this._collectTileIntoList(tile2, this._tilesToLoad);
}
_collectTileToRender(tile2) {
return this._collectTileIntoList(tile2, this._tilesToRender);
}
_collectTileIntoList(tile2, tileList) {
var found = false;
for (var i = 0; i < tileList.length; i++) {
if (tile2.equals(tileList[i])) {
found = true;
break;
}
}
if (!found) {
tileList.push(tile2);
}
return !found;
}
createTexture(tile2, asset, done) {
var self2 = this;
function makeTexture() {
if (self2.TextureClass) {
return new self2.TextureClass(self2, tile2, asset);
}
return null;
}
var fn = cancelize(async(makeTexture));
return this._createTextureWorkQueue.push(fn, function(err, texture) {
done(err, tile2, asset, texture);
});
}
_emitRenderInvalid() {
this.emit("renderInvalid");
}
}
minimalEventEmitter(Stage);
Stage.prototype._emitRenderInvalid = function() {
this.emit("renderInvalid");
};
const globalObject = function() {
if (typeof window !== "undefined") {
return window;
}
if (typeof self !== "undefined") {
return self;
}
if (typeof global !== "undefined") {
return global;
}
return null;
}();
const propertyMap = {
HTMLImageElement: ["naturalWidth", "naturalHeight"],
HTMLCanvasElement: ["width", "height"],
ImageBitmap: ["width", "height"]
};
class StaticAsset {
constructor(element) {
__privateAdd(this, _widthProp, void 0);
__privateAdd(this, _heightProp, void 0);
__privateAdd(this, _element, void 0);
let supported = false;
for (const type2 in propertyMap) {
if ((globalObject == null ? void 0 : globalObject[type2]) && element instanceof globalObject[type2]) {
supported = true;
__privateSet(this, _widthProp, propertyMap[type2][0]);
__privateSet(this, _heightProp, propertyMap[type2][1]);
break;
}
}
if (!supported) {
throw new Error("Unsupported pixel source");
}
__privateSet(this, _element, element);
}
destroy() {
clearOwnProperties(this);
}
element() {
return __privateGet(this, _element);
}
width() {
return __privateGet(this, _element)[__privateGet(this, _widthProp)];
}
height() {
return __privateGet(this, _element)[__privateGet(this, _heightProp)];
}
timestamp() {
return 0;
}
isDynamic() {
return false;
}
}
_widthProp = new WeakMap();
_heightProp = new WeakMap();
_element = new WeakMap();
minimalEventEmitter(StaticAsset);
class NetworkError extends Error {
constructor(...args) {
super(...args);
if (typeof args[0] === "string") {
this.message = args[0];
}
}
}
var bowser$1 = { exports: {} };
/*!
* Bowser - a browser detector
* https://github.com/ded/bowser
* MIT License | (c) Dustin Diaz 2015
*/
(function(module) {
!function(root, name, definition) {
if (module.exports)
module.exports = definition();
else
root[name] = definition();
}(commonjsGlobal, "bowser", function() {
var t = true;
function detect(ua) {
function getFirstMatch(regex) {
var match = ua.match(regex);
return match && match.length > 1 && match[1] || "";
}
function getSecondMatch(regex) {
var match = ua.match(regex);
return match && match.length > 1 && match[2] || "";
}
var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase(), likeAndroid = /like android/i.test(ua), android = !likeAndroid && /android/i.test(ua), nexusMobile = /nexus\s*[0-6]\s*/i.test(ua), nexusTablet = !nexusMobile && /nexus\s*[0-9]+/i.test(ua), chromeos = /CrOS/.test(ua), silk = /silk/i.test(ua), sailfish = /sailfish/i.test(ua), tizen = /tizen/i.test(ua), webos = /(web|hpw)(o|0)s/i.test(ua), windowsphone = /windows phone/i.test(ua);
/SamsungBrowser/i.test(ua);
var windows = !windowsphone && /windows/i.test(ua), mac = !iosdevice && !silk && /macintosh/i.test(ua), linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua), edgeVersion = getSecondMatch(/edg([ea]|ios)\/(\d+(\.\d+)?)/i), versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i), tablet = /tablet/i.test(ua) && !/tablet pc/i.test(ua), mobile = !tablet && /[^-]mobi/i.test(ua), xbox = /xbox/i.test(ua), result;
if (/opera/i.test(ua)) {
result = {
name: "Opera",
opera: t,
version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\s\/](\d+(\.\d+)?)/i)
};
} else if (/opr\/|opios/i.test(ua)) {
result = {
name: "Opera",
opera: t,
version: getFirstMatch(/(?:opr|opios)[\s\/](\d+(\.\d+)?)/i) || versionIdentifier
};
} else if (/SamsungBrowser/i.test(ua)) {
result = {
name: "Samsung Internet for Android",
samsungBrowser: t,
version: versionIdentifier || getFirstMatch(/(?:SamsungBrowser)[\s\/](\d+(\.\d+)?)/i)
};
} else if (/Whale/i.test(ua)) {
result = {
name: "NAVER Whale browser",
whale: t,
version: getFirstMatch(/(?:whale)[\s\/](\d+(?:\.\d+)+)/i)
};
} else if (/MZBrowser/i.test(ua)) {
result = {
name: "MZ Browser",
mzbrowser: t,
version: getFirstMatch(/(?:MZBrowser)[\s\/](\d+(?:\.\d+)+)/i)
};
} else if (/coast/i.test(ua)) {
result = {
name: "Opera Coast",
coast: t,
version: versionIdentifier || getFirstMatch(/(?:coast)[\s\/](\d+(\.\d+)?)/i)
};
} else if (/focus/i.test(ua)) {
result = {
name: "Focus",
focus: t,
version: getFirstMatch(/(?:focus)[\s\/](\d+(?:\.\d+)+)/i)
};
} else if (/yabrowser/i.test(ua)) {
result = {
name: "Yandex Browser",
yandexbrowser: t,
version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i)
};
} else if (/ucbrowser/i.test(ua)) {
result = {
name: "UC Browser",
ucbrowser: t,
version: getFirstMatch(/(?:ucbrowser)[\s\/](\d+(?:\.\d+)+)/i)
};
} else if (/mxios/i.test(ua)) {
result = {
name: "Maxthon",
maxthon: t,
version: getFirstMatch(/(?:mxios)[\s\/](\d+(?:\.\d+)+)/i)
};
} else if (/epiphany/i.test(ua)) {
result = {
name: "Epiphany",
epiphany: t,
version: getFirstMatch(/(?:epiphany)[\s\/](\d+(?:\.\d+)+)/i)
};
} else if (/puffin/i.test(ua)) {
result = {
name: "Puffin",
puffin: t,
version: getFirstMatch(/(?:puffin)[\s\/](\d+(?:\.\d+)?)/i)
};
} else if (/sleipnir/i.test(ua)) {
result = {
name: "Sleipnir",
sleipnir: t,
version: getFirstMatch(/(?:sleipnir)[\s\/](\d+(?:\.\d+)+)/i)
};
} else if (/k-meleon/i.test(ua)) {
result = {
name: "K-Meleon",
kMeleon: t,
version: getFirstMatch(/(?:k-meleon)[\s\/](\d+(?:\.\d+)+)/i)
};
} else if (windowsphone) {
result = {
name: "Windows Phone",
osname: "Windows Phone",
windowsphone: t
};
if (edgeVersion) {
result.msedge = t;
result.version = edgeVersion;
} else {
result.msie = t;
result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i);
}
} else if (/msie|trident/i.test(ua)) {
result = {
name: "Internet Explorer",
msie: t,
version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i)
};
} else if (chromeos) {
result = {
name: "Chrome",
osname: "Chrome OS",
chromeos: t,
chromeBook: t,
chrome: t,
version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
};
} else if (/edg([ea]|ios)/i.test(ua)) {
result = {
name: "Microsoft Edge",
msedge: t,
version: edgeVersion
};
} else if (/vivaldi/i.test(ua)) {
result = {
name: "Vivaldi",
vivaldi: t,
version: getFirstMatch(/vivaldi\/(\d+(\.\d+)?)/i) || versionIdentifier
};
} else if (sailfish) {
result = {
name: "Sailfish",
osname: "Sailfish OS",
sailfish: t,
version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i)
};
} else if (/seamonkey\//i.test(ua)) {
result = {
name: "SeaMonkey",
seamonkey: t,
version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i)
};
} else if (/firefox|iceweasel|fxios/i.test(ua)) {
result = {
name: "Firefox",
firefox: t,
version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.\d+)?)/i)
};
if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) {
result.firefoxos = t;
result.osname = "Firefox OS";
}
} else if (silk) {
result = {
name: "Amazon Silk",
silk: t,
version: getFirstMatch(/silk\/(\d+(\.\d+)?)/i)
};
} else if (/phantom/i.test(ua)) {
result = {
name: "PhantomJS",
phantom: t,
version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i)
};
} else if (/slimerjs/i.test(ua)) {
result = {
name: "SlimerJS",
slimer: t,
version: getFirstMatch(/slimerjs\/(\d+(\.\d+)?)/i)
};
} else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) {
result = {
name: "BlackBerry",
osname: "BlackBerry OS",
blackberry: t,
version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i)
};
} else if (webos) {
result = {
name: "WebOS",
osname: "WebOS",
webos: t,
version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)
};
/touchpad\//i.test(ua) && (result.touchpad = t);
} else if (/bada/i.test(ua)) {
result = {
name: "Bada",
osname: "Bada",
bada: t,
version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i)
};
} else if (tizen) {
result = {
name: "Tizen",
osname: "Tizen",
tizen: t,
version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier
};
} else if (/qupzilla/i.test(ua)) {
result = {
name: "QupZilla",
qupzilla: t,
version: getFirstMatch(/(?:qupzilla)[\s\/](\d+(?:\.\d+)+)/i) || versionIdentifier
};
} else if (/chromium/i.test(ua)) {
result = {
name: "Chromium",
chromium: t,
version: getFirstMatch(/(?:chromium)[\s\/](\d+(?:\.\d+)?)/i) || versionIdentifier
};
} else if (/chrome|crios|crmo/i.test(ua)) {
result = {
name: "Chrome",
chrome: t,
version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
};
} else if (android) {
result = {
name: "Android",
version: versionIdentifier
};
} else if (/safari|applewebkit/i.test(ua)) {
result = {
name: "Safari",
safari: t
};
if (versionIdentifier) {
result.version = versionIdentifier;
}
} else if (iosdevice) {
result = {
name: iosdevice == "iphone" ? "iPhone" : iosdevice == "ipad" ? "iPad" : "iPod"
};
if (versionIdentifier) {
result.version = versionIdentifier;
}
} else if (/googlebot/i.test(ua)) {
result = {
name: "Googlebot",
googlebot: t,
version: getFirstMatch(/googlebot\/(\d+(\.\d+))/i) || versionIdentifier
};
} else {
result = {
name: getFirstMatch(/^(.*)\/(.*) /),
version: getSecondMatch(/^(.*)\/(.*) /)
};
}
if (!result.msedge && /(apple)?webkit/i.test(ua)) {
if (/(apple)?webkit\/537\.36/i.test(ua)) {
result.name = result.name || "Blink";
result.blink = t;
} else {
result.name = result.name || "Webkit";
result.webkit = t;
}
if (!result.version && versionIdentifier) {
result.version = versionIdentifier;
}
} else if (!result.opera && /gecko\//i.test(ua)) {
result.name = result.name || "Gecko";
result.gecko = t;
result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i);
}
if (!result.windowsphone && (android || result.silk)) {
result.android = t;
result.osname = "Android";
} else if (!result.windowsphone && iosdevice) {
result[iosdevice] = t;
result.ios = t;
result.osname = "iOS";
} else if (mac) {
result.mac = t;
result.osname = "macOS";
} else if (xbox) {
result.xbox = t;
result.osname = "Xbox";
} else if (windows) {
result.windows = t;
result.osname = "Windows";
} else if (linux) {
result.linux = t;
result.osname = "Linux";
}
function getWindowsVersion(s) {
switch (s) {
case "NT":
return "NT";
case "XP":
return "XP";
case "NT 5.0":
return "2000";
case "NT 5.1":
return "XP";
case "NT 5.2":
return "2003";
case "NT 6.0":
return "Vista";
case "NT 6.1":
return "7";
case "NT 6.2":
return "8";
case "NT 6.3":
return "8.1";
case "NT 10.0":
return "10";
default:
return void 0;
}
}
var osVersion = "";
if (result.windows) {
osVersion = getWindowsVersion(getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i));
} else if (result.windowsphone) {
osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
} else if (result.mac) {
osVersion = getFirstMatch(/Mac OS X (\d+([_\.\s]\d+)*)/i);
osVersion = osVersion.replace(/[_\s]/g, ".");
} else if (iosdevice) {
osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i);
osVersion = osVersion.replace(/[_\s]/g, ".");
} else if (android) {
osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i);
} else if (result.webos) {
osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i);
} else if (result.blackberry) {
osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i);
} else if (result.bada) {
osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i);
} else if (result.tizen) {
osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i);
}
if (osVersion) {
result.osversion = osVersion;
}
var osMajorVersion = !result.windows && osVersion.split(".")[0];
if (tablet || nexusTablet || iosdevice == "ipad" || android && (osMajorVersion == 3 || osMajorVersion >= 4 && !mobile) || result.silk) {
result.tablet = t;
} else if (mobile || iosdevice == "iphone" || iosdevice == "ipod" || android || nexusMobile || result.blackberry || result.webos || result.bada) {
result.mobile = t;
}
if (result.msedge || result.msie && result.version >= 10 || result.yandexbrowser && result.version >= 15 || result.vivaldi && result.version >= 1 || result.chrome && result.version >= 20 || result.samsungBrowser && result.version >= 4 || result.whale && compareVersions([result.version, "1.0"]) === 1 || result.mzbrowser && compareVersions([result.version, "6.0"]) === 1 || result.focus && compareVersions([result.version, "1.0"]) === 1 || result.firefox && result.version >= 20 || result.safari && result.version >= 6 || result.opera && result.version >= 10 || result.ios && result.osversion && result.osversion.split(".")[0] >= 6 || result.blackberry && result.version >= 10.1 || result.chromium && result.version >= 20) {
result.a = t;
} else if (result.msie && result.version < 10 || result.chrome && result.version < 20 || result.firefox && result.version < 20 || result.safari && result.version < 6 || result.opera && result.version < 10 || result.ios && result.osversion && result.osversion.split(".")[0] < 6 || result.chromium && result.version < 20) {
result.c = t;
} else
result.x = t;
return result;
}
var bowser2 = detect(typeof navigator !== "undefined" ? navigator.userAgent || "" : "");
bowser2.test = function(browserList) {
for (var i = 0; i < browserList.length; ++i) {
var browserItem = browserList[i];
if (typeof browserItem === "string") {
if (browserItem in bowser2) {
return true;
}
}
}
return false;
};
function getVersionPrecision(version) {
return version.split(".").length;
}
function map(arr, iterator) {
var result = [], i;
if (Array.prototype.map) {
return Array.prototype.map.call(arr, iterator);
}
for (i = 0; i < arr.length; i++) {
result.push(iterator(arr[i]));
}
return result;
}
function compareVersions(versions) {
var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1]));
var chunks = map(versions, function(version) {
var delta = precision - getVersionPrecision(version);
version = version + new Array(delta + 1).join(".0");
return map(version.split("."), function(chunk) {
return new Array(20 - chunk.length).join("0") + chunk;
}).reverse();
});
while (--precision >= 0) {
if (chunks[0][precision] > chunks[1][precision]) {
return 1;
} else if (chunks[0][precision] === chunks[1][precision]) {
if (precision === 0) {
return 0;
}
} else {
return -1;
}
}
}
function isUnsupportedBrowser(minVersions, strictMode, ua) {
var _bowser = bowser2;
if (typeof strictMode === "string") {
ua = strictMode;
strictMode = void 0;
}
if (strictMode === void 0) {
strictMode = false;
}
if (ua) {
_bowser = detect(ua);
}
var version = "" + _bowser.version;
for (var browser in minVersions) {
if (minVersions.hasOwnProperty(browser)) {
if (_bowser[browser]) {
if (typeof minVersions[browser] !== "string") {
throw new Error("Browser version in the minVersion map should be a string: " + browser + ": " + String(minVersions));
}
return compareVersions([version, minVersions[browser]]) < 0;
}
}
}
return strictMode;
}
function check(minVersions, strictMode, ua) {
return !isUnsupportedBrowser(minVersions, strictMode, ua);
}
bowser2.isUnsupportedBrowser = isUnsupportedBrowser;
bowser2.compareVersions = compareVersions;
bowser2.check = check;
bowser2._detect = detect;
bowser2.detect = detect;
return bowser2;
});
})(bowser$1);
var bowser = bowser$1.exports;
const useCreateImageBitmap = !!(globalObject == null ? void 0 : globalObject.createImageBitmap) && !bowser.firefox && !bowser.safari;
const createImageBitmapOpts = {
imageOrientation: "flipY",
premultiplyAlpha: "premultiply"
};
class HtmlImageLoader {
constructor(stage) {
__publicField(this, "_stage");
this._stage = stage;
}
loadImage(url, rect, done) {
const self2 = this;
const img = new Image();
img.crossOrigin = "anonymous";
const x = rect && rect.x || 0;
const y = rect && rect.y || 0;
const width = rect && rect.width || 1;
const height = rect && rect.height || 1;
done = once(done);
img.onload = function() {
self2._handleLoad(img, x, y, width, height, done);
};
img.onerror = function() {
self2._handleError(url, done);
};
img.src = url;
function cancel() {
img.onload = img.onerror = null;
img.src = "";
done.apply(null, arguments);
}
return cancel;
}
_handleLoad(img, x, y, width, height, done) {
if (x === 0 && y === 0 && width === 1 && height === 1) {
done(null, new StaticAsset(img));
return;
}
x *= img.naturalWidth;
y *= img.naturalHeight;
width *= img.naturalWidth;
height *= img.naturalHeight;
if (useCreateImageBitmap) {
globalObject == null ? void 0 : globalObject.createImageBitmap(img, x, y, width, height, createImageBitmapOpts).then(function(bitmap) {
done(null, new StaticAsset(bitmap));
});
} else {
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const context = canvas.getContext("2d");
context == null ? void 0 : context.drawImage(img, x, y, width, height, 0, 0, width, height);
done(null, new StaticAsset(canvas));
}
}
_handleError(url, done) {
done(new NetworkError("Network error: " + url));
}
}
var defaultPixelRatio = 1;
function pixelRatio() {
if (typeof window !== "undefined") {
if (window.devicePixelRatio) {
return window.devicePixelRatio;
} else {
var screen = window.screen;
if (screen && screen.deviceXDPI && screen.logicalXDPI) {
return screen.deviceXDPI / screen.logicalXDPI;
} else if (screen && screen.systemXDPI && screen.logicalXDPI) {
return screen.systemXDPI / screen.logicalXDPI;
}
}
}
return defaultPixelRatio;
}
function ispot(n) {
return (n & n - 1) == 0;
}
function prefixProperty(property) {
if (typeof document === "undefined") {
return property;
}
const style = document.documentElement.style;
const prefixList = ["Moz", "Webkit", "Khtml", "O", "ms"];
for (let i = 0; i < prefixList.length; i++) {
const prefix = prefixList[i];
const capitalizedProperty = property[0].toUpperCase() + property.slice(1);
const prefixedProperty = prefix + capitalizedProperty;
if (prefixedProperty in style) {
return prefixedProperty;
}
}
return property;
}
function getWithVendorPrefix(property) {
const prefixedProperty = prefixProperty(property);
return function getPropertyWithVendorPrefix(element) {
return element.style[prefixedProperty];
};
}
function setWithVendorPrefix(property) {
const prefixedProperty = prefixProperty(property);
return function setPropertyWithVendorPrefix(element, val) {
return element.style[prefixedProperty] = val;
};
}
const setTransform = setWithVendorPrefix("transform");
const setTransformOrigin = setWithVendorPrefix("transformOrigin");
function setNullTransform(element) {
setTransform(element, "translateZ(0)");
}
function setNullTransformOrigin(element) {
setTransformOrigin(element, "0 0 0");
}
function setAbsolute(element) {
element.style.position = "absolute";
}
function setPixelPosition(element, x, y) {
element.style.left = x + "px";
element.style.top = y + "px";
}
function setPixelSize(element, width, height) {
element.style.width = width + "px";
element.style.height = height + "px";
}
function setNullSize(element) {
element.style.width = element.style.height = "0";
}
function setFullSize(element) {
element.style.width = element.style.height = "100%";
}
function setOverflowHidden(element) {
element.style.overflow = "hidden";
}
function setOverflowVisible(element) {
element.style.overflow = "visible";
}
function setNoPointerEvents(element) {
element.style.pointerEvents = "none";
}
var dom = {
prefixProperty,
getWithVendorPrefix,
setWithVendorPrefix,
setTransform,
setTransformOrigin,
setNullTransform,
setNullTransformOrigin,
setAbsolute,
setPixelPosition,
setPixelSize,
setNullSize,
setFullSize,
setOverflowHidden,
setOverflowVisible,
setNoPointerEvents
};
var browserQuirks = {
videoUseTexImage2D: bowser.chrome
};
function initWebGlContext(canvas, opts) {
var options = {
alpha: true,
premultipliedAlpha: true,
antialias: !!(opts && opts.antialias),
preserveDrawingBuffer: !!(opts && opts.preserveDrawingBuffer)
};
var gl = canvas.getContext && (canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options));
if (!gl) {
throw new Error("Could not get WebGL context");
}
if (opts.wrapContext) {
gl = opts.wrapContext(gl);
}
return gl;
}
class WebGlTexture {
constructor(stage, tile2, asset) {
__publicField(this, "_stage");
__publicField(this, "_gl");
__publicField(this, "_texture");
__publicField(this, "_timestamp");
__publicField(this, "_width");
__publicField(this, "_height");
this._stage = stage;
this._gl = stage._gl;
this._texture = null;
this._timestamp = null;
this._width = this._height = null;
this.refresh(tile2, asset);
}
refresh(_tile2, asset) {
var gl = this._gl;
var stage = this._stage;
var texture;
var timestamp = asset.timestamp();
if (timestamp === this._timestamp) {
return;
}
var element = asset.element();
var width = asset.width();
var height = asset.height();
if (width !== this._width || height !== this._height) {
var maxSize = stage.maxTextureSize();
if (width > maxSize) {
throw new Error("Texture width larger than max size (" + width + " vs. " + maxSize + ")");
}
if (height > maxSize) {
throw new Error("Texture height larger than max size (" + height + " vs. " + maxSize + ")");
}
if (this._texture) {
gl.deleteTexture(texture);
}
texture = this._texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, element);
} else {
texture = this._texture;
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
if (element instanceof HTMLVideoElement && browserQuirks.videoUseTexImage2D) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, element);
} else {
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, element);
}
}
if (stage._generateMipmaps && ispot(width) && ispot(height)) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);