{
  "version": 3,
  "sources": ["../src/main/index.ts", "../src/main/fifo-queue.ts", "../src/main/engines/audio.engine.ts", "../src/main/const.ts", "../src/main/double-linked-list.ts", "../src/main/inputs.ts", "../src/main/engines/gamepad.engine.ts", "../src/main/engines/keyboard.engine.ts", "../src/main/engines/mouse.engine.ts", "../src/main/engines/touch.engine.ts", "../src/main/models.ts", "../src/main/gaming-canvas.ts", "../src/main/stat.ts", "../src/main/util.ts"],
  "sourcesContent": ["export { GamingCanvasAudioType } from './engines/audio.engine.js';\nexport * from './const.js';\nexport * from './double-linked-list.js';\nexport { GamingCanvasInputGamepad, GamingCanvasInputGamepadControllerButtons, GamingCanvasInputGamepadState } from './engines/gamepad.engine.js';\nexport { GamingCanvasInputKeyboardAction, GamingCanvasInputKeyboard } from './engines/keyboard.engine.js';\nexport { GamingCanvasInputMouseAction, GamingCanvasInputMouse } from './engines/mouse.engine.js';\nexport { GamingCanvasInputTouchAction, GamingCanvasInputTouch } from './engines/touch.engine.js';\nexport * from './fifo-queue.js';\nexport * from './inputs.js';\nexport * from './gaming-canvas.js';\nexport * from './models.js';\nexport * from './stat.js';\nexport * from './util.js';\n", "/**\n * @author tknight-dev\n */\n\ninterface GamingCanvasFIFOQueueNode<T> {\n\tdata: T;\n\tnext?: GamingCanvasFIFOQueueNode<T>;\n}\n\nexport class GamingCanvasFIFOQueue<T> {\n\tprivate end?: GamingCanvasFIFOQueueNode<T>;\n\tprivate start?: GamingCanvasFIFOQueueNode<T>;\n\tprivate _length: number = 0;\n\tprivate limit: number = -1;\n\tprivate overflow: boolean;\n\n\tpublic constructor(array?: T[]) {\n\t\tif (array !== undefined && Array.isArray(array)) {\n\t\t\tlet data: T, node: GamingCanvasFIFOQueueNode<T>;\n\n\t\t\tfor (data of array) {\n\t\t\t\tnode = {\n\t\t\t\t\tdata: data,\n\t\t\t\t\tnext: undefined,\n\t\t\t\t};\n\n\t\t\t\tif (this.end) {\n\t\t\t\t\tthis.end.next = node;\n\t\t\t\t\tthis.end = node;\n\t\t\t\t} else {\n\t\t\t\t\tthis.end = node;\n\t\t\t\t\tthis.start = node;\n\t\t\t\t}\n\n\t\t\t\t// Reset overflow one-time alarm\n\t\t\t\tif (this.overflow) {\n\t\t\t\t\tthis.overflow = false;\n\t\t\t\t}\n\n\t\t\t\tthis._length++;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Remove all nodes\n\t */\n\tpublic clear(): void {\n\t\tthis.end = undefined;\n\t\tthis._length = 0;\n\t\tthis.start = undefined;\n\t}\n\n\t/**\n\t * Removes and returns the first queue item\n\t */\n\tpublic pop(): T | undefined {\n\t\tlet start: GamingCanvasFIFOQueueNode<T> | undefined = this.start;\n\n\t\tif (start) {\n\t\t\tif (this._length === 1) {\n\t\t\t\tthis.end = undefined;\n\t\t\t\tthis.start = undefined;\n\t\t\t} else {\n\t\t\t\tthis.start = start.next;\n\t\t\t}\n\n\t\t\tthis._length--;\n\t\t\treturn start.data;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Adds to the end of the queue\n\t */\n\tpublic push(data: T): void {\n\t\tif (this.limit !== -1 && this._length >= this.limit) {\n\t\t\tif (!this.overflow) {\n\t\t\t\t// Only use a one-time alarm\n\t\t\t\tconsole.error(`GamingCanvas > GamingCanvasFIFOQueue: input overflow [limit=${this.limit}]`);\n\t\t\t\tthis.overflow = true;\n\t\t\t}\n\t\t} else {\n\t\t\tlet node: GamingCanvasFIFOQueueNode<T> = {\n\t\t\t\tdata: data,\n\t\t\t\tnext: undefined,\n\t\t\t};\n\n\t\t\tif (this.end) {\n\t\t\t\tthis.end.next = node;\n\t\t\t\tthis.end = node;\n\t\t\t} else {\n\t\t\t\tthis.end = node;\n\t\t\t\tthis.start = node;\n\t\t\t}\n\n\t\t\t// Reset overflow one-time alarm\n\t\t\tif (this.overflow) {\n\t\t\t\tthis.overflow = false;\n\t\t\t}\n\n\t\t\tthis._length++;\n\t\t}\n\t}\n\n\tpublic toArray(): T[] {\n\t\tlet array: T[] = new Array(this._length),\n\t\t\ti: number = 0,\n\t\t\tnode: GamingCanvasFIFOQueueNode<T> | undefined = this.start;\n\n\t\twhile (node) {\n\t\t\tarray[i++] = node.data;\n\t\t\tnode = node.next;\n\t\t}\n\n\t\treturn array;\n\t}\n\n\tpublic get length(): number {\n\t\treturn this._length;\n\t}\n\n\tpublic forEach(callback: (value: T) => void): void {\n\t\tlet node: GamingCanvasFIFOQueueNode<T> | undefined = this.start;\n\t\twhile (node) {\n\t\t\tcallback(node.data);\n\t\t\tnode = node.next;\n\t\t}\n\t}\n\n\t/**\n\t * @param limit 0 or null is unlimited\n\t */\n\tpublic setLimit(limit: number | null) {\n\t\tthis.limit = limit || -1;\n\t}\n\n\tpublic isOverflow(): boolean {\n\t\treturn this.overflow;\n\t}\n}\n", "import { GamingCanvasDoubleLinkedListNode } from '../double-linked-list.js';\nimport { GamingCanvasFIFOQueue } from '../fifo-queue.js';\n\n/**\n * The user must interact with the page before the browser will allow the audio to play\n *\n * Provide multiple buffers for controlling and overlaying single audio assets\n *\n * @author tknight-dev\n */\n\ninterface Buffer {\n\tassetId?: number;\n\taudio: HTMLAudioElement;\n\tavailable: boolean;\n\tcallbackDone?: (bufferId: number) => void;\n\tid: number;\n\tinstance: number;\n\tfaderNode?: GamingCanvasDoubleLinkedListNode<Fader>;\n\tpanner: StereoPannerNode;\n\tsource: MediaElementAudioSourceNode;\n\ttype?: GamingCanvasAudioType;\n\tvolumeRequested: number;\n}\n\ninterface Fader {\n\tactive: boolean;\n\tid: number;\n\tpanCallback?: (bufferId: number) => void;\n\tpanRequested: number;\n\tpanSteps: number;\n\tpanStepValue: number;\n\tpause: boolean;\n\tvolumeCallback?: (bufferId: number) => void;\n\tvolumeLimit: number;\n\tvolumeRequested: number;\n\tvolumeRequestedEff: number;\n\tvolumeSteps: number;\n\tvolumeStepValue: number;\n}\n\nexport enum GamingCanvasAudioType {\n\tALL,\n\tAMBIENCE,\n\tEFFECT,\n\tMUSIC,\n\tVOICEOVER,\n}\n\n// Allows for blocking\nconst bufferCallbackPromise = async (instance: number, callback: (bufferId: number) => void): Promise<void> => {\n\treturn new Promise((resolve: any) => {\n\t\tsetTimeout(() => {\n\t\t\tresolve();\n\t\t\tcallback(instance);\n\t\t});\n\t});\n};\n\n// Non-blocking\nconst faderCallback = (instance: number, callback: (bufferId: number) => void, faderInternal: Fader, pan: boolean) => {\n\tif (pan) {\n\t\tfaderInternal.panCallback = undefined;\n\t} else {\n\t\tfaderInternal.volumeCallback = undefined;\n\t}\n\tsetTimeout(() => {\n\t\tcallback(instance);\n\t});\n};\n\n// Allows for blocking\nconst faderCallbackPromise = async (instance: number, callback: (bufferId: number) => void, faderInternal: Fader, pan: boolean): Promise<void> => {\n\tif (pan) {\n\t\tfaderInternal.panCallback = undefined;\n\t} else {\n\t\tfaderInternal.volumeCallback = undefined;\n\t}\n\treturn new Promise((resolve: any) => {\n\t\tsetTimeout(() => {\n\t\t\tresolve();\n\t\t\tcallback(instance);\n\t\t});\n\t});\n};\n\nconst faderReset = (fader: Fader) => {\n\tfader.active = false;\n\tfader.panCallback = undefined;\n\tfader.panRequested = 0;\n\tfader.panSteps = 0;\n\tfader.panStepValue = 0;\n\tfader.pause = false;\n\tfader.volumeCallback = undefined;\n\tfader.volumeLimit = 0;\n\tfader.volumeRequested = 0;\n\tfader.volumeRequestedEff = 0;\n\tfader.volumeSteps = 0;\n\tfader.volumeStepValue = 0;\n};\n\nexport class GamingCanvasEngineAudio {\n\tprivate static assets: Map<number, HTMLAudioElement> = new Map();\n\tprivate static buffers: Buffer[];\n\tprivate static buffersAvailable: GamingCanvasFIFOQueue<Buffer> = new GamingCanvasFIFOQueue();\n\tprivate static buffersByInstanceId: Map<number, Buffer> = new Map();\n\tprivate static callbackIsPermitted: (state: boolean) => void;\n\tprivate static context: AudioContext;\n\tprivate static enabled: boolean = false;\n\tprivate static faders: Fader[];\n\tprivate static fadersActive: Set<number> = new Set();\n\tprivate static goIntervalInMs: number = 20;\n\tprivate static muted: boolean = false;\n\tprivate static permission: boolean = false;\n\tprivate static permissionInterval: ReturnType<typeof setInterval>;\n\tprivate static permissionSample: HTMLAudioElement;\n\tprivate static request: number;\n\tprivate static volumeAll: number = 1;\n\tprivate static volumeAmbience: number = 0.6;\n\tprivate static volumeAmbienceEff: number = GamingCanvasEngineAudio.volumeAmbience;\n\tprivate static volumeEffect: number = 0.8;\n\tprivate static volumeEffectEff: number = GamingCanvasEngineAudio.volumeEffect;\n\tprivate static volumeMusic: number = 1;\n\tprivate static volumeMusicEff: number = GamingCanvasEngineAudio.volumeMusic;\n\tprivate static volumeVoiceover: number = 1;\n\tprivate static volumeVoiceoverEff: number = GamingCanvasEngineAudio.volumeVoiceover;\n\n\tprivate static go(_timestampNow: number): void {}\n\tprivate static go__funcForward(): void {\n\t\tlet buffer: Buffer,\n\t\t\tbuffers: Buffer[] = GamingCanvasEngineAudio.buffers,\n\t\t\tchanged: boolean,\n\t\t\tfader: Fader,\n\t\t\tfaderId: number,\n\t\t\tfaders: Fader[] = GamingCanvasEngineAudio.faders,\n\t\t\tfadersActive: Set<number> = GamingCanvasEngineAudio.fadersActive,\n\t\t\tintervalInMs: number = GamingCanvasEngineAudio.goIntervalInMs,\n\t\t\tlimit: number,\n\t\t\ttimestampDelta: number,\n\t\t\ttimestampThen: number = 0;\n\n\t\tconst go = (timestampNow: number) => {\n\t\t\t// Always load the next frame first\n\t\t\tGamingCanvasEngineAudio.request = requestAnimationFrame(go);\n\n\t\t\t// Faders\n\t\t\ttimestampDelta = timestampNow - timestampThen;\n\t\t\tif (timestampDelta > intervalInMs) {\n\t\t\t\ttimestampThen = timestampNow - (timestampDelta % intervalInMs);\n\n\t\t\t\t// Process them\n\t\t\t\tfor (faderId of fadersActive) {\n\t\t\t\t\tfader = faders[faderId];\n\n\t\t\t\t\tif (!fader.active || fader.pause) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tbuffer = buffers[faderId];\n\t\t\t\t\tchanged = false;\n\n\t\t\t\t\tif (fader.panSteps !== 0) {\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tfader.panSteps--;\n\n\t\t\t\t\t\tif (fader.panSteps === 0) {\n\t\t\t\t\t\t\tbuffer.panner.pan.setValueAtTime(fader.panRequested, 0);\n\t\t\t\t\t\t\tfader.panCallback !== undefined && faderCallback(buffer.instance, fader.panCallback, fader, true);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbuffer.panner.pan.setValueAtTime(Math.max(-1, Math.min(1, buffer.panner.pan.value + fader.panStepValue)), 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (fader.volumeSteps !== 0) {\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t\tfader.volumeSteps--;\n\n\t\t\t\t\t\tswitch (buffer.type) {\n\t\t\t\t\t\t\tcase GamingCanvasAudioType.AMBIENCE:\n\t\t\t\t\t\t\t\tlimit = GamingCanvasEngineAudio.volumeAmbienceEff;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase GamingCanvasAudioType.EFFECT:\n\t\t\t\t\t\t\t\tlimit = GamingCanvasEngineAudio.volumeEffectEff;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase GamingCanvasAudioType.MUSIC:\n\t\t\t\t\t\t\t\tlimit = GamingCanvasEngineAudio.volumeMusicEff;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase GamingCanvasAudioType.VOICEOVER:\n\t\t\t\t\t\t\t\tlimit = GamingCanvasEngineAudio.volumeVoiceoverEff;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (fader.volumeLimit !== limit) {\n\t\t\t\t\t\t\tfader.volumeLimit = limit;\n\t\t\t\t\t\t\tfader.volumeRequestedEff = fader.volumeRequested * limit;\n\t\t\t\t\t\t\tfader.volumeStepValue = Math.abs(buffer.audio.volume - fader.volumeRequestedEff) / fader.volumeSteps;\n\n\t\t\t\t\t\t\tif (buffer.audio.volume > fader.volumeRequestedEff) {\n\t\t\t\t\t\t\t\tfader.volumeStepValue *= -1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (fader.volumeSteps === 0) {\n\t\t\t\t\t\t\tbuffer.audio.volume = fader.volumeRequestedEff;\n\t\t\t\t\t\t\tfader.volumeCallback !== undefined && faderCallback(buffer.instance, fader.volumeCallback, fader, false);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbuffer.audio.volume = Math.max(0, Math.min(1, buffer.audio.volume + fader.volumeStepValue));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (changed === false) {\n\t\t\t\t\t\tfader.active = false;\n\t\t\t\t\t\tfadersActive.delete(faderId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tGamingCanvasEngineAudio.go = go;\n\t}\n\n\t/**\n\t * Set the specific audio instance's volume\n\t *\n\t * @param instance is the number returned by the controlPlay() function. Invalid instances are ignored\n\t * @param pan is -1 left, 0 center, 1 right\n\t * @param durationInMs is how long it takes to apply the new value completely (default is 0 milliseconds)\n\t * @param callback is triggered when audio or fader is complete\n\t */\n\tpublic static controlPan(instance: number, pan: number, durationInMs: number = 0, callback?: (instance: number) => void): void {\n\t\tconst buffer: Buffer = <Buffer>GamingCanvasEngineAudio.buffersByInstanceId.get(instance);\n\n\t\tif (buffer !== undefined) {\n\t\t\tif (!buffer.audio.ended) {\n\t\t\t\tlet panCurrent: number = buffer.panner.pan.value;\n\t\t\t\tpan = Math.max(-1, Math.min(1, pan));\n\n\t\t\t\tif (pan > panCurrent - 0.01 && pan < panCurrent + 0.01) {\n\t\t\t\t\t// The change request is too small\n\t\t\t\t\tcallback && callback(buffer.instance);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tdurationInMs = Math.max(0, durationInMs);\n\n\t\t\t\t// Don't fade if the request duration is less than the goIntervalInMs\n\t\t\t\tif (durationInMs > GamingCanvasEngineAudio.goIntervalInMs) {\n\t\t\t\t\tconst fader: Fader = GamingCanvasEngineAudio.faders[buffer.id];\n\n\t\t\t\t\t// Duration can't be more than twice as long as the audio source is\n\t\t\t\t\tdurationInMs = Math.min((<HTMLAudioElement>GamingCanvasEngineAudio.assets.get(<number>buffer.assetId)).duration * 2000, durationInMs);\n\n\t\t\t\t\t// Set the fader parameters\n\t\t\t\t\tfader.active = true;\n\t\t\t\t\tfader.panCallback = callback;\n\t\t\t\t\tfader.panSteps = ((durationInMs / GamingCanvasEngineAudio.goIntervalInMs) | 0) + 1; // Make sure we at least overshoot the target\n\t\t\t\t\tfader.panStepValue = Math.abs(panCurrent - pan) / fader.panSteps;\n\t\t\t\t\tfader.panRequested = pan;\n\n\t\t\t\t\tif (panCurrent > pan) {\n\t\t\t\t\t\tfader.panStepValue *= -1;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Done\n\t\t\t\t\tGamingCanvasEngineAudio.fadersActive.add(buffer.id);\n\t\t\t\t} else {\n\t\t\t\t\tbuffer.panner.pan.setValueAtTime(pan, 0);\n\t\t\t\t\tcallback && callback(buffer.instance);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Suspend playing the audio without ending it, or resume audio where you suspended it\n\t *\n\t * @param instance is the number returned by the controlPlay() function. Invalid instances are ignored\n\t * @param state true = pause, false = unpause\n\t */\n\tpublic static controlPause(instance: number, state: boolean): void {\n\t\tconst buffer: Buffer = <Buffer>GamingCanvasEngineAudio.buffersByInstanceId.get(instance);\n\n\t\tif (buffer !== undefined) {\n\t\t\tif (!buffer.audio.ended) {\n\t\t\t\tstate === true ? buffer.audio.pause() : buffer.audio.play();\n\t\t\t\tGamingCanvasEngineAudio.faders[buffer.id].pause = state;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Suspend playing the audio without ending it, or resume audio where you suspended it\n\t *\n\t * @param state true = pause, false = unpause\n\t */\n\tpublic static controlPauseAll(state: boolean): void {\n\t\tlet buffer: Buffer;\n\n\t\tfor (buffer of GamingCanvasEngineAudio.buffersByInstanceId.values()) {\n\t\t\tif (!buffer.audio.ended) {\n\t\t\t\tstate === true ? buffer.audio.pause() : buffer.audio.play();\n\t\t\t\tGamingCanvasEngineAudio.faders[buffer.id].pause = state;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If an audio buffer is available, via the availibility FIFO queue, then the asset will be loaded into the buffer and played from that source\n\t *\n\t * @param assetId is the id of the audio file in cache to be played\n\t * @param type (default is EFFECT)\n\t * @param loop (default is false)\n\t * @param pan is -1 left, 0 center, 1 right (default is 0)\n\t * @param positionInS is between 0 and the duration of the audio asset in seconds (default is 0)\n\t * @param volume is between 0 and 1 (default is 1)\n\t * @param callback is triggered when audio is complete\n\t * @return is instance, use this to modify the active audio (null on failure)\n\t */\n\tpublic static async controlPlay(\n\t\tassetId: number,\n\t\ttype: GamingCanvasAudioType = GamingCanvasAudioType.EFFECT,\n\t\tloop: boolean = false,\n\t\tpan: number = 0,\n\t\tpositionInS: number = 0,\n\t\tvolume?: number,\n\t\tcallback?: (instance: number) => void,\n\t): Promise<number | null> {\n\t\tif (GamingCanvasEngineAudio.enabled !== true) {\n\t\t\tconsole.error(`GamingCanvas > GamingCanvasEngineAudio > controlPlay: audio not enabled [see options]`);\n\t\t\treturn null;\n\t\t} else if (GamingCanvasEngineAudio.permission !== true) {\n\t\t\tconsole.error(`GamingCanvas > GamingCanvasEngineAudio > controlPlay: audio not permitted`);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst asset: HTMLAudioElement | undefined = GamingCanvasEngineAudio.assets.get(assetId);\n\t\tif (asset === undefined) {\n\t\t\tconsole.error(`GamingCanvas > GamingCanvasEngineAudio > controlPlay: assetId ${assetId} is invalid`);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst buffer: Buffer | undefined = GamingCanvasEngineAudio.buffersAvailable.pop();\n\t\tif (buffer === undefined) {\n\t\t\tconsole.error(`GamingCanvas > GamingCanvasEngineAudio > controlPlay: buffer underflow`);\n\t\t\treturn null;\n\t\t}\n\n\t\tlet audio: HTMLAudioElement, volumeGlobal: number, volumeEff: number;\n\n\t\tswitch (type) {\n\t\t\tcase GamingCanvasAudioType.AMBIENCE:\n\t\t\t\tvolumeGlobal = GamingCanvasEngineAudio.volumeAmbienceEff;\n\t\t\t\tbreak;\n\t\t\tcase GamingCanvasAudioType.EFFECT:\n\t\t\t\tvolumeGlobal = GamingCanvasEngineAudio.volumeEffectEff;\n\t\t\t\tbreak;\n\t\t\tcase GamingCanvasAudioType.MUSIC:\n\t\t\t\tvolumeGlobal = GamingCanvasEngineAudio.volumeMusicEff;\n\t\t\t\tbreak;\n\t\t\tcase GamingCanvasAudioType.VOICEOVER:\n\t\t\t\tvolumeGlobal = GamingCanvasEngineAudio.volumeVoiceoverEff;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tconsole.error(`GamingCanvas > GamingCanvasEngineAudio > controlPlay: unknown type ${type}`);\n\t\t\t\treturn null;\n\t\t}\n\n\t\tvolumeEff = volumeGlobal * (volume === undefined ? 1 : volume);\n\n\t\t// Apply bounds\n\t\tpan = Math.max(-1, Math.min(1, pan));\n\t\tpositionInS = Math.max(0, Math.min(asset.duration, positionInS));\n\t\tvolumeEff = Math.max(0, Math.min(1, volumeEff));\n\n\t\t// Load buffer source\n\t\taudio = buffer.audio;\n\t\taudio.pause(); // Shouldn't be necessary, but hey\n\t\taudio.src = asset.src;\n\n\t\t// Config: Audio\n\t\taudio.currentTime = positionInS;\n\t\taudio.loop = loop === true;\n\t\taudio.muted = GamingCanvasEngineAudio.muted;\n\t\taudio.volume = volumeEff;\n\n\t\t// Config: Buffer\n\t\tbuffer.assetId = assetId;\n\t\tbuffer.available = false;\n\t\t((buffer.callbackDone = callback), buffer.panner.pan.setValueAtTime(pan, 0));\n\t\tbuffer.volumeRequested = Math.max(0, Math.min(1, volume === undefined ? 1 : volume));\n\n\t\t// Keep randomizing until a unique number is generated\n\t\tbuffer.instance = (Math.random() * Number.MAX_SAFE_INTEGER) | 0;\n\t\twhile (buffer.instance === 0 || GamingCanvasEngineAudio.buffersByInstanceId.has(buffer.instance) === true) {\n\t\t\tbuffer.instance = (Math.random() * Number.MAX_SAFE_INTEGER) | 0;\n\t\t}\n\t\tGamingCanvasEngineAudio.buffersByInstanceId.set(buffer.instance, buffer);\n\n\t\tbuffer.type = type;\n\n\t\t// Config: Fader\n\t\tfaderReset(GamingCanvasEngineAudio.faders[buffer.id]);\n\n\t\t// Play\n\t\tawait audio.play();\n\t\treturn buffer.instance;\n\t}\n\n\t/**\n\t * Stop the audio and return the buffer to the availability FIFO queue\n\t *\n\t * @param instance is the number returned by the controlPlay() function. Invalid instances are ignored\n\t */\n\tpublic static controlStop(instance: number): void {\n\t\tconst buffer: Buffer = <Buffer>GamingCanvasEngineAudio.buffersByInstanceId.get(instance);\n\n\t\tif (buffer !== undefined) {\n\t\t\t// callbacks triggered by 'audio.onended' event\n\t\t\tif (!buffer.audio.ended) {\n\t\t\t\t// Buffer\n\t\t\t\tbuffer.audio.loop = false;\n\t\t\t\tbuffer.audio.currentTime = buffer.audio.duration;\n\n\t\t\t\t// Fader\n\t\t\t\tGamingCanvasEngineAudio.fadersActive.delete(buffer.id);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stop the audio and return the buffer to the availability FIFO queue\n\t *\n\t * @param type specify a specific type to stop (default is all types)\n\t */\n\tpublic static controlStopAll(type: GamingCanvasAudioType = GamingCanvasAudioType.ALL): void {\n\t\tlet buffer: Buffer;\n\n\t\tfor (buffer of GamingCanvasEngineAudio.buffersByInstanceId.values()) {\n\t\t\t// callbacks triggered by 'audio.onended' event\n\t\t\tif (!buffer.audio.ended) {\n\t\t\t\tif (type === GamingCanvasAudioType.ALL || buffer.type === type) {\n\t\t\t\t\t// Buffer\n\t\t\t\t\tbuffer.audio.loop = false;\n\t\t\t\t\tbuffer.audio.currentTime = buffer.audio.duration || 0;\n\n\t\t\t\t\t// Fader\n\t\t\t\t\tGamingCanvasEngineAudio.fadersActive.delete(buffer.id);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set the specific audio instance's volume\n\t *\n\t * @param instance is the number returned by the controlPlay() function. Invalid instances are ignored\n\t * @param volume is between 0 and 1\n\t * @param durationInMs is how long it takes to apply the new value completely (default is 0 milliseconds)\n\t * @param callback is triggered when audio or fader is complete\n\t */\n\tpublic static controlVolume(instance: number, volume: number, durationInMs: number = 0, callback?: (instance: number) => void): void {\n\t\tconst buffer: Buffer = <Buffer>GamingCanvasEngineAudio.buffersByInstanceId.get(instance);\n\n\t\tif (buffer !== undefined) {\n\t\t\tif (!buffer.audio.ended) {\n\t\t\t\tlet volumeCurrent: number = buffer.audio.volume,\n\t\t\t\t\tvolumeEff: number;\n\n\t\t\t\tvolume = Math.max(0, Math.min(1, volume));\n\t\t\t\tvolumeEff = volume;\n\t\t\t\tbuffer.volumeRequested = volumeEff;\n\n\t\t\t\tswitch (buffer.type) {\n\t\t\t\t\tcase GamingCanvasAudioType.AMBIENCE:\n\t\t\t\t\t\tvolumeEff *= GamingCanvasEngineAudio.volumeAmbienceEff;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase GamingCanvasAudioType.EFFECT:\n\t\t\t\t\t\tvolumeEff *= GamingCanvasEngineAudio.volumeEffectEff;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase GamingCanvasAudioType.MUSIC:\n\t\t\t\t\t\tvolumeEff *= GamingCanvasEngineAudio.volumeMusicEff;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase GamingCanvasAudioType.VOICEOVER:\n\t\t\t\t\t\tvolumeEff *= GamingCanvasEngineAudio.volumeVoiceoverEff;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (volumeEff > volumeCurrent - 0.01 && volumeEff < volumeCurrent + 0.01) {\n\t\t\t\t\t// The change request is too small\n\t\t\t\t\tcallback && callback(buffer.instance);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Don't fade if the request duration is less than the goIntervalInMs\n\t\t\t\tif (durationInMs > GamingCanvasEngineAudio.goIntervalInMs) {\n\t\t\t\t\tconst fader: Fader = GamingCanvasEngineAudio.faders[buffer.id];\n\n\t\t\t\t\t// Duration can't be more than twice as long as the audio source is\n\t\t\t\t\tdurationInMs = Math.min((<HTMLAudioElement>GamingCanvasEngineAudio.assets.get(<number>buffer.assetId)).duration * 2000, durationInMs);\n\n\t\t\t\t\t// Set the fader parameters\n\t\t\t\t\tfader.active = true;\n\t\t\t\t\tfader.volumeCallback = callback;\n\n\t\t\t\t\tswitch (buffer.type) {\n\t\t\t\t\t\tcase GamingCanvasAudioType.AMBIENCE:\n\t\t\t\t\t\t\tfader.volumeLimit = GamingCanvasEngineAudio.volumeAmbienceEff;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase GamingCanvasAudioType.EFFECT:\n\t\t\t\t\t\t\tfader.volumeLimit = GamingCanvasEngineAudio.volumeEffectEff;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase GamingCanvasAudioType.MUSIC:\n\t\t\t\t\t\t\tfader.volumeLimit = GamingCanvasEngineAudio.volumeMusicEff;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase GamingCanvasAudioType.VOICEOVER:\n\t\t\t\t\t\t\tfader.volumeLimit = GamingCanvasEngineAudio.volumeVoiceoverEff;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tfader.volumeSteps = ((durationInMs / GamingCanvasEngineAudio.goIntervalInMs) | 0) + 1; // Make sure we at least overshoot the target\n\t\t\t\t\tfader.volumeStepValue = Math.abs(volumeCurrent - volumeEff) / fader.volumeSteps;\n\t\t\t\t\tfader.volumeRequested = volume;\n\t\t\t\t\tfader.volumeRequestedEff = volumeEff;\n\n\t\t\t\t\tif (volumeCurrent > volumeEff) {\n\t\t\t\t\t\tfader.volumeStepValue *= -1;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Done\n\t\t\t\t\tGamingCanvasEngineAudio.fadersActive.add(buffer.id);\n\t\t\t\t} else {\n\t\t\t\t\tbuffer.audio.volume = volumeEff;\n\t\t\t\t\tcallback && callback(buffer.instance);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static isContext(): boolean {\n\t\treturn GamingCanvasEngineAudio.context !== undefined;\n\t}\n\n\tpublic static initialize(enable: boolean, bufferCount: number, audioContext?: AudioContext): void {\n\t\tif (audioContext) {\n\t\t\tGamingCanvasEngineAudio.context = audioContext;\n\t\t}\n\t\tif (!enable) {\n\t\t\tGamingCanvasEngineAudio.enabled = false;\n\t\t\tcancelAnimationFrame(GamingCanvasEngineAudio.request);\n\t\t\treturn;\n\t\t}\n\n\t\t// Only ever initialize this section once\n\t\tif (GamingCanvasEngineAudio.buffers === undefined) {\n\t\t\t// buffers\n\t\t\tGamingCanvasEngineAudio.buffers = new Array(bufferCount);\n\t\t\tGamingCanvasEngineAudio.faders = new Array(bufferCount);\n\t\t\tGamingCanvasEngineAudio.initializeBuffersAndFaders(bufferCount);\n\n\t\t\t// go functionFoward\n\t\t\tGamingCanvasEngineAudio.go__funcForward();\n\t\t}\n\n\t\t/**\n\t\t * Create the audio sample for permission checking\n\t\t */\n\t\tif (GamingCanvasEngineAudio.permissionSample === undefined) {\n\t\t\tGamingCanvasEngineAudio.permissionSample = new Audio();\n\t\t\tGamingCanvasEngineAudio.permissionSample.setAttribute('preload', 'auto');\n\t\t\tGamingCanvasEngineAudio.permissionSample.setAttribute(\n\t\t\t\t'src',\n\t\t\t\t'data:audio/mp3;base64,//MUxAAB4AWIoAgAATgAH4CA8PD1TEFN//MUxAMAAAGUAAAAAEUzLjEwMFVVVVVV',\n\t\t\t);\n\t\t\tGamingCanvasEngineAudio.permissionSample.volume = 0.01;\n\t\t}\n\n\t\t/**\n\t\t * Poll the system for the play permission from the browser\n\t\t */\n\t\tclearInterval(GamingCanvasEngineAudio.permissionInterval);\n\t\tGamingCanvasEngineAudio.permissionInterval = setInterval(async () => {\n\t\t\tlet permission: boolean = true;\n\n\t\t\ttry {\n\t\t\t\tawait GamingCanvasEngineAudio.permissionSample.play();\n\t\t\t} catch (error: any) {\n\t\t\t\tpermission = false;\n\t\t\t}\n\n\t\t\tif (GamingCanvasEngineAudio.permission !== permission) {\n\t\t\t\tGamingCanvasEngineAudio.permission = permission;\n\n\t\t\t\tif (GamingCanvasEngineAudio.callbackIsPermitted !== undefined) {\n\t\t\t\t\tGamingCanvasEngineAudio.callbackIsPermitted(permission);\n\t\t\t\t}\n\t\t\t}\n\t\t}, 1000);\n\n\t\t// Done\n\t\tif (GamingCanvasEngineAudio.enabled !== true) {\n\t\t\tGamingCanvasEngineAudio.enabled = true;\n\t\t\tGamingCanvasEngineAudio.request = requestAnimationFrame(GamingCanvasEngineAudio.go);\n\t\t}\n\t}\n\n\tprivate static initializeBuffersAndFaders(bufferCount: number): void {\n\t\tlet audio: HTMLAudioElement,\n\t\t\tbuffers: Buffer[] = GamingCanvasEngineAudio.buffers,\n\t\t\tbuffersAvailable: GamingCanvasFIFOQueue<Buffer> = GamingCanvasEngineAudio.buffersAvailable,\n\t\t\tbuffersByInstanceId: Map<number, Buffer> = GamingCanvasEngineAudio.buffersByInstanceId,\n\t\t\tcontext: AudioContext = GamingCanvasEngineAudio.context,\n\t\t\tfaders: Fader[] = GamingCanvasEngineAudio.faders,\n\t\t\ti: number,\n\t\t\tpanner: StereoPannerNode,\n\t\t\tsource: MediaElementAudioSourceNode;\n\n\t\tconst add = (buffer: Buffer, fader: Fader) => {\n\t\t\tbuffers[buffer.id] = buffer;\n\t\t\tfaders[fader.id] = fader;\n\n\t\t\t// OnEnded: Put buffer back in queue\n\t\t\tbuffer.audio.onended = async () => {\n\t\t\t\t// Buffer\n\t\t\t\tbuffer.callbackDone !== undefined && (await bufferCallbackPromise(buffer.instance, buffer.callbackDone));\n\t\t\t\tbuffer.available = true;\n\n\t\t\t\tbuffersByInstanceId.delete(buffer.instance);\n\t\t\t\tbuffersAvailable.push(buffer);\n\n\t\t\t\t// Fader\n\t\t\t\tfader.panCallback !== undefined && (await faderCallbackPromise(buffer.instance, fader.panCallback, fader, true));\n\t\t\t\tfader.volumeCallback !== undefined && (await faderCallbackPromise(buffer.instance, fader.volumeCallback, fader, false));\n\t\t\t\tGamingCanvasEngineAudio.fadersActive.delete(buffer.id);\n\t\t\t\tfaderReset(GamingCanvasEngineAudio.faders[buffer.id]);\n\t\t\t};\n\n\t\t\t// Done: Add the buffer to the queue\n\t\t\tbuffersAvailable.push(buffer);\n\t\t};\n\n\t\tfor (i = 0; i < bufferCount; i++) {\n\t\t\t// Create buffer stack\n\t\t\taudio = new Audio();\n\t\t\tpanner = context.createStereoPanner();\n\t\t\tsource = context.createMediaElementSource(audio);\n\n\t\t\t// Audio\n\t\t\taudio.preload = 'auto'; // Indicates that the whole audio file can be downloaded, even if the user is not expected to use it (MDN)\n\n\t\t\t// Wiring: source -> panner -> output\n\t\t\tsource.connect(panner);\n\t\t\tpanner.connect(context.destination);\n\n\t\t\t// Add itv\n\t\t\tadd(\n\t\t\t\t{\n\t\t\t\t\taudio: audio,\n\t\t\t\t\tavailable: true,\n\t\t\t\t\tid: i,\n\t\t\t\t\tinstance: -1,\n\t\t\t\t\tpanner: panner,\n\t\t\t\t\tsource: source,\n\t\t\t\t\tvolumeRequested: 0,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tactive: false,\n\t\t\t\t\tid: i,\n\t\t\t\t\tpanRequested: 0,\n\t\t\t\t\tpanSteps: 0,\n\t\t\t\t\tpanStepValue: 0,\n\t\t\t\t\tpause: false,\n\t\t\t\t\tvolumeLimit: 0,\n\t\t\t\t\tvolumeRequested: 0,\n\t\t\t\t\tvolumeRequestedEff: 0,\n\t\t\t\t\tvolumeSteps: 0,\n\t\t\t\t\tvolumeStepValue: 0,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * @param assets Map<identifing number, DataURL/URL>\n\t */\n\tpublic static async load(assets: Map<number, string>): Promise<void> {\n\t\tlet id: number,\n\t\t\tpromises: Promise<void>[] = new Array(assets.size),\n\t\t\tpromisesIndex: number = 0,\n\t\t\tsrc: string;\n\n\t\t// Attach the src to a HTMLAudioElement\n\t\tconst loader = async (id: number, src: string) => {\n\t\t\tlet audio: HTMLAudioElement = new Audio(),\n\t\t\t\tresolver: any,\n\t\t\t\tskip: boolean = false,\n\t\t\t\ttimeout: ReturnType<typeof setTimeout>;\n\n\t\t\tconst loaded = () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tGamingCanvasEngineAudio.assets.set(id, audio);\n\t\t\t\taudio.removeEventListener('canplaythrough', loaded, false);\n\n\t\t\t\t// Took to long and the resolver() was triggered to keep things moving forward\n\t\t\t\tif (skip !== true) {\n\t\t\t\t\tresolver();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\treturn new Promise<void>((resolve: any) => {\n\t\t\t\tresolver = resolve;\n\n\t\t\t\t// Prepare to cache and callback when ready\n\t\t\t\taudio.addEventListener('canplaythrough', loaded, false);\n\t\t\t\taudio.preload = 'auto'; // Indicates that the whole audio file can be downloaded, even if the user is not expected to use it (MDN)\n\n\t\t\t\ttry {\n\t\t\t\t\ttimeout = setTimeout(() => {\n\t\t\t\t\t\tconsole.warn(`GamingCanvas > GamingCanvasEngineAudio > loader: asset ${id} is taking a long time to load [+5s] [size=${src.length}B]`);\n\t\t\t\t\t\tresolver();\n\t\t\t\t\t\tskip = true;\n\t\t\t\t\t}, 5000);\n\n\t\t\t\t\t// Start the loading process\n\t\t\t\t\taudio.setAttribute('src', src);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(`GamingCanvas > GamingCanvasEngineAudio > loader: failed to load '${id}' with`, error);\n\t\t\t\t\tresolver();\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\t// Start the load process\n\t\tfor ([id, src] of assets) {\n\t\t\tpromises[promisesIndex++] = loader(id, src);\n\t\t}\n\n\t\t// Wait for all the audio files to load (parallize loading)\n\t\tawait Promise.all(promises);\n\t}\n\n\t/**\n\t * Mute or unmute all audio\n\t */\n\tpublic static mute(enable: boolean): void {\n\t\tlet buffer: Buffer,\n\t\t\tbuffers: Buffer[] = GamingCanvasEngineAudio.buffers;\n\n\t\tGamingCanvasEngineAudio.muted = enable;\n\n\t\tfor (buffer of buffers) {\n\t\t\tbuffer.audio.muted = enable;\n\t\t}\n\t}\n\n\t/**\n\t * @param volume is between 0 and 1\n\t */\n\tpublic static volumeGlobal(volume: number, type: GamingCanvasAudioType) {\n\t\tlet buffer: Buffer,\n\t\t\tbuffers: Buffer[] = GamingCanvasEngineAudio.buffers;\n\n\t\ttry {\n\t\t\t// Make sure it's in range\n\t\t\tvolume = Math.max(0, Math.min(1, volume));\n\n\t\t\t// Apply to global volumnes\n\t\t\tswitch (type) {\n\t\t\t\tcase GamingCanvasAudioType.ALL:\n\t\t\t\t\tGamingCanvasEngineAudio.volumeAll = volume;\n\t\t\t\t\tGamingCanvasEngineAudio.volumeAmbienceEff = GamingCanvasEngineAudio.volumeAmbience * GamingCanvasEngineAudio.volumeAll;\n\t\t\t\t\tGamingCanvasEngineAudio.volumeEffectEff = GamingCanvasEngineAudio.volumeEffect * GamingCanvasEngineAudio.volumeAll;\n\t\t\t\t\tGamingCanvasEngineAudio.volumeMusicEff = GamingCanvasEngineAudio.volumeMusic * GamingCanvasEngineAudio.volumeAll;\n\t\t\t\t\tGamingCanvasEngineAudio.volumeVoiceoverEff = GamingCanvasEngineAudio.volumeVoiceover * GamingCanvasEngineAudio.volumeAll;\n\t\t\t\t\tbreak;\n\t\t\t\tcase GamingCanvasAudioType.AMBIENCE:\n\t\t\t\t\tGamingCanvasEngineAudio.volumeAmbience = volume;\n\t\t\t\t\tGamingCanvasEngineAudio.volumeAmbienceEff = GamingCanvasEngineAudio.volumeAmbience * GamingCanvasEngineAudio.volumeAll;\n\t\t\t\t\tbreak;\n\t\t\t\tcase GamingCanvasAudioType.EFFECT:\n\t\t\t\t\tGamingCanvasEngineAudio.volumeEffect = volume;\n\t\t\t\t\tGamingCanvasEngineAudio.volumeEffectEff = GamingCanvasEngineAudio.volumeEffect * GamingCanvasEngineAudio.volumeAll;\n\t\t\t\t\tbreak;\n\t\t\t\tcase GamingCanvasAudioType.MUSIC:\n\t\t\t\t\tGamingCanvasEngineAudio.volumeMusic = volume;\n\t\t\t\t\tGamingCanvasEngineAudio.volumeMusicEff = GamingCanvasEngineAudio.volumeMusic * GamingCanvasEngineAudio.volumeAll;\n\t\t\t\t\tbreak;\n\t\t\t\tcase GamingCanvasAudioType.VOICEOVER:\n\t\t\t\t\tGamingCanvasEngineAudio.volumeVoiceover = volume;\n\t\t\t\t\tGamingCanvasEngineAudio.volumeVoiceoverEff = GamingCanvasEngineAudio.volumeVoiceover * GamingCanvasEngineAudio.volumeAll;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tconsole.error(`GamingCanvas > GamingCanvasEngineAudio > volumeGlobal: type ${type} is invalid`);\n\t\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Apply volume difference to buffers, as required\n\t\t\tfor (buffer of buffers) {\n\t\t\t\tif (type === GamingCanvasAudioType.ALL || buffer.type === type) {\n\t\t\t\t\tswitch (buffer.type) {\n\t\t\t\t\t\tcase GamingCanvasAudioType.AMBIENCE:\n\t\t\t\t\t\t\tbuffer.audio.volume = buffer.volumeRequested * GamingCanvasEngineAudio.volumeAmbienceEff;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase GamingCanvasAudioType.EFFECT:\n\t\t\t\t\t\t\tbuffer.audio.volume = buffer.volumeRequested * GamingCanvasEngineAudio.volumeEffectEff;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase GamingCanvasAudioType.MUSIC:\n\t\t\t\t\t\t\tbuffer.audio.volume = buffer.volumeRequested * GamingCanvasEngineAudio.volumeMusicEff;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase GamingCanvasAudioType.VOICEOVER:\n\t\t\t\t\t\t\tbuffer.audio.volume = buffer.volumeRequested * GamingCanvasEngineAudio.volumeVoiceoverEff;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(volume, GamingCanvasEngineAudio.volumeAll, error);\n\t\t}\n\t}\n\n\tpublic static setCallbackIsPermitted(callbackIsPermitted: (state: boolean) => void): void {\n\t\tGamingCanvasEngineAudio.callbackIsPermitted = callbackIsPermitted;\n\t}\n\n\tpublic static isMuted(): boolean {\n\t\treturn GamingCanvasEngineAudio.muted;\n\t}\n\n\tpublic static isPermitted(): boolean {\n\t\treturn GamingCanvasEngineAudio.permission;\n\t}\n}\n", "/**\n * @author tknight-dev\n */\n\nexport const GamingCanvasConstIntegerMaxSafe: number = Number.MAX_SAFE_INTEGER;\nexport const GamingCanvasConstIntegerMinSafe: number = Number.MIN_SAFE_INTEGER;\n\nexport const GamingCanvasConstPI_0_125: number = Math.PI * 0.125;\nexport const GamingCanvasConstPI_0_250: number = Math.PI * 0.25;\nexport const GamingCanvasConstPI_0_375: number = Math.PI * 0.375;\nexport const GamingCanvasConstPI_0_500: number = Math.PI * 0.5;\nexport const GamingCanvasConstPI_0_625: number = Math.PI * 0.625;\nexport const GamingCanvasConstPI_0_750: number = Math.PI * 0.75;\nexport const GamingCanvasConstPI_0_875: number = Math.PI * 0.875;\nexport const GamingCanvasConstPI_1_000: number = Math.PI;\nexport const GamingCanvasConstPI_1_125: number = Math.PI * 1.125;\nexport const GamingCanvasConstPI_1_250: number = Math.PI * 1.25;\nexport const GamingCanvasConstPI_1_375: number = Math.PI * 1.375;\nexport const GamingCanvasConstPI_1_500: number = Math.PI * 1.5;\nexport const GamingCanvasConstPI_1_625: number = Math.PI * 1.625;\nexport const GamingCanvasConstPI_1_750: number = Math.PI * 1.75;\nexport const GamingCanvasConstPI_1_875: number = Math.PI * 1.875;\nexport const GamingCanvasConstPI_2_000: number = Math.PI * 2;\n", "/**\n * IE a DLL (Double-Linked-List)\n *\n * @author tknight-dev\n */\n\nexport interface GamingCanvasDoubleLinkedListNode<T> {\n\tdata: T;\n\tnext: GamingCanvasDoubleLinkedListNode<T> | undefined;\n\tprevious: GamingCanvasDoubleLinkedListNode<T> | undefined;\n}\n\nexport class GamingCanvasDoubleLinkedList<T> {\n\tprivate end: GamingCanvasDoubleLinkedListNode<T> | undefined = undefined;\n\tprivate start: GamingCanvasDoubleLinkedListNode<T> | undefined = undefined;\n\tprivate _length: number = 0;\n\n\tpublic constructor(array?: T[]) {\n\t\tif (array !== undefined && Array.isArray(array)) {\n\t\t\tlet data: T, node: GamingCanvasDoubleLinkedListNode<T>;\n\n\t\t\tfor (data of array) {\n\t\t\t\tnode = {\n\t\t\t\t\tdata: data,\n\t\t\t\t\tnext: undefined,\n\t\t\t\t\tprevious: this._length !== 0 ? this.end : undefined,\n\t\t\t\t};\n\n\t\t\t\tif (this.end !== undefined) {\n\t\t\t\t\tthis.end.next = node;\n\t\t\t\t\tthis.end = node;\n\t\t\t\t} else {\n\t\t\t\t\tthis.end = node;\n\t\t\t\t\tthis.start = node;\n\t\t\t\t}\n\n\t\t\t\tthis._length++;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Remove all nodes\n\t */\n\tpublic clear(): void {\n\t\tthis.end = undefined;\n\t\tthis._length = 0;\n\t\tthis.start = undefined;\n\t}\n\n\tpublic getEnd(): GamingCanvasDoubleLinkedListNode<T> | undefined {\n\t\treturn this.end;\n\t}\n\n\tpublic getStart(): GamingCanvasDoubleLinkedListNode<T> | undefined {\n\t\treturn this.start;\n\t}\n\n\tpublic popEnd(): T | undefined {\n\t\tlet end: GamingCanvasDoubleLinkedListNode<T> | undefined = this.end;\n\n\t\tif (end !== undefined) {\n\t\t\tif (this._length === 1) {\n\t\t\t\tthis.end = undefined;\n\t\t\t\tthis.start = undefined;\n\t\t\t} else {\n\t\t\t\tthis.end = end.previous;\n\t\t\t}\n\n\t\t\tthis._length--;\n\t\t\treturn end.data;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic popStart(): T | undefined {\n\t\tlet start: GamingCanvasDoubleLinkedListNode<T> | undefined = this.start;\n\n\t\tif (start !== undefined) {\n\t\t\tif (this._length === 1) {\n\t\t\t\tthis.end = undefined;\n\t\t\t\tthis.start = undefined;\n\t\t\t} else {\n\t\t\t\tthis.start = start.next;\n\t\t\t}\n\n\t\t\tthis._length--;\n\t\t\treturn start.data;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic pushEnd(data: T): GamingCanvasDoubleLinkedListNode<T> {\n\t\tlet node: GamingCanvasDoubleLinkedListNode<T> = {\n\t\t\tdata: data,\n\t\t\tnext: undefined,\n\t\t\tprevious: this._length ? this.end : undefined,\n\t\t};\n\n\t\tif (this.end !== undefined) {\n\t\t\tthis.end.next = node;\n\t\t\tthis.end = node;\n\t\t} else {\n\t\t\tthis.end = node;\n\t\t\tthis.start = node;\n\t\t}\n\n\t\tthis._length++;\n\n\t\treturn node;\n\t}\n\n\tpublic pushStart(data: T): GamingCanvasDoubleLinkedListNode<T> {\n\t\tlet node: GamingCanvasDoubleLinkedListNode<T> = {\n\t\t\tdata: data,\n\t\t\tnext: this._length ? this.start : undefined,\n\t\t\tprevious: undefined,\n\t\t};\n\n\t\tif (this.start !== undefined) {\n\t\t\tthis.start.previous = node;\n\t\t\tthis.start = node;\n\t\t} else {\n\t\t\tthis.end = node;\n\t\t\tthis.start = node;\n\t\t}\n\n\t\tthis._length++;\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Caution: removing a node that doesn't actually exist in this list will cause the length of this list to be incorrect\n\t */\n\tpublic remove(node: GamingCanvasDoubleLinkedListNode<T>): GamingCanvasDoubleLinkedListNode<T> {\n\t\tif (this.end === node) {\n\t\t\tthis.end = node.previous;\n\t\t}\n\t\tif (this.start === node) {\n\t\t\tthis.start = node.next;\n\t\t}\n\t\tif (node.next !== undefined) {\n\t\t\tnode.next.previous = node.previous;\n\t\t}\n\t\tif (node.previous !== undefined) {\n\t\t\tnode.previous.next = node.next;\n\t\t}\n\n\t\tthis._length--;\n\n\t\treturn node;\n\t}\n\n\tpublic toArray(): T[] {\n\t\tlet array: T[] = new Array(this._length),\n\t\t\ti: number = 0,\n\t\t\tnode: GamingCanvasDoubleLinkedListNode<T> | undefined = this.start;\n\n\t\twhile (node) {\n\t\t\tarray[i++] = node.data;\n\t\t\tnode = node.next;\n\t\t}\n\n\t\treturn array;\n\t}\n\n\tpublic toJSON(): string {\n\t\treturn JSON.stringify(this.toArray());\n\t}\n\n\tpublic toString(): string {\n\t\treturn this.toArray().toString();\n\t}\n\n\tpublic get length(): number {\n\t\treturn this._length;\n\t}\n\n\tpublic forEach(callback: (value: T) => void): void {\n\t\tlet node: GamingCanvasDoubleLinkedListNode<T> | undefined = this.start;\n\t\twhile (node) {\n\t\t\tcallback(node.data);\n\t\t\tnode = node.next;\n\t\t}\n\t}\n\n\t[Symbol.iterator] = () => {\n\t\tlet i: number = 0,\n\t\t\tlength: number = this.length,\n\t\t\tnode: GamingCanvasDoubleLinkedListNode<T> | undefined = this.start;\n\n\t\treturn {\n\t\t\tnext() {\n\t\t\t\tif (length === 0 || i === length) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tdone: true,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tif (i !== 0) {\n\t\t\t\t\t\tnode = (<GamingCanvasDoubleLinkedListNode<T>>node).next;\n\t\t\t\t\t}\n\t\t\t\t\ti++;\n\t\t\t\t\treturn { value: node, done: false };\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t};\n}\n", "/**\n * @author tknight-dev\n */\n\nexport interface GamingCanvasInput {\n\tpropriatary: any;\n\ttype: GamingCanvasInputType;\n}\n\nexport interface GamingCanvasInputPosition extends GamingCanvasInputPositionBasic {\n\tout: boolean;\n\txRelative: number;\n\tyRelative: number;\n}\n\nexport interface GamingCanvasInputPositionBasic {\n\tx: number;\n\ty: number;\n}\n\nexport interface GamingCanvasInputPositionOverlay {\n\tcellSizePx: number;\n\tleft: number;\n\ttop: number;\n}\n\nexport const GamingCanvasInputPositionClone = (position: GamingCanvasInputPosition): GamingCanvasInputPosition => {\n\treturn {\n\t\tout: position.out,\n\t\tx: position.x,\n\t\txRelative: position.xRelative,\n\t\ty: position.y,\n\t\tyRelative: position.yRelative,\n\t};\n};\n\nexport const GamingCanvasInputPositionsClone = (positions: GamingCanvasInputPosition[]): GamingCanvasInputPosition[] => {\n\tlet clone: GamingCanvasInputPosition[] = new Array(positions.length),\n\t\ti = 0,\n\t\tposition: GamingCanvasInputPosition;\n\n\tfor (position of positions) {\n\t\tclone[i++] = {\n\t\t\tout: position.out,\n\t\t\tx: position.x,\n\t\t\txRelative: position.xRelative,\n\t\t\ty: position.y,\n\t\t\tyRelative: position.yRelative,\n\t\t};\n\t}\n\n\treturn clone;\n};\n\nexport const GamingCanvasInputPositionDistance = (a: GamingCanvasInputPositionBasic, b: GamingCanvasInputPositionBasic) => {\n\tconst x = a.x - b.x,\n\t\ty = a.y - b.y;\n\treturn (x * x + y * y) ** 0.5;\n};\n\nexport const GamingCanvasInputPositionDistanceRelative = (a: GamingCanvasInputPosition, b: GamingCanvasInputPosition) => {\n\tconst x = a.xRelative - b.xRelative,\n\t\ty = a.yRelative - b.yRelative;\n\treturn (x * x + y * y) ** 0.5;\n};\n\nexport enum GamingCanvasInputType {\n\tGAMEPAD,\n\tKEYBOARD,\n\tMOUSE,\n\tTOUCH,\n}\n", "import { GamingCanvasFIFOQueue } from '../fifo-queue.js';\nimport { GamingCanvasInput, GamingCanvasInputType } from '../inputs.js';\n\n/**\n * Triggers are axes in Firefox and buttons in Chrome\n *\n * @author tknight-dev\n */\n\nexport interface GamingCanvasInputGamepad extends GamingCanvasInput {\n\tpropriatary: {\n\t\taxes?: number[];\n\t\tbuttons?: { [key: number]: boolean };\n\t\tconnected: boolean;\n\t\tindex: number;\n\t};\n}\n\n/**\n * Format: XboxName__PlaystationName\n */\nexport enum GamingCanvasInputGamepadControllerButtons {\n\tA__X = 0,\n\tB__O = 1,\n\tBUMPER__LEFT = 4,\n\tBUMPER__RIGHT = 5,\n\tDPAD__DOWN = 13,\n\tDPAD__LEFT = 14,\n\tDPAD__RIGHT = 15,\n\tDPAD__UP = 12,\n\tHOME__HOME = 16,\n\tMENU__OPTIONS = 9,\n\tSTICK__LEFT = 10,\n\tSTICK__RIGHT = 11,\n\tTRIGGER__LEFT = 6,\n\tTRIGGER__RIGHT = 7,\n\tVIEW__SHARE = 8,\n\tX__TRIANGE = 3,\n\tY__SQUARE = 2,\n}\n\nexport enum GamingCanvasInputGamepadControllerVendor {\n\tMICROSOFT = '045E',\n\tSONY = '054C',\n}\n\nexport interface GamingCanvasInputGamepadState {\n\tconnected: boolean;\n\tidDevice: string;\n\tidVendor: string;\n\ttimestamp: number;\n}\n\nexport class GamingCanvasEngineGamepad {\n\tpublic static active: boolean = true;\n\tprivate static axesByIndex: { [key: number]: number[] } = {};\n\tprivate static buttonsByIndex: { [key: number]: boolean[] } = {};\n\tprivate static gamepadByIndex: { [key: number]: Gamepad } = {};\n\tprivate static queue: GamingCanvasFIFOQueue<GamingCanvasInput>;\n\tprivate static quit: boolean;\n\tprivate static scannerRequest: number;\n\tprivate static statesByIndex: { [key: number]: GamingCanvasInputGamepadState } = {};\n\n\tpublic static initialize(queue: GamingCanvasFIFOQueue<GamingCanvasInput>, deadbandStick: number): void {\n\t\tGamingCanvasEngineGamepad.active = true;\n\t\tGamingCanvasEngineGamepad.queue = queue;\n\t\tGamingCanvasEngineGamepad.quit = false;\n\n\t\t/*\n\t\t * Connection\n\t\t */\n\t\tconst connectionChange = (event: GamepadEvent) => {\n\t\t\t/*\n\t\t\t * State\n\t\t\t */\n\t\t\tconst gamepad: Gamepad = event.gamepad,\n\t\t\t\tconnected: boolean = gamepad.connected,\n\t\t\t\tid: string = gamepad.id,\n\t\t\t\tindex: number = gamepad.index;\n\t\t\tlet state: GamingCanvasInputGamepadState = GamingCanvasEngineGamepad.statesByIndex[index];\n\n\t\t\tif (state) {\n\t\t\t\tstate.connected = connected;\n\t\t\t\tstate.timestamp = gamepad.timestamp;\n\t\t\t} else {\n\t\t\t\tGamingCanvasEngineGamepad.statesByIndex[index] = {\n\t\t\t\t\tconnected: connected,\n\t\t\t\t\tidDevice: id.substring(5, 9).toUpperCase(),\n\t\t\t\t\tidVendor: id.substring(0, 4).toUpperCase(),\n\t\t\t\t\ttimestamp: gamepad.timestamp,\n\t\t\t\t};\n\t\t\t\tstate = GamingCanvasEngineGamepad.statesByIndex[index];\n\t\t\t}\n\t\t\tGamingCanvasEngineGamepad.axesByIndex[index] = new Array(4).fill(0);\n\t\t\tGamingCanvasEngineGamepad.buttonsByIndex[index] = new Array(gamepad.buttons.length).fill(false);\n\t\t\tGamingCanvasEngineGamepad.gamepadByIndex[index] = gamepad;\n\n\t\t\t/*\n\t\t\t * Queue\n\t\t\t */\n\t\t\tif (GamingCanvasEngineGamepad.active) {\n\t\t\t\tGamingCanvasEngineGamepad.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\tconnected: connected,\n\t\t\t\t\t\tindex: index,\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.GAMEPAD,\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\taddEventListener('gamepadconnected', connectionChange);\n\t\taddEventListener('gamepaddisconnected', connectionChange);\n\n\t\t/*\n\t\t * Scanner\n\t\t */\n\t\tlet axes: number[],\n\t\t\tbuttons: boolean[],\n\t\t\tbuttonsChanged: { [key: number]: boolean } | undefined,\n\t\t\tchangedAxes: boolean,\n\t\t\tchangedButtons: boolean,\n\t\t\tfirefox: boolean = navigator.userAgent.toLowerCase().includes('firefox'),\n\t\t\tgamepads: (Gamepad | null)[],\n\t\t\tgamepad: Gamepad | null,\n\t\t\ti: number,\n\t\t\tindex: number,\n\t\t\tstate: GamingCanvasInputGamepadState,\n\t\t\ttimestamp: number = 0,\n\t\t\tvalue: number;\n\n\t\tconst axesByIndex: { [key: number]: number[] } = GamingCanvasEngineGamepad.axesByIndex,\n\t\t\tbuttonsByIndex: { [key: number]: boolean[] } = GamingCanvasEngineGamepad.buttonsByIndex,\n\t\t\tstatesByIndex: { [key: number]: GamingCanvasInputGamepadState } = GamingCanvasEngineGamepad.statesByIndex;\n\t\tconst scanner = (timestampNow: number) => {\n\t\t\t// Always request the next animation frame before processing the current one for best performance\n\t\t\tGamingCanvasEngineGamepad.scannerRequest = requestAnimationFrame(scanner);\n\n\t\t\t// Limit how often we check for inputs. Controllers can be really chatty on the communication bus.\n\t\t\tif (GamingCanvasEngineGamepad.active === true && timestampNow - timestamp > 4) {\n\t\t\t\tgamepads = navigator.getGamepads();\n\t\t\t\ttimestamp = timestampNow;\n\n\t\t\t\tfor (gamepad of gamepads) {\n\t\t\t\t\tif (GamingCanvasEngineGamepad.quit !== true && gamepad !== null) {\n\t\t\t\t\t\tindex = gamepad.index;\n\t\t\t\t\t\tstate = statesByIndex[index];\n\n\t\t\t\t\t\t// New input for processing!\n\t\t\t\t\t\tif (gamepad.timestamp !== state.timestamp) {\n\t\t\t\t\t\t\tstate.timestamp = gamepad.timestamp;\n\n\t\t\t\t\t\t\t// Axis\n\t\t\t\t\t\t\taxes = axesByIndex[index];\n\t\t\t\t\t\t\tchangedAxes = false;\n\n\t\t\t\t\t\t\t// Firefox: skip triggers as Chrome treats them as buttons\n\t\t\t\t\t\t\tfor (i = 0; i < Math.min(4, gamepad.axes.length); i++) {\n\t\t\t\t\t\t\t\tif (firefox && state.idVendor === GamingCanvasInputGamepadControllerVendor.MICROSOFT && i > 1) {\n\t\t\t\t\t\t\t\t\t// Fix for Firefox bug of detecting another axes [x,y] between the left and right stick for xbox controllers\n\t\t\t\t\t\t\t\t\tvalue = gamepad.axes[i + 2];\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tvalue = gamepad.axes[i];\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (value > -deadbandStick && value < deadbandStick) {\n\t\t\t\t\t\t\t\t\tvalue = 0;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (axes[i] !== value) {\n\t\t\t\t\t\t\t\t\taxes[i] = value;\n\t\t\t\t\t\t\t\t\tchangedAxes = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Buttons\n\t\t\t\t\t\t\tbuttons = buttonsByIndex[index];\n\t\t\t\t\t\t\tbuttonsChanged = undefined;\n\t\t\t\t\t\t\tchangedButtons = false;\n\t\t\t\t\t\t\tfor (i = 0; i < gamepad.buttons.length; i++) {\n\t\t\t\t\t\t\t\tif (i === 6 || i === 7) {\n\t\t\t\t\t\t\t\t\t// Chrome: skip triggers as Firefox treats them as axes\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (buttons[i] !== gamepad.buttons[i].pressed) {\n\t\t\t\t\t\t\t\t\tbuttons[i] = gamepad.buttons[i].pressed;\n\n\t\t\t\t\t\t\t\t\tif (buttonsChanged === undefined) {\n\t\t\t\t\t\t\t\t\t\tbuttonsChanged = <{ [key: number]: boolean }>new Object();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbuttonsChanged[i] = buttons[i];\n\t\t\t\t\t\t\t\t\tchangedButtons = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (changedAxes || changedButtons) {\n\t\t\t\t\t\t\t\tGamingCanvasEngineGamepad.queue.push({\n\t\t\t\t\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\t\t\t\t\taxes: changedAxes ? axes : undefined,\n\t\t\t\t\t\t\t\t\t\tbuttons: buttonsChanged,\n\t\t\t\t\t\t\t\t\t\tconnected: gamepad.connected,\n\t\t\t\t\t\t\t\t\t\tindex: index,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\ttype: GamingCanvasInputType.GAMEPAD,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tGamingCanvasEngineGamepad.scannerRequest = requestAnimationFrame(scanner);\n\t}\n\n\tpublic static getGamepads(): { [key: string]: GamingCanvasInputGamepadState } {\n\t\treturn JSON.parse(JSON.stringify(GamingCanvasEngineGamepad.statesByIndex));\n\t}\n\n\tpublic static shutdown(): void {\n\t\tcancelAnimationFrame(GamingCanvasEngineGamepad.scannerRequest);\n\t\tGamingCanvasEngineGamepad.quit = true;\n\t}\n}\n", "import { GamingCanvasFIFOQueue } from '../fifo-queue.js';\nimport { GamingCanvasInput, GamingCanvasInputType } from '../inputs.js';\n\n/**\n * Repeating keys (key held down) are filtered out\n *\n * @author tknight-dev\n */\n\n// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent\nexport interface GamingCanvasInputKeyboardAction {\n\tcode: string;\n\tkey: string;\n\tkeyCtrl: boolean;\n\tkeyShift: boolean;\n\tlocation: GamingCanvasInputKeyboardActionLocation;\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#keyboard_locations\nexport enum GamingCanvasInputKeyboardActionLocation {\n\tLEFT = 1,\n\tRIGHT = 2,\n\tSTANDARD = 0,\n}\n\nexport interface GamingCanvasInputKeyboard extends GamingCanvasInput {\n\tpropriatary: {\n\t\taction: GamingCanvasInputKeyboardAction;\n\t\tdown: boolean;\n\t};\n}\n\nexport class GamingCanvasEngineKeyboard {\n\tpublic static active: boolean = true;\n\tprivate static queue: GamingCanvasFIFOQueue<GamingCanvasInput>;\n\n\tpublic static initialize(\n\t\tqueue: GamingCanvasFIFOQueue<GamingCanvasInput>,\n\t\tpreventAlt: boolean,\n\t\tpreventCntrl: boolean,\n\t\tpreventMeta: boolean,\n\t\tpreventShift: boolean,\n\t\tpreventTab: boolean,\n\t): void {\n\t\tGamingCanvasEngineKeyboard.active = true;\n\t\tGamingCanvasEngineKeyboard.queue = queue;\n\n\t\tdocument.addEventListener('keydown', (event: KeyboardEvent) => {\n\t\t\tif (GamingCanvasEngineKeyboard.active === true) {\n\t\t\t\tif (\n\t\t\t\t\t(preventAlt === true && event.altKey === true) ||\n\t\t\t\t\t(preventCntrl === true && event.ctrlKey === true) ||\n\t\t\t\t\t(preventMeta === true && event.metaKey === true) ||\n\t\t\t\t\t(preventShift === true && event.shiftKey === true) ||\n\t\t\t\t\t(preventTab === true && event.code === 'Tab')\n\t\t\t\t) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t\tif (event.repeat !== true) {\n\t\t\t\t\tGamingCanvasEngineKeyboard.queue.push({\n\t\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\t\tcode: event.code,\n\t\t\t\t\t\t\t\tkey: event.key,\n\t\t\t\t\t\t\t\tkeyCtrl: event.ctrlKey,\n\t\t\t\t\t\t\t\tkeyShift: event.shiftKey,\n\t\t\t\t\t\t\t\tlocation: event.location,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdown: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttype: GamingCanvasInputType.KEYBOARD,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tdocument.addEventListener('keyup', (event: KeyboardEvent) => {\n\t\t\tif (GamingCanvasEngineKeyboard.active === true) {\n\t\t\t\tif (\n\t\t\t\t\t(preventAlt === true && event.altKey === true) ||\n\t\t\t\t\t(preventCntrl === true && event.ctrlKey === true) ||\n\t\t\t\t\t(preventMeta === true && event.metaKey === true) ||\n\t\t\t\t\t(preventShift === true && event.shiftKey === true) ||\n\t\t\t\t\t(preventTab === true && event.code === 'Tab')\n\t\t\t\t) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t\tGamingCanvasEngineKeyboard.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: {\n\t\t\t\t\t\t\tcode: event.code,\n\t\t\t\t\t\t\tkey: event.key,\n\t\t\t\t\t\t\tkeyCtrl: event.ctrlKey,\n\t\t\t\t\t\t\tkeyShift: event.shiftKey,\n\t\t\t\t\t\t\tlocation: event.location,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdown: false,\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.KEYBOARD,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n}\n", "import { GamingCanvasFIFOQueue } from '../fifo-queue.js';\nimport { GamingCanvasInput, GamingCanvasInputPosition, GamingCanvasInputType } from '../inputs.js';\n\n/**\n * @author tknight-dev\n */\n\nexport enum GamingCanvasInputMouseAction {\n\tLEFT, // GamingCanvasMousedown and GamingCanvasMouseup based triggers\n\tLEFT_CLICK, // click based trigger\n\tRIGHT, // GamingCanvasMousedown and GamingCanvasMouseup based triggers\n\tRIGHT_CLICK, // click based trigger\n\tMOVE, // GamingCanvasMousemove based trigger\n\tSCROLL, // SCROLL based trigger\n\tWHEEL, // GamingCanvasMousedown and GamingCanvasMouseup based triggers\n\tWHEEL_CLICK, // click based trigger\n}\n\nexport interface GamingCanvasInputMouse extends GamingCanvasInput {\n\tpropriatary: {\n\t\taction: GamingCanvasInputMouseAction;\n\t\tdown?: boolean;\n\t\tmovementX?: number;\n\t\tmovementY?: number;\n\t\tposition: GamingCanvasInputPosition;\n\t};\n}\n\nexport class GamingCanvasEngineMouse {\n\tpublic static active: boolean = true;\n\tpublic static callbackLocked: (state: boolean) => void;\n\tprivate static el: HTMLElement;\n\tprivate static elInteractive: HTMLElement | undefined;\n\tprivate static locked: boolean;\n\tprivate static lockHooked: boolean;\n\tprivate static queue: GamingCanvasFIFOQueue<GamingCanvasInput>;\n\n\t/**\n\t * Function forwarding: Reduce garbage collector demand be reducing temporary variables (best performance for repeating functions\n\t */\n\tstatic {\n\t\tGamingCanvasEngineMouse.calc__funcForward();\n\t}\n\n\tprivate static calc(_event: MouseEvent): GamingCanvasInputPosition {\n\t\treturn <GamingCanvasInputPosition>(<unknown>undefined);\n\t}\n\n\tprivate static calc__funcForward(): void {\n\t\tlet domRect: DOMRect, domRectHeight: number, domRectWidth: number, xEff: number, yEff: number;\n\n\t\tconst calc = (event: MouseEvent) => {\n\t\t\tdomRect = GamingCanvasEngineMouse.el.getBoundingClientRect();\n\t\t\tdomRectHeight = domRect.height | 0;\n\t\t\tdomRectWidth = domRect.width | 0;\n\n\t\t\txEff = Math.max(0, Math.min(domRectWidth, event.clientX - domRect.x)) | 0;\n\t\t\tyEff = Math.max(0, Math.min(domRectHeight, event.clientY - domRect.y)) | 0;\n\n\t\t\treturn {\n\t\t\t\tout: xEff === 0 || yEff === 0 || xEff === domRectWidth || yEff === domRectHeight,\n\t\t\t\tx: xEff,\n\t\t\t\txRelative: xEff / domRectWidth,\n\t\t\t\ty: yEff,\n\t\t\t\tyRelative: yEff / domRectHeight,\n\t\t\t};\n\t\t};\n\t\tGamingCanvasEngineMouse.calc = calc;\n\t}\n\n\tpublic static initialize(\n\t\telInputs: HTMLElement,\n\t\telInteractive: HTMLElement | undefined,\n\t\tqueue: GamingCanvasFIFOQueue<GamingCanvasInput>,\n\t\tpreventContextMenu: boolean,\n\t): void {\n\t\tGamingCanvasEngineMouse.active = true;\n\t\tGamingCanvasEngineMouse.el = elInputs;\n\t\tGamingCanvasEngineMouse.queue = queue;\n\n\t\t// Context Menu\n\t\tconst contextmenu = (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && preventContextMenu === true) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\t\t(elInteractive || document.body).addEventListener('contextmenu', contextmenu);\n\n\t\t// Mouse: Click\n\t\tlet clickAction: GamingCanvasInputMouseAction;\n\t\tdocument.addEventListener('click', (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked === true && event.button < 3) {\n\t\t\t\tif (event.button === 0) {\n\t\t\t\t\tclickAction = GamingCanvasInputMouseAction.LEFT_CLICK;\n\t\t\t\t} else if (event.button === 1) {\n\t\t\t\t\tclickAction = GamingCanvasInputMouseAction.WHEEL_CLICK;\n\t\t\t\t} else {\n\t\t\t\t\tclickAction = GamingCanvasInputMouseAction.RIGHT_CLICK;\n\t\t\t\t}\n\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: clickAction,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t(elInteractive || document.body).addEventListener('click', (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked !== true && event.button < 3) {\n\t\t\t\tif (event.button === 0) {\n\t\t\t\t\tclickAction = GamingCanvasInputMouseAction.LEFT_CLICK;\n\t\t\t\t} else if (event.button === 1) {\n\t\t\t\t\tclickAction = GamingCanvasInputMouseAction.WHEEL_CLICK;\n\t\t\t\t} else {\n\t\t\t\t\tclickAction = GamingCanvasInputMouseAction.RIGHT_CLICK;\n\t\t\t\t}\n\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: clickAction,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Mouse: Down\n\t\tlet mousedownAction: GamingCanvasInputMouseAction;\n\t\tdocument.addEventListener('mousedown', (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.locked === true) {\n\t\t\t\tif (event.button === 0) {\n\t\t\t\t\tmousedownAction = GamingCanvasInputMouseAction.LEFT;\n\t\t\t\t} else if (event.button === 1) {\n\t\t\t\t\tmousedownAction = GamingCanvasInputMouseAction.WHEEL;\n\t\t\t\t} else {\n\t\t\t\t\tmousedownAction = GamingCanvasInputMouseAction.RIGHT;\n\t\t\t\t}\n\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: mousedownAction,\n\t\t\t\t\t\tdown: true,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t(elInteractive || document.body).addEventListener('mousedown', (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked !== true && event.button < 3) {\n\t\t\t\tif (event.button === 0) {\n\t\t\t\t\tmousedownAction = GamingCanvasInputMouseAction.LEFT;\n\t\t\t\t} else if (event.button === 1) {\n\t\t\t\t\tmousedownAction = GamingCanvasInputMouseAction.WHEEL;\n\t\t\t\t} else {\n\t\t\t\t\tmousedownAction = GamingCanvasInputMouseAction.RIGHT;\n\t\t\t\t}\n\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: mousedownAction,\n\t\t\t\t\t\tdown: true,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Mouse: Move\n\t\tdocument.addEventListener('mousemove', (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked === true) {\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: GamingCanvasInputMouseAction.MOVE,\n\t\t\t\t\t\tmovementX: event.movementX,\n\t\t\t\t\t\tmovementY: event.movementY,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t(elInteractive || document.body).addEventListener('mousemove', (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked !== true) {\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: GamingCanvasInputMouseAction.MOVE,\n\t\t\t\t\t\tmovementX: event.movementX,\n\t\t\t\t\t\tmovementY: event.movementY,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Mouse: Down\n\t\tlet mouseupAction: GamingCanvasInputMouseAction;\n\t\tdocument.addEventListener('mouseup', (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked === true && event.button < 3) {\n\t\t\t\tif (event.button === 0) {\n\t\t\t\t\tmouseupAction = GamingCanvasInputMouseAction.LEFT;\n\t\t\t\t} else if (event.button === 1) {\n\t\t\t\t\tmouseupAction = GamingCanvasInputMouseAction.WHEEL;\n\t\t\t\t} else {\n\t\t\t\t\tmouseupAction = GamingCanvasInputMouseAction.RIGHT;\n\t\t\t\t}\n\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: mouseupAction,\n\t\t\t\t\t\tdown: false,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t(elInteractive || document.body).addEventListener('mouseup', (event: MouseEvent) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked !== true && event.button < 3) {\n\t\t\t\tif (event.button === 0) {\n\t\t\t\t\tmouseupAction = GamingCanvasInputMouseAction.LEFT;\n\t\t\t\t} else if (event.button === 1) {\n\t\t\t\t\tmouseupAction = GamingCanvasInputMouseAction.WHEEL;\n\t\t\t\t} else {\n\t\t\t\t\tmouseupAction = GamingCanvasInputMouseAction.RIGHT;\n\t\t\t\t}\n\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: mouseupAction,\n\t\t\t\t\t\tdown: false,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// Pointer Lock\n\t\tif (GamingCanvasEngineMouse.lockHooked !== true) {\n\t\t\tGamingCanvasEngineMouse.lockHooked = true;\n\n\t\t\tdocument.addEventListener('pointerlockchange', () => {\n\t\t\t\tGamingCanvasEngineMouse.locked = document.pointerLockElement === (GamingCanvasEngineMouse.elInteractive || document.body);\n\n\t\t\t\tif (GamingCanvasEngineMouse.callbackLocked !== undefined) {\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tGamingCanvasEngineMouse.callbackLocked(GamingCanvasEngineMouse.locked);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tdocument.addEventListener('pointerlockerror', (event: Event) => {\n\t\t\t\tconsole.error('GamingCanvasEngineMouse: pointer locked failed with', event);\n\t\t\t});\n\t\t}\n\n\t\t// Wheel\n\t\tdocument.addEventListener('wheel', (event: any) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked === true) {\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: GamingCanvasInputMouseAction.SCROLL,\n\t\t\t\t\t\tdown: event.deltaY > 0,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t(elInteractive || document.body).addEventListener('wheel', (event: any) => {\n\t\t\tif (GamingCanvasEngineMouse.active === true && GamingCanvasEngineMouse.locked !== true) {\n\t\t\t\tGamingCanvasEngineMouse.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: GamingCanvasInputMouseAction.SCROLL,\n\t\t\t\t\t\tdown: event.deltaY > 0,\n\t\t\t\t\t\tposition: GamingCanvasEngineMouse.calc(event),\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.MOUSE,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * @param unadjustedMovement when true, disables OS-level mouse acceleration and access raw mouse input\n\t */\n\tpublic static async lock(unadjustedMovement?: boolean): Promise<boolean> {\n\t\ttry {\n\t\t\tawait (GamingCanvasEngineMouse.elInteractive || document.body).requestPointerLock({\n\t\t\t\tunadjustedMovement: unadjustedMovement,\n\t\t\t});\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tconsole.error('GamingCanvas > GamingCanvasEngineMouse > lock: unable to aquire due to', (<any>error).name);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic static unlock(): void {\n\t\tdocument.exitPointerLock();\n\t}\n\n\tpublic static isLocked(): boolean {\n\t\treturn GamingCanvasEngineMouse.locked;\n\t}\n}\n", "import { GamingCanvasFIFOQueue } from '../fifo-queue.js';\nimport { GamingCanvasInput, GamingCanvasInputPosition, GamingCanvasInputType } from '../inputs.js';\n\n/**\n * @author tknight-dev\n */\n\nexport enum GamingCanvasInputTouchAction {\n\tACTIVE, // A finger is touching the screen\n\tMOVE,\n}\n\nexport interface GamingCanvasInputTouch extends GamingCanvasInput {\n\tpropriatary: {\n\t\taction: GamingCanvasInputTouchAction;\n\t\tdown?: boolean;\n\t\tpositions: GamingCanvasInputPosition[];\n\t};\n}\n\nexport class GamingCanvasEngineTouch {\n\tpublic static active: boolean = true;\n\tprivate static el: HTMLElement;\n\tprivate static queue: GamingCanvasFIFOQueue<GamingCanvasInput>;\n\tprivate static timeout: ReturnType<typeof setTimeout>;\n\tprivate static timestamp: number = -2025;\n\n\t/**\n\t * Function forwarding: Reduce garbage collector demand be reducing temporary variables (best performance for repeating functions\n\t */\n\tstatic {\n\t\tGamingCanvasEngineTouch.calc__funcForward();\n\t}\n\n\tprivate static calc(_event: TouchEvent): GamingCanvasInputPosition[] {\n\t\treturn <GamingCanvasInputPosition[]>(<unknown>undefined);\n\t}\n\n\tprivate static calc__funcForward(): void {\n\t\tlet domRect: DOMRect,\n\t\t\tdomRectHeight: number,\n\t\t\tdomRectWidth: number,\n\t\t\ttouch: Touch,\n\t\t\ttouchLength: number,\n\t\t\ttouchList: TouchList,\n\t\t\ttouchPositions: GamingCanvasInputPosition[],\n\t\t\txEff: number,\n\t\t\tyEff: number;\n\n\t\tconst calc = (event: TouchEvent) => {\n\t\t\tdomRect = GamingCanvasEngineTouch.el.getBoundingClientRect();\n\t\t\tdomRectHeight = domRect.height | 0;\n\t\t\tdomRectWidth = domRect.width | 0;\n\t\t\ttouchLength = event.touches.length;\n\t\t\ttouchList = event.touches;\n\t\t\ttouchPositions = [];\n\n\t\t\tfor (let i = 0; i < touchLength; i++) {\n\t\t\t\ttouch = touchList[i];\n\n\t\t\t\txEff = Math.max(0, Math.min(domRectWidth, touch.clientX - domRect.x)) | 0;\n\t\t\t\tyEff = Math.max(0, Math.min(domRectHeight, touch.clientY - domRect.y)) | 0;\n\n\t\t\t\ttouchPositions.push({\n\t\t\t\t\tout: xEff === 0 || yEff === 0 || xEff === domRectWidth || yEff === domRectHeight,\n\t\t\t\t\tx: xEff,\n\t\t\t\t\txRelative: xEff / domRectWidth,\n\t\t\t\t\ty: yEff,\n\t\t\t\t\tyRelative: yEff / domRectHeight,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn touchPositions;\n\t\t};\n\t\tGamingCanvasEngineTouch.calc = calc;\n\t}\n\n\tpublic static initialize(\n\t\telInputs: HTMLElement,\n\t\telInteractive: HTMLElement | undefined,\n\t\tinputLimitPerMs: number,\n\t\tqueue: GamingCanvasFIFOQueue<GamingCanvasInput>,\n\t): void {\n\t\tGamingCanvasEngineTouch.active = true;\n\t\tGamingCanvasEngineTouch.el = elInputs;\n\t\tGamingCanvasEngineTouch.queue = queue;\n\n\t\tconst touchActive = (down: boolean, event: TouchEvent, positions: GamingCanvasInputPosition[]): boolean => {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tif (GamingCanvasEngineTouch.active) {\n\t\t\t\tclearTimeout(GamingCanvasEngineTouch.timeout);\n\t\t\t\tGamingCanvasEngineTouch.queue.push({\n\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\taction: GamingCanvasInputTouchAction.ACTIVE,\n\t\t\t\t\t\tdown: down,\n\t\t\t\t\t\tpositions: positions,\n\t\t\t\t\t},\n\t\t\t\t\ttype: GamingCanvasInputType.TOUCH,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn false;\n\t\t};\n\n\t\t(elInteractive || document.body).addEventListener('touchcancel', (event: TouchEvent) => {\n\t\t\treturn touchActive(false, event, []);\n\t\t});\n\n\t\t(elInteractive || document.body).addEventListener('touchend', (event: TouchEvent) => {\n\t\t\treturn touchActive(false, event, GamingCanvasEngineTouch.calc(event));\n\t\t});\n\n\t\tlet touchmoveDiff: number, touchmoveNow: number;\n\t\t(elInteractive || document.body).addEventListener('touchmove', (event: TouchEvent) => {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\n\t\t\tif (GamingCanvasEngineTouch.active) {\n\t\t\t\t((touchmoveNow = performance.now()), (touchmoveDiff = touchmoveNow - GamingCanvasEngineTouch.timestamp));\n\n\t\t\t\tif (touchmoveDiff > inputLimitPerMs) {\n\t\t\t\t\tclearTimeout(GamingCanvasEngineTouch.timeout);\n\t\t\t\t\tGamingCanvasEngineTouch.queue.push({\n\t\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\t\taction: GamingCanvasInputTouchAction.MOVE,\n\t\t\t\t\t\t\tpositions: GamingCanvasEngineTouch.calc(event),\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttype: GamingCanvasInputType.TOUCH,\n\t\t\t\t\t});\n\n\t\t\t\t\tGamingCanvasEngineTouch.timestamp = touchmoveNow;\n\t\t\t\t} else {\n\t\t\t\t\tclearTimeout(GamingCanvasEngineTouch.timeout);\n\t\t\t\t\tGamingCanvasEngineTouch.timeout = setTimeout(() => {\n\t\t\t\t\t\tGamingCanvasEngineTouch.queue.push({\n\t\t\t\t\t\t\tpropriatary: {\n\t\t\t\t\t\t\t\taction: GamingCanvasInputTouchAction.MOVE,\n\t\t\t\t\t\t\t\tpositions: GamingCanvasEngineTouch.calc(event),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttype: GamingCanvasInputType.TOUCH,\n\t\t\t\t\t\t});\n\t\t\t\t\t}, touchmoveDiff - inputLimitPerMs);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t});\n\n\t\t(elInteractive || document.body).addEventListener('touchstart', (event: TouchEvent) => {\n\t\t\treturn touchActive(true, event, GamingCanvasEngineTouch.calc(event));\n\t\t});\n\t}\n}\n", "/**\n * @author tknight-dev\n */\n\nexport enum GamingCanvasOptionsDetectDeviceType {\n\tMOBILE,\n\tPC,\n\tTABLET,\n}\n\nexport class GamingCanvasOptions {\n\taspectRatio?: number;\n\taudioBufferCount?: number;\n\taudioEnable?: boolean;\n\tcallbackReportLimitPerMs?: number;\n\tcanvasCount?: number;\n\tcanvasSplit?: number[];\n\tcanvasSplitLandscapeVertical?: boolean;\n\tdebug?: boolean;\n\tdpiSupportEnable?: boolean;\n\telementInteractive?: HTMLElement;\n\telementInjectAsCanvas?: HTMLElement[];\n\telementInjectAsOverlay?: HTMLElement[];\n\tinputGamepadDeadbandStick?: number;\n\tinputGamepadEnable?: boolean;\n\tinputKeyboardEnable?: boolean;\n\tinputKeyboardPreventAlt?: boolean;\n\tinputKeyboardPreventCntrl?: boolean;\n\tinputKeyboardPreventMeta?: boolean;\n\tinputKeyboardPreventShift?: boolean;\n\tinputKeyboardPreventTab?: boolean;\n\tinputMouseEnable?: boolean;\n\tinputMousePreventContextMenu?: boolean;\n\tinputTouchEnable?: boolean;\n\tinputLimitPerMs?: number;\n\torientation?: GamingCanvasOrientation;\n\torientationCanvasRotateEnable?: boolean;\n\torientationCanvasPortaitRotateLeft?: boolean;\n\trenderStyle?: GamingCanvasRenderStyle;\n\tresolutionScaleToFit?: boolean;\n\tresolutionWidthPx?: null | number;\n}\n\nexport enum GamingCanvasOrientation {\n\tAUTO,\n\tLANDSCAPE,\n\tPORTRAIT,\n}\n\nexport interface GamingCanvasReport {\n\tcanvasHeight: number;\n\tcanvasHeightSplit: number;\n\tcanvasWidth: number;\n\tcanvasWidthSplit: number;\n\tdevicePixelRatio: number;\n\torientation: GamingCanvasOrientation;\n\torientationCanvasRotated: boolean;\n\tscaler: number;\n}\n\nexport enum GamingCanvasRenderStyle {\n\tANTIALIAS,\n\tPIXELATED,\n}\n", "import { GamingCanvasFIFOQueue } from './fifo-queue.js';\nimport { GamingCanvasInput, GamingCanvasInputPosition, GamingCanvasInputType } from './inputs.js';\nimport { GamingCanvasOptions, GamingCanvasOrientation, GamingCanvasReport, GamingCanvasRenderStyle, GamingCanvasOptionsDetectDeviceType } from './models.js';\nimport { GamingCanvasAudioType, GamingCanvasEngineAudio } from './engines/audio.engine.js';\nimport { GamingCanvasEngineGamepad, GamingCanvasInputGamepadState } from './engines/gamepad.engine.js';\nimport { GamingCanvasEngineKeyboard } from './engines/keyboard.engine.js';\nimport { GamingCanvasEngineMouse } from './engines/mouse.engine.js';\nimport { GamingCanvasEngineTouch } from './engines/touch.engine.js';\n\n/**\n * Canvas:\n * \t-\tDimensions are not automatically set here as the canvas could be controlled by another thread (primary vs WebWorkers(s))\n * \t-\tDimensions are rounded down to the nearest pixel for optimal canvas performance\n *\n * Debug: The green border is the the top-right of the canvas element\n *\n * @author tknight-dev\n */\n\nexport class GamingCanvas {\n\tprivate static callbackFullscreen: (state: boolean) => void;\n\tprivate static callbackReport: (report: GamingCanvasReport) => void;\n\tprivate static callbackReportLastInMs: number = -2025;\n\tprivate static callbackReportTimeout: ReturnType<typeof setTimeout>;\n\tprivate static callbackVisibility: (state: boolean) => void;\n\tprivate static elementCanvases: HTMLCanvasElement[];\n\tprivate static elementCanvasesSplit: HTMLCanvasElement[];\n\tprivate static elementContainer: HTMLElement;\n\tprivate static elementContainerCanvas: HTMLDivElement;\n\tprivate static elementContainerCanvasInputs: HTMLDivElement;\n\tprivate static elementContainerOverlay: HTMLDivElement;\n\tprivate static elementContainerOverlayWrapper: HTMLDivElement;\n\tprivate static elementParent: HTMLElement;\n\tprivate static elementRotator1: HTMLDivElement;\n\tprivate static elementRotator2: HTMLDivElement;\n\tprivate static inputQueue: GamingCanvasFIFOQueue<GamingCanvasInput> = new GamingCanvasFIFOQueue<GamingCanvasInput>();\n\tprivate static options: GamingCanvasOptions;\n\tprivate static regExpScale: RegExp = /(?<=scale\\()(.*?)(?=\\))/;\n\tprivate static stateFullscreen: boolean;\n\tprivate static stateHeight: number;\n\tprivate static stateOrientation: GamingCanvasOrientation;\n\tprivate static stateReport: GamingCanvasReport;\n\tprivate static stateScaler: number;\n\tprivate static stateVisibility: boolean;\n\tprivate static stateWakeLock: WakeLockSentinel | undefined;\n\tprivate static stateWakeLockState: boolean;\n\tprivate static stateWidth: number;\n\tprivate static vibrateInterval: ReturnType<typeof setInterval>;\n\n\t/**\n\t * Function Forwarding: Reduce garbage collector demand be reducing temporary variables (best performance for repeating functions)\n\t */\n\tstatic {\n\t\tGamingCanvas.go__funcForward();\n\t\tGamingCanvas.relativizeInputToCanvas__funcForward();\n\n\t\t// Function Forward: Engine Audio\n\t\tGamingCanvas.audioControlPan = GamingCanvasEngineAudio.controlPan;\n\t\tGamingCanvas.audioControlPause = GamingCanvasEngineAudio.controlPause;\n\t\tGamingCanvas.audioControlPauseAll = GamingCanvasEngineAudio.controlPauseAll;\n\t\tGamingCanvas.audioControlPlay = GamingCanvasEngineAudio.controlPlay;\n\t\tGamingCanvas.audioControlStop = GamingCanvasEngineAudio.controlStop;\n\t\tGamingCanvas.audioControlStopAll = GamingCanvasEngineAudio.controlStopAll;\n\t\tGamingCanvas.audioControlVolume = GamingCanvasEngineAudio.controlVolume;\n\t\tGamingCanvas.audioLoad = GamingCanvasEngineAudio.load;\n\t\tGamingCanvas.audioMute = GamingCanvasEngineAudio.mute;\n\t\tGamingCanvas.isAudioMuted = GamingCanvasEngineAudio.isMuted;\n\t\tGamingCanvas.isAudioPermitted = GamingCanvasEngineAudio.isPermitted;\n\t\tGamingCanvas.audioVolumeGlobal = GamingCanvasEngineAudio.volumeGlobal;\n\t\tGamingCanvas.setCallbackIsAudioPermitted = GamingCanvasEngineAudio.setCallbackIsPermitted;\n\n\t\t// Function Forward: Engine Gamepad\n\t\tGamingCanvas.getGamepads = GamingCanvasEngineGamepad.getGamepads;\n\n\t\t// Function Forward: Engine Mouse\n\t\tGamingCanvas.mouseLock = GamingCanvasEngineMouse.lock;\n\t\tGamingCanvas.mouseUnlock = GamingCanvasEngineMouse.unlock;\n\t\tGamingCanvas.isMouseLocked = GamingCanvasEngineMouse.isLocked;\n\t}\n\n\t/**\n\t * Rotate, Scale, and callbackReport() as required\n\t */\n\tprivate static go(_?: any, _skipCallback?: boolean): GamingCanvasReport {\n\t\treturn <GamingCanvasReport>(<unknown>undefined);\n\t}\n\tprivate static go__funcForward(): void {\n\t\tlet aspectRatio: number,\n\t\t\tcanvas: HTMLCanvasElement,\n\t\t\tchanged: boolean,\n\t\t\tdevicePixelRatio: number,\n\t\t\tdevicePixelRatioEff: number,\n\t\t\tdiff: number,\n\t\t\tdomRectContainerCanvas: DOMRect,\n\t\t\tdomRectRotator2: DOMRect,\n\t\t\theightContainer: number,\n\t\t\theightResolution: number,\n\t\t\tinitial: boolean,\n\t\t\tnow: number,\n\t\t\toptions: GamingCanvasOptions,\n\t\t\treport: GamingCanvasReport,\n\t\t\tscaler: number,\n\t\t\tsplitRotateSpecial: boolean | undefined,\n\t\t\tstyleTransform: string,\n\t\t\twidthContainer: number,\n\t\t\twidthResolution: number;\n\n\t\tconst go = (_?: any, skipCallback?: boolean) => {\n\t\t\tchanged = false;\n\t\t\tinitial = GamingCanvas.stateOrientation === undefined;\n\t\t\toptions = GamingCanvas.options;\n\n\t\t\t/**\n\t\t\t * Orientation\n\t\t\t */\n\t\t\tif (options.orientation === GamingCanvasOrientation.LANDSCAPE) {\n\t\t\t\tchanged = GamingCanvas.oLandscape();\n\t\t\t} else if (options.orientation === GamingCanvasOrientation.PORTRAIT) {\n\t\t\t\tchanged = GamingCanvas.oPortrait();\n\t\t\t} else {\n\t\t\t\t// Auto\n\t\t\t\tif (window.innerWidth < window.innerHeight) {\n\t\t\t\t\tchanged = GamingCanvas.oPortrait();\n\t\t\t\t} else {\n\t\t\t\t\tchanged = GamingCanvas.oLandscape();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Size and Scale\n\t\t\t */\n\t\t\taspectRatio = <number>options.aspectRatio;\n\t\t\tdevicePixelRatio = options.dpiSupportEnable === true ? window.devicePixelRatio : 1;\n\t\t\tdevicePixelRatioEff = options.dpiSupportEnable === true ? 1 / window.devicePixelRatio : 1;\n\t\t\theightContainer = (GamingCanvas.elementRotator2.clientWidth / aspectRatio) | 0;\n\t\t\theightResolution = (options.resolutionWidthPx ? options.resolutionWidthPx / aspectRatio : heightContainer) | 0;\n\t\t\treport = <GamingCanvasReport>{\n\t\t\t\torientation: GamingCanvas.stateOrientation,\n\t\t\t\torientationCanvasRotated:\n\t\t\t\t\tGamingCanvas.stateOrientation !== GamingCanvasOrientation.LANDSCAPE && GamingCanvas.options.orientationCanvasRotateEnable !== false,\n\t\t\t};\n\t\t\tstyleTransform = GamingCanvas.elementContainerCanvas.style.transform;\n\t\t\twidthContainer = GamingCanvas.elementRotator2.clientWidth | 0;\n\t\t\twidthResolution = (options.resolutionWidthPx || widthContainer) | 0;\n\n\t\t\t// Correction\n\t\t\tif (!options.resolutionWidthPx && GamingCanvas.stateOrientation !== GamingCanvasOrientation.LANDSCAPE) {\n\t\t\t\theightContainer = GamingCanvas.elementRotator2.clientWidth | 0;\n\t\t\t\theightResolution = heightContainer;\n\n\t\t\t\twidthContainer = (GamingCanvas.elementRotator2.clientWidth * aspectRatio) | 0;\n\t\t\t\twidthResolution = widthContainer;\n\t\t\t}\n\n\t\t\t// Determine dimensions\n\t\t\treport.devicePixelRatio = devicePixelRatio;\n\t\t\treport.canvasHeight = heightResolution;\n\t\t\treport.canvasWidth = widthResolution;\n\n\t\t\t// Determine scaler\n\t\t\tif (options.resolutionScaleToFit === true && options.resolutionWidthPx !== null) {\n\t\t\t\tif (GamingCanvas.stateOrientation === GamingCanvasOrientation.LANDSCAPE) {\n\t\t\t\t\tscaler = (devicePixelRatioEff * widthContainer) / widthResolution;\n\t\t\t\t} else {\n\t\t\t\t\tscaler = widthContainer / devicePixelRatio / heightResolution;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tscaler = devicePixelRatioEff;\n\t\t\t}\n\t\t\treport.scaler = scaler;\n\t\t\tGamingCanvas.elementContainerCanvas.style.transform = styleTransform.replace(\n\t\t\t\t`scale(${(GamingCanvas.regExpScale.exec(styleTransform) || [''])[0]})`,\n\t\t\t\t'scale(' + scaler + ')',\n\t\t\t);\n\n\t\t\t// Rotate\n\t\t\tif (GamingCanvas.stateOrientation !== GamingCanvasOrientation.LANDSCAPE && GamingCanvas.options.orientationCanvasRotateEnable !== true) {\n\t\t\t\treport.canvasHeight = widthResolution;\n\t\t\t\treport.canvasWidth = heightResolution;\n\t\t\t}\n\n\t\t\t// Set the container canvas size\n\t\t\tGamingCanvas.elementContainerCanvas.style.height = ((devicePixelRatio * report.canvasHeight) | 0) + 'px';\n\t\t\tGamingCanvas.elementContainerCanvas.style.width = ((devicePixelRatio * report.canvasWidth) | 0) + 'px';\n\n\t\t\t// Set the container overlay size\n\t\t\tif (GamingCanvas.stateOrientation === GamingCanvasOrientation.LANDSCAPE || options.orientationCanvasRotateEnable !== true) {\n\t\t\t\tGamingCanvas.elementContainerOverlay.style.height = ((devicePixelRatio * report.canvasHeight * scaler) | 0) + 'px';\n\t\t\t\tGamingCanvas.elementContainerOverlay.style.width = ((devicePixelRatio * report.canvasWidth * scaler) | 0) + 'px';\n\t\t\t} else {\n\t\t\t\tGamingCanvas.elementContainerOverlay.style.height = ((devicePixelRatio * report.canvasWidth * scaler) | 0) + 'px';\n\t\t\t\tGamingCanvas.elementContainerOverlay.style.width = ((devicePixelRatio * report.canvasHeight * scaler) | 0) + 'px';\n\t\t\t}\n\n\t\t\t// Set split size\n\t\t\tif (GamingCanvas.stateOrientation === GamingCanvasOrientation.LANDSCAPE && options.canvasSplitLandscapeVertical === true) {\n\t\t\t\treport.canvasHeightSplit = report.canvasHeight;\n\t\t\t\treport.canvasWidthSplit = (report.canvasWidth / 2) | 0;\n\t\t\t} else {\n\t\t\t\treport.canvasHeightSplit = (report.canvasHeight / 2) | 0;\n\t\t\t\treport.canvasWidthSplit = report.canvasWidth;\n\t\t\t}\n\n\t\t\t// Set split swap for specific rotation case\n\t\t\tif (GamingCanvas.elementCanvasesSplit !== undefined) {\n\t\t\t\tif (\n\t\t\t\t\tGamingCanvas.stateOrientation === GamingCanvasOrientation.PORTRAIT &&\n\t\t\t\t\toptions.orientationCanvasRotateEnable === true &&\n\t\t\t\t\toptions.orientationCanvasPortaitRotateLeft !== true\n\t\t\t\t) {\n\t\t\t\t\tif (splitRotateSpecial !== true) {\n\t\t\t\t\t\tsplitRotateSpecial = true;\n\n\t\t\t\t\t\tfor (canvas of GamingCanvas.elementCanvasesSplit) {\n\t\t\t\t\t\t\tif (canvas.id.endsWith('a')) {\n\t\t\t\t\t\t\t\tcanvas.style.bottom = '0';\n\t\t\t\t\t\t\t\tcanvas.style.left = 'auto';\n\t\t\t\t\t\t\t\tcanvas.style.right = '0';\n\t\t\t\t\t\t\t\tcanvas.style.top = 'auto';\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcanvas.style.bottom = 'auto';\n\t\t\t\t\t\t\t\tcanvas.style.left = '0';\n\t\t\t\t\t\t\t\tcanvas.style.right = 'auto';\n\t\t\t\t\t\t\t\tcanvas.style.top = '0';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (splitRotateSpecial === true) {\n\t\t\t\t\tsplitRotateSpecial = false;\n\n\t\t\t\t\tfor (canvas of GamingCanvas.elementCanvasesSplit) {\n\t\t\t\t\t\tif (canvas.id.endsWith('a')) {\n\t\t\t\t\t\t\tcanvas.style.bottom = 'auto';\n\t\t\t\t\t\t\tcanvas.style.left = '0';\n\t\t\t\t\t\t\tcanvas.style.right = 'auto';\n\t\t\t\t\t\t\tcanvas.style.top = '0';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcanvas.style.bottom = '0';\n\t\t\t\t\t\t\tcanvas.style.left = 'auto';\n\t\t\t\t\t\t\tcanvas.style.right = '0';\n\t\t\t\t\t\t\tcanvas.style.top = 'auto';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * Centering\n\t\t\t */\n\t\t\tdomRectContainerCanvas = GamingCanvas.elementContainerCanvas.getBoundingClientRect();\n\t\t\tdomRectRotator2 = GamingCanvas.elementRotator2.getBoundingClientRect();\n\t\t\tGamingCanvas.elementContainerCanvas.style.marginLeft = (domRectRotator2.width - domRectContainerCanvas.width) / 2 + 'px';\n\t\t\tGamingCanvas.elementContainerCanvas.style.marginTop = (domRectRotator2.height - domRectContainerCanvas.height) / 2 + 'px';\n\t\t\tGamingCanvas.elementContainerOverlay.style.marginLeft = GamingCanvas.elementContainerCanvas.style.marginLeft;\n\t\t\tGamingCanvas.elementContainerOverlay.style.marginTop = GamingCanvas.elementContainerCanvas.style.marginTop;\n\n\t\t\t/*\n\t\t\t * DPI\n\t\t\t */\n\t\t\treport.canvasHeight = (report.canvasHeight * devicePixelRatio) | 0;\n\t\t\treport.canvasWidth = (report.canvasWidth * devicePixelRatio) | 0;\n\n\t\t\t/*\n\t\t\t * Callback\n\t\t\t */\n\t\t\tGamingCanvas.stateReport = report;\n\t\t\tif (skipCallback !== true && GamingCanvas.callbackReport !== undefined) {\n\t\t\t\tif (\n\t\t\t\t\tchanged === true ||\n\t\t\t\t\tinitial === true ||\n\t\t\t\t\treport.canvasHeight !== GamingCanvas.stateHeight ||\n\t\t\t\t\treport.canvasWidth !== GamingCanvas.stateWidth ||\n\t\t\t\t\treport.scaler !== GamingCanvas.stateScaler\n\t\t\t\t) {\n\t\t\t\t\tGamingCanvas.stateHeight = report.canvasHeight;\n\t\t\t\t\tGamingCanvas.stateWidth = report.canvasWidth;\n\t\t\t\t\tGamingCanvas.stateScaler = report.scaler;\n\n\t\t\t\t\tif (GamingCanvas.options.callbackReportLimitPerMs === 0) {\n\t\t\t\t\t\tGamingCanvas.callbackReport(report);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnow = performance.now();\n\t\t\t\t\t\tdiff = now - GamingCanvas.callbackReportLastInMs;\n\n\t\t\t\t\t\tif (diff > <number>GamingCanvas.options.callbackReportLimitPerMs) {\n\t\t\t\t\t\t\tclearTimeout(GamingCanvas.callbackReportTimeout);\n\t\t\t\t\t\t\tGamingCanvas.callbackReportLastInMs = now;\n\t\t\t\t\t\t\tGamingCanvas.callbackReport(report);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tGamingCanvas.stateReport = report;\n\t\t\t\t\t\t\tclearTimeout(GamingCanvas.callbackReportTimeout);\n\t\t\t\t\t\t\tGamingCanvas.callbackReportTimeout = setTimeout(\n\t\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\t\tGamingCanvas.callbackReportLastInMs = performance.now();\n\t\t\t\t\t\t\t\t\tGamingCanvas.callbackReport(GamingCanvas.stateReport);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t<number>GamingCanvas.options.callbackReportLimitPerMs - diff,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn report;\n\t\t};\n\t\tGamingCanvas.go = go;\n\t}\n\n\t/**\n\t * Hold onto your butts\n\t *\n\t * @param elementParent is document.body on undefined | null\n\t * @param options are default on undefined | null\n\t */\n\tpublic static initialize(elementParent: HTMLElement = document.body, options: GamingCanvasOptions = {}): HTMLCanvasElement[] {\n\t\tif (GamingCanvas.elementContainer === undefined) {\n\t\t\t// First time being initialized\n\n\t\t\tGamingCanvas.stateFullscreen = document.fullscreenElement !== null;\n\t\t\taddEventListener('fullscreenchange', () => {\n\t\t\t\tconst state: boolean = document.fullscreenElement !== null;\n\n\t\t\t\tif (GamingCanvas.stateFullscreen !== state) {\n\t\t\t\t\tGamingCanvas.stateFullscreen = state;\n\n\t\t\t\t\tGamingCanvas.callbackFullscreen && GamingCanvas.callbackFullscreen(state);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tGamingCanvas.stateVisibility = document.visibilityState !== 'hidden';\n\t\t\taddEventListener('visibilitychange', async () => {\n\t\t\t\tconst state: boolean = document.visibilityState !== 'hidden';\n\n\t\t\t\tif (GamingCanvas.stateVisibility !== state) {\n\t\t\t\t\tGamingCanvas.stateVisibility = state;\n\n\t\t\t\t\t// Automatically suspend wakeLock when not visible\n\t\t\t\t\tif (state && GamingCanvas.stateWakeLockState && !GamingCanvas.stateWakeLock) {\n\t\t\t\t\t\t// Re-enable after becoming visible again\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tGamingCanvas.stateWakeLock = await navigator.wakeLock.request('screen');\n\t\t\t\t\t\t} catch (error) {}\n\n\t\t\t\t\t\tif (!GamingCanvas.stateWakeLock) {\n\t\t\t\t\t\t\tconsole.error('GamingCanvas: failed to wake lock after becoming visible');\n\t\t\t\t\t\t\tGamingCanvas.stateWakeLockState = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (!state && GamingCanvas.stateWakeLockState && GamingCanvas.stateWakeLock) {\n\t\t\t\t\t\t// Disable while not visible\n\t\t\t\t\t\tGamingCanvas.stateWakeLock.release();\n\t\t\t\t\t\tGamingCanvas.stateWakeLock = undefined;\n\t\t\t\t\t}\n\n\t\t\t\t\tGamingCanvas.callbackVisibility && GamingCanvas.callbackVisibility(state);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// Stop active processes\n\t\t\tGamingCanvasEngineGamepad.shutdown();\n\n\t\t\t// Clear old elements and listeners\n\t\t\tGamingCanvas.elementContainer.innerText = '';\n\t\t\tGamingCanvas.elementParent.removeChild(GamingCanvas.elementContainer);\n\t\t}\n\t\tGamingCanvas.elementParent = elementParent;\n\t\tGamingCanvas.options = GamingCanvas.formatOptions(options || {});\n\n\t\t// Go() event listeners\n\t\tscreen.orientation.addEventListener('change', GamingCanvas.go);\n\t\taddEventListener('resize', GamingCanvas.go);\n\n\t\t// Element: Container\n\t\tGamingCanvas.elementContainer = document.createElement('div');\n\t\tGamingCanvas.elementContainer.id = 'gaming-canvas';\n\t\tGamingCanvas.elementContainer.style.alignItems = 'center';\n\t\tGamingCanvas.elementContainer.style.display = 'flex';\n\t\tGamingCanvas.elementContainer.style.height = '100%';\n\t\tGamingCanvas.elementContainer.style.justifyContent = 'center';\n\t\tGamingCanvas.elementContainer.style.position = 'relative';\n\t\tGamingCanvas.elementContainer.style.width = '100%';\n\t\telementParent.appendChild(GamingCanvas.elementContainer);\n\n\t\t// Element: Rotator1\n\t\tGamingCanvas.elementRotator1 = document.createElement('div');\n\t\tGamingCanvas.elementRotator1.id = 'gaming-canvas-rotator1';\n\t\tGamingCanvas.elementRotator1.style.alignItems = 'center';\n\t\tGamingCanvas.elementRotator1.style.display = 'flex';\n\t\tGamingCanvas.elementRotator1.style.height = 'auto';\n\t\tGamingCanvas.elementRotator1.style.maxHeight = '100%';\n\t\tGamingCanvas.elementRotator1.style.justifyContent = 'center';\n\t\tGamingCanvas.elementRotator1.style.width = '100%';\n\t\tGamingCanvas.elementRotator1.style.maxWidth = 'auto';\n\t\tGamingCanvas.elementContainer.appendChild(GamingCanvas.elementRotator1);\n\n\t\t// Element: Rotator2\n\t\tGamingCanvas.elementRotator2 = document.createElement('div');\n\t\tGamingCanvas.elementRotator2.id = 'gaming-canvas-rotator2';\n\t\tGamingCanvas.elementRotator2.style.height = '100%';\n\t\tGamingCanvas.elementRotator2.style.maxHeight = 'auto';\n\t\tGamingCanvas.elementRotator2.style.position = 'relative';\n\t\tGamingCanvas.elementRotator2.style.width = 'auto';\n\t\tGamingCanvas.elementRotator2.style.maxWidth = '100%';\n\t\tGamingCanvas.elementRotator1.appendChild(GamingCanvas.elementRotator2);\n\n\t\t// Element: Container Canvas\n\t\tGamingCanvas.elementContainerCanvas = document.createElement('div');\n\t\tGamingCanvas.elementContainerCanvas.id = 'gaming-canvas-container-canvas';\n\t\tGamingCanvas.elementContainerCanvas.style.transformOrigin = 'top left';\n\t\tGamingCanvas.elementContainerCanvas.style.position = 'relative';\n\t\tGamingCanvas.elementContainerCanvas.style.zIndex = '1';\n\t\tGamingCanvas.elementRotator2.appendChild(GamingCanvas.elementContainerCanvas);\n\n\t\t// Element: Canvas Input Relativer\n\t\tGamingCanvas.elementContainerCanvasInputs = document.createElement('div');\n\t\tGamingCanvas.elementContainerCanvasInputs.id = 'gaming-canvas-container-canvas-inputs';\n\t\tGamingCanvas.elementContainerCanvasInputs.style.bottom = '0';\n\t\tGamingCanvas.elementContainerCanvasInputs.style.left = '0';\n\t\tGamingCanvas.elementContainerCanvasInputs.style.pointerEvents = 'none';\n\t\tGamingCanvas.elementContainerCanvasInputs.style.position = 'absolute';\n\t\tGamingCanvas.elementContainerCanvasInputs.style.right = '0';\n\t\tGamingCanvas.elementContainerCanvasInputs.style.top = '0';\n\t\tGamingCanvas.elementContainerCanvasInputs.style.touchAction = 'none';\n\t\tGamingCanvas.elementContainerCanvasInputs.style.zIndex = '0';\n\t\tGamingCanvas.elementContainerCanvas.appendChild(GamingCanvas.elementContainerCanvasInputs);\n\n\t\t// Element: Canvas\n\t\tlet canvas: HTMLCanvasElement,\n\t\t\tcount: number = <number>options.canvasCount;\n\n\t\tGamingCanvas.elementCanvases = new Array();\n\t\tGamingCanvas.elementCanvasesSplit = new Array();\n\t\tfor (let i = 1; i <= count; i++) {\n\t\t\tif ((<number[]>options.canvasSplit).includes(i)) {\n\t\t\t\t// Split: A\n\t\t\t\tcanvas = document.createElement('canvas');\n\t\t\t\tcanvas.height = 0;\n\t\t\t\tcanvas.id = `gaming-canvas-canvas${i}a`;\n\t\t\t\tcanvas.width = 0;\n\t\t\t\tcanvas.style.left = '0';\n\t\t\t\tcanvas.style.position = 'absolute';\n\t\t\t\tcanvas.style.top = '0';\n\t\t\t\tcanvas.style.zIndex = String(i * 10);\n\n\t\t\t\tGamingCanvas.elementCanvases.push(canvas);\n\t\t\t\tGamingCanvas.elementCanvasesSplit.push(canvas);\n\t\t\t\tGamingCanvas.elementContainerCanvas.appendChild(canvas);\n\n\t\t\t\t// Split: B\n\t\t\t\tcanvas = document.createElement('canvas');\n\t\t\t\tcanvas.height = 0;\n\t\t\t\tcanvas.id = `gaming-canvas-canvas${i}b`;\n\t\t\t\tcanvas.width = 0;\n\t\t\t\tcanvas.style.bottom = '0';\n\t\t\t\tcanvas.style.position = 'absolute';\n\t\t\t\tcanvas.style.right = '0';\n\t\t\t\tcanvas.style.zIndex = String(i * 10);\n\n\t\t\t\tGamingCanvas.elementCanvases.push(canvas);\n\t\t\t\tGamingCanvas.elementCanvasesSplit.push(canvas);\n\t\t\t\tGamingCanvas.elementContainerCanvas.appendChild(canvas);\n\t\t\t} else {\n\t\t\t\tcanvas = document.createElement('canvas');\n\t\t\t\tcanvas.height = 0;\n\t\t\t\tcanvas.id = `gaming-canvas-canvas${i}`;\n\t\t\t\tcanvas.width = 0;\n\t\t\t\tcanvas.style.left = '0';\n\t\t\t\tcanvas.style.position = 'absolute';\n\t\t\t\tcanvas.style.top = '0';\n\t\t\t\tcanvas.style.zIndex = String(i * 10);\n\n\t\t\t\tGamingCanvas.elementCanvases.push(canvas);\n\t\t\t\tGamingCanvas.elementContainerCanvas.appendChild(canvas);\n\t\t\t}\n\t\t}\n\t\toptions.elementInteractive = options.elementInteractive === undefined ? GamingCanvas.elementContainerOverlayWrapper : options.elementInteractive;\n\n\t\t// Element: Canvas Injectables\n\t\tif (options.elementInjectAsCanvas && Array.isArray(options.elementInjectAsCanvas)) {\n\t\t\tfor (let element of options.elementInjectAsCanvas) {\n\t\t\t\tGamingCanvas.elementContainerCanvas.appendChild(element);\n\t\t\t}\n\t\t}\n\n\t\t// Element: Container Overlays\n\t\tGamingCanvas.elementContainerOverlay = document.createElement('div');\n\t\tGamingCanvas.elementContainerOverlay.id = 'gaming-canvas-container-overlay';\n\t\tGamingCanvas.elementContainerOverlay.style.left = '0';\n\t\tGamingCanvas.elementContainerOverlay.style.position = 'absolute';\n\t\tGamingCanvas.elementContainerOverlay.style.top = '0';\n\t\tGamingCanvas.elementContainerOverlay.style.transformOrigin = 'top left';\n\t\tGamingCanvas.elementContainerOverlay.style.zIndex = '2';\n\t\tGamingCanvas.elementRotator2.appendChild(GamingCanvas.elementContainerOverlay);\n\n\t\t// Element: Container Overlays Wrapper\n\t\tGamingCanvas.elementContainerOverlayWrapper = document.createElement('div');\n\t\tGamingCanvas.elementContainerOverlayWrapper.id = 'gaming-canvas-container-overlay-wrapper';\n\t\tGamingCanvas.elementContainerOverlayWrapper.style.height = '100%';\n\t\tGamingCanvas.elementContainerOverlayWrapper.style.position = 'relative';\n\t\tGamingCanvas.elementContainerOverlayWrapper.style.width = '100%';\n\t\tGamingCanvas.elementContainerOverlay.appendChild(GamingCanvas.elementContainerOverlayWrapper);\n\n\t\t// Element: Overlay Injectables\n\t\tif (options.elementInjectAsOverlay && Array.isArray(options.elementInjectAsOverlay)) {\n\t\t\tfor (let element of options.elementInjectAsOverlay) {\n\t\t\t\tGamingCanvas.elementContainerOverlayWrapper.appendChild(element);\n\t\t\t}\n\t\t}\n\n\t\t// Apply\n\t\tGamingCanvas.setOptions(options);\n\n\t\t// Engines\n\t\tGamingCanvasEngineAudio.initialize(\n\t\t\t<boolean>options.audioEnable,\n\t\t\t<number>options.audioBufferCount,\n\t\t\tGamingCanvasEngineAudio.isContext() ? undefined : new AudioContext(),\n\t\t);\n\t\toptions.inputGamepadEnable && GamingCanvasEngineGamepad.initialize(GamingCanvas.inputQueue, <number>options.inputGamepadDeadbandStick);\n\t\toptions.inputKeyboardEnable &&\n\t\t\tGamingCanvasEngineKeyboard.initialize(\n\t\t\t\tGamingCanvas.inputQueue,\n\t\t\t\t<boolean>options.inputKeyboardPreventAlt,\n\t\t\t\t<boolean>options.inputKeyboardPreventCntrl,\n\t\t\t\t<boolean>options.inputKeyboardPreventMeta,\n\t\t\t\t<boolean>options.inputKeyboardPreventShift,\n\t\t\t\t<boolean>options.inputKeyboardPreventTab,\n\t\t\t);\n\t\toptions.inputMouseEnable &&\n\t\t\tGamingCanvasEngineMouse.initialize(\n\t\t\t\tGamingCanvas.elementContainerCanvasInputs,\n\t\t\t\t<HTMLElement>options.elementInteractive,\n\t\t\t\tGamingCanvas.inputQueue,\n\t\t\t\t<boolean>options.inputMousePreventContextMenu,\n\t\t\t);\n\t\toptions.inputTouchEnable &&\n\t\t\tGamingCanvasEngineTouch.initialize(\n\t\t\t\tGamingCanvas.elementContainerCanvasInputs,\n\t\t\t\t<HTMLElement>options.elementInteractive,\n\t\t\t\t<number>options.inputLimitPerMs,\n\t\t\t\tGamingCanvas.inputQueue,\n\t\t\t);\n\n\t\t// Done\n\t\treturn GamingCanvas.elementCanvases;\n\t}\n\n\tprivate static oLandscape(): boolean {\n\t\tif (GamingCanvas.stateOrientation !== GamingCanvasOrientation.LANDSCAPE) {\n\t\t\tGamingCanvas.stateOrientation = GamingCanvasOrientation.LANDSCAPE;\n\n\t\t\tGamingCanvas.elementRotator1.style.aspectRatio = `${GamingCanvas.options.aspectRatio}`;\n\t\t\tGamingCanvas.elementRotator1.style.height = 'auto';\n\t\t\tGamingCanvas.elementRotator1.style.maxHeight = '100%';\n\t\t\tGamingCanvas.elementRotator1.style.width = '100%';\n\t\t\tGamingCanvas.elementRotator1.style.maxWidth = 'auto';\n\n\t\t\tGamingCanvas.elementRotator2.style.aspectRatio = GamingCanvas.elementRotator1.style.aspectRatio;\n\t\t\tGamingCanvas.elementRotator2.style.height = '100%';\n\t\t\tGamingCanvas.elementRotator2.style.maxHeight = 'auto';\n\t\t\tGamingCanvas.elementRotator2.style.width = 'auto';\n\t\t\tGamingCanvas.elementRotator2.style.maxWidth = '100%';\n\n\t\t\tGamingCanvas.elementContainerCanvas.style.transform = 'scale(1)';\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate static oPortrait(): boolean {\n\t\tif (GamingCanvas.stateOrientation !== GamingCanvasOrientation.PORTRAIT) {\n\t\t\tGamingCanvas.stateOrientation = GamingCanvasOrientation.PORTRAIT;\n\n\t\t\tGamingCanvas.elementRotator1.style.aspectRatio = `${1 / <number>GamingCanvas.options.aspectRatio}`;\n\t\t\tGamingCanvas.elementRotator1.style.height = '100%';\n\t\t\tGamingCanvas.elementRotator1.style.maxHeight = 'auto';\n\t\t\tGamingCanvas.elementRotator1.style.width = 'auto';\n\t\t\tGamingCanvas.elementRotator1.style.maxWidth = '100%';\n\n\t\t\tGamingCanvas.elementRotator2.style.aspectRatio = GamingCanvas.elementRotator1.style.aspectRatio;\n\t\t\tGamingCanvas.elementRotator2.style.height = 'auto';\n\t\t\tGamingCanvas.elementRotator2.style.maxHeight = '100%';\n\t\t\tGamingCanvas.elementRotator2.style.width = '100%';\n\t\t\tGamingCanvas.elementRotator2.style.maxWidth = 'auto';\n\n\t\t\tif (GamingCanvas.options.orientationCanvasRotateEnable === true) {\n\t\t\t\tGamingCanvas.elementContainerCanvas.style.transform = GamingCanvas.options.orientationCanvasPortaitRotateLeft\n\t\t\t\t\t? 'rotate(-90deg) scale(1) translateX(-100%)'\n\t\t\t\t\t: 'rotate(90deg) scale(1) translateY(-100%)';\n\t\t\t} else {\n\t\t\t\tGamingCanvas.elementContainerCanvas.style.transform = 'scale(1)';\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Moves canvas elements back into GamingCanvas's canvas container\n\t */\n\t// public static recontainerizeCanvases(): void {\n\t// \tlet canvas: HTMLCanvasElement,\n\t// \t\tcanvases: HTMLCanvasElement[] = GamingCanvas.elementCanvases,\n\t// \t\tcontainerCanvas: HTMLElement = GamingCanvas.elementContainerCanvas;\n\n\t// \tfor (canvas of canvases) {\n\t// \t\tcanvas.parentElement?.removeChild(canvas);\n\t// \t\tcontainerCanvas.appendChild(canvas);\n\t// \t}\n\t// }\n\n\t/**\n\t * Inputs are relative to the overlay container, but this will convert it to be relative to the canvas container\n\t *\n\t * This has to be applied after the input is pulled from the queue as the canvas(es) may have rotated or scaled while the input was waiting in the queue\n\t */\n\tpublic static relativizeInputToCanvas(_input: GamingCanvasInput): GamingCanvasInput {\n\t\treturn <GamingCanvasInput>(<unknown>undefined);\n\t}\n\tprivate static relativizeInputToCanvas__funcForward(): void {\n\t\tlet a: number,\n\t\t\taRelative: number,\n\t\t\theight: number,\n\t\t\tposition: GamingCanvasInputPosition,\n\t\t\tpositions: GamingCanvasInputPosition[] | undefined,\n\t\t\trotated: boolean,\n\t\t\trotatedLeft: boolean,\n\t\t\tscaler: number,\n\t\t\twidth: number;\n\n\t\tconst relativizeInputToCanvas = (input: GamingCanvasInput) => {\n\t\t\tif (input.type === GamingCanvasInputType.GAMEPAD || input.type === GamingCanvasInputType.KEYBOARD) {\n\t\t\t\t// Nothing to do\n\t\t\t\treturn input;\n\t\t\t}\n\t\t\trotated = GamingCanvas.stateOrientation !== GamingCanvasOrientation.LANDSCAPE && GamingCanvas.options.orientationCanvasRotateEnable !== false;\n\t\t\tscaler = GamingCanvas.stateReport.scaler;\n\n\t\t\tif (rotated) {\n\t\t\t\theight = GamingCanvas.elementContainerCanvas.clientHeight;\n\t\t\t\trotatedLeft = GamingCanvas.options.orientationCanvasPortaitRotateLeft === true;\n\t\t\t\twidth = GamingCanvas.elementContainerCanvas.clientWidth;\n\t\t\t} else if (scaler === 1) {\n\t\t\t\t// Nothing to do\n\t\t\t\treturn input;\n\t\t\t}\n\n\t\t\t// Fix it\n\t\t\tswitch (input.type) {\n\t\t\t\tcase GamingCanvasInputType.MOUSE:\n\t\t\t\t\tposition = input.propriatary.position;\n\n\t\t\t\t\t// Rotate\n\t\t\t\t\tif (rotated === true) {\n\t\t\t\t\t\ta = position.x;\n\t\t\t\t\t\taRelative = position.xRelative;\n\t\t\t\t\t\tif (rotatedLeft === true) {\n\t\t\t\t\t\t\tposition.x = width - position.y;\n\t\t\t\t\t\t\tposition.xRelative = 1 - position.yRelative;\n\t\t\t\t\t\t\tposition.y = a;\n\t\t\t\t\t\t\tposition.yRelative = aRelative;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tposition.x = position.y;\n\t\t\t\t\t\t\tposition.xRelative = position.yRelative;\n\t\t\t\t\t\t\tposition.y = height - a;\n\t\t\t\t\t\t\tposition.yRelative = 1 - aRelative;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Scale\n\t\t\t\t\tif (scaler !== 1) {\n\t\t\t\t\t\tposition.x = (position.x / scaler) | 0;\n\t\t\t\t\t\tposition.y = (position.y / scaler) | 0;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase GamingCanvasInputType.TOUCH:\n\t\t\t\t\tpositions = input.propriatary.positions;\n\n\t\t\t\t\tif (positions) {\n\t\t\t\t\t\tfor (let i = 0; i < positions.length; i++) {\n\t\t\t\t\t\t\tposition = positions[i];\n\n\t\t\t\t\t\t\tif (rotated === true) {\n\t\t\t\t\t\t\t\t// Rotate\n\t\t\t\t\t\t\t\ta = position.x;\n\t\t\t\t\t\t\t\taRelative = position.xRelative;\n\t\t\t\t\t\t\t\tif (rotatedLeft === true) {\n\t\t\t\t\t\t\t\t\tposition.x = width - position.y;\n\t\t\t\t\t\t\t\t\tposition.xRelative = 1 - position.yRelative;\n\t\t\t\t\t\t\t\t\tposition.y = a;\n\t\t\t\t\t\t\t\t\tposition.yRelative = aRelative;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tposition.x = position.y;\n\t\t\t\t\t\t\t\t\tposition.xRelative = position.yRelative;\n\t\t\t\t\t\t\t\t\tposition.y = height - a;\n\t\t\t\t\t\t\t\t\tposition.yRelative = 1 - aRelative;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Scale\n\t\t\t\t\t\t\tif (scaler !== 1) {\n\t\t\t\t\t\t\t\tposition.x = (position.x / scaler) | 0;\n\t\t\t\t\t\t\t\tposition.y = (position.y / scaler) | 0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn input;\n\t\t};\n\n\t\tGamingCanvas.relativizeInputToCanvas = relativizeInputToCanvas;\n\t}\n\n\t/**\n\t * Take screenshot of all canvas layers stacked as they are displayed\n\t *\n\t * @param skipCanvases don't include these canvasId's in the screenshot\n\t * @return null on failure\n\t */\n\tpublic static async screenshot(skipCanvases?: number[]): Promise<Blob | null> {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > screenshot: not initialized yet');\n\t\t\treturn null;\n\t\t}\n\n\t\tlet canvasScreenshot: OffscreenCanvas = new OffscreenCanvas(GamingCanvas.stateReport.canvasWidth, GamingCanvas.stateReport.canvasHeight),\n\t\t\tcanvasScreenshotContext: OffscreenCanvasRenderingContext2D = <OffscreenCanvasRenderingContext2D>canvasScreenshot.getContext('2d', {\n\t\t\t\talpha: true,\n\t\t\t\tantialias: false,\n\t\t\t\tdepth: true,\n\t\t\t\tdesynchronized: false,\n\t\t\t\tpowerPreference: 'high-performance',\n\t\t\t}),\n\t\t\tcanvasSplitLandscapeVertical: boolean = GamingCanvas.options.canvasSplitLandscapeVertical === true,\n\t\t\tcanvas: HTMLCanvasElement,\n\t\t\tcanvases: HTMLCanvasElement[] = GamingCanvas.elementCanvases,\n\t\t\torientationCanvasRotateEnable: boolean = GamingCanvas.options.orientationCanvasRotateEnable === true,\n\t\t\torientationCanvasPortaitRotateLeft: boolean = GamingCanvas.options.orientationCanvasPortaitRotateLeft === true,\n\t\t\torientationLandscape: boolean = GamingCanvas.stateOrientation === GamingCanvasOrientation.LANDSCAPE;\n\n\t\t// Draw every layer into the screenshot canvas starting with the lowest layer canvases[0]\n\t\tfor (canvas of canvases) {\n\t\t\tif (skipCanvases !== undefined && skipCanvases.includes(Number(canvas.id.replace(/\\D/g, ''))) === true) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (canvas.id.endsWith('a') === true || canvas.id.endsWith('b') === true) {\n\t\t\t\t// Split Screen\n\t\t\t\tif (orientationLandscape !== true && orientationCanvasRotateEnable === true && orientationCanvasPortaitRotateLeft !== true) {\n\t\t\t\t\t// Special case\n\t\t\t\t\tif (canvas.id.endsWith('a') === true) {\n\t\t\t\t\t\tcanvasScreenshotContext.drawImage(canvas, 0, 0);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcanvasScreenshotContext.drawImage(canvas, (canvasScreenshot.width / 2) | 0, 0);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Regular\n\t\t\t\t\tif (canvas.id.endsWith('b') === true) {\n\t\t\t\t\t\tif (orientationLandscape === true && canvasSplitLandscapeVertical === true) {\n\t\t\t\t\t\t\tcanvasScreenshotContext.drawImage(canvas, (canvasScreenshot.width / 2) | 0, 0);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcanvasScreenshotContext.drawImage(canvas, 0, (canvasScreenshot.height / 2) | 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Whole Screen\n\t\t\t\tcanvasScreenshotContext.drawImage(canvas, 0, 0);\n\t\t\t}\n\n\t\t\tif (orientationLandscape !== true && orientationCanvasRotateEnable === true && orientationCanvasPortaitRotateLeft !== true) {\n\t\t\t} else {\n\t\t\t\tif (canvas.id.endsWith('b') === true) {\n\t\t\t\t\tif (orientationLandscape === true && canvasSplitLandscapeVertical === true) {\n\t\t\t\t\t\tcanvasScreenshotContext.drawImage(canvas, (canvasScreenshot.width / 2) | 0, 0);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcanvasScreenshotContext.drawImage(canvas, 0, (canvasScreenshot.height / 2) | 0);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcanvasScreenshotContext.drawImage(canvas, 0, 0);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Convert screnshot canvas into PNG blob\n\t\treturn await canvasScreenshot.convertToBlob({\n\t\t\ttype: 'image/png',\n\t\t\tquality: 1,\n\t\t});\n\t}\n\n\t/**\n\t * Not supported by all browsers: https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API\n\t *\n\t * @param pattern [200, 100, 300] is 200ms on, 100ms off, 300ms on\n\t * @param repeat if true will loop the pattern\n\t * @param repeatOffsetInMs delay in milliseconds before repeating\n\t * @param returns true if supported and valid\n\t */\n\tpublic static vibrate(pattern: number[], repeat?: boolean, repeatOffsetInMs?: number): boolean {\n\t\tif ('vibrate' in navigator) {\n\t\t\tlet durationInMs: number = 0;\n\n\t\t\tif (!Array.isArray(pattern) || pattern.length === 0) {\n\t\t\t\tconsole.error('GamingCanvas > vibrate: pattern is invalid');\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < pattern.length; i++) {\n\t\t\t\tif (pattern[i] < 1) {\n\t\t\t\t\tconsole.error('GamingCanvas > vibrate: pattern cannot contain a value less than 1');\n\t\t\t\t\treturn false;\n\t\t\t\t} else {\n\t\t\t\t\tdurationInMs += pattern[i];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Vibrate\n\t\t\tclearInterval(GamingCanvas.vibrateInterval);\n\t\t\tnavigator.vibrate(pattern);\n\n\t\t\tif (repeat) {\n\t\t\t\trepeatOffsetInMs = Math.max(0, repeatOffsetInMs || 0);\n\t\t\t\tGamingCanvas.vibrateInterval = setInterval(() => {\n\t\t\t\t\tnavigator.vibrate(pattern);\n\t\t\t\t}, durationInMs + repeatOffsetInMs);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic static vibrateCancel(): void {\n\t\tclearInterval(GamingCanvas.vibrateInterval);\n\t\tif ('vibrate' in navigator) {\n\t\t\tnavigator.vibrate(0);\n\t\t}\n\t}\n\n\t/**\n\t * @return is false on failure\n\t */\n\tpublic static async wakeLock(enable: boolean): Promise<boolean> {\n\t\tif (enable === GamingCanvas.stateWakeLockState) {\n\t\t\t// Already in that state\n\t\t\treturn true;\n\t\t}\n\n\t\tif ('wakeLock' in navigator) {\n\t\t\tif (enable) {\n\t\t\t\ttry {\n\t\t\t\t\tGamingCanvas.stateWakeLock = await navigator.wakeLock.request('screen');\n\t\t\t\t} catch (error) {}\n\n\t\t\t\tif (GamingCanvas.stateWakeLock) {\n\t\t\t\t\tGamingCanvas.stateWakeLockState = true;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tGamingCanvas.stateWakeLock && GamingCanvas.stateWakeLock.release();\n\t\t\t\tGamingCanvas.stateWakeLock = undefined;\n\t\t\t\tGamingCanvas.stateWakeLockState = false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\tconsole.error(\"GamingCanvas > wakeLock: 'Wake Lock API' not supported by this browser\");\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Set the specific audio instance's volume\n\t *\n\t * @param instance is the number returned by the controlPlay() function\n\t * @param pan is -1 left, 0 center, 1 right\n\t * @param durationInMs is how long it takes to apply the new value completely (default is 0 milliseconds)\n\t * @param callback is triggered when audio or fader is complete\n\t */\n\tpublic static audioControlPan(_instance: number, _pan: number, _durationInMs: number = 0, _callback?: (instance: number) => void): void {}\n\n\t/**\n\t * Suspend playing the audio without ending it, or resume audio where you suspended it\n\t *\n\t * @param instance is the number returned by the controlPlay() function\n\t * @param state true = pause, false = unpause\n\t */\n\tpublic static audioControlPause(_instance: number, _state: boolean): void {}\n\n\t/**\n\t * Suspend playing the audio without ending it, or resume audio where you suspended it\n\t *\n\t * @param state true = pause, false = unpause\n\t */\n\tpublic static audioControlPauseAll(_state: boolean): void {}\n\n\t/**\n\t * If an audio buffer is available, via the availibility FIFO queue, then the asset will be loaded into the buffer and played from that source\n\t *\n\t * @param effect (default is true) [false implies music]\n\t * @param loop (default is false)\n\t * @param pan is -1 left, 0 center, 1 right (default is 0)\n\t * @param positionInS is between 0 and the duration of the audio asset in seconds (default is 0)\n\t * @param volume is between 0 and 1 (default is 1)\n\t * @return is instance, use this to modify the active audio (null on failure)\n\t */\n\tpublic static async audioControlPlay(\n\t\t_assetId: number,\n\t\t_type: GamingCanvasAudioType = GamingCanvasAudioType.EFFECT,\n\t\t_loop: boolean = false,\n\t\t_pan: number = 0,\n\t\t_positionInS: number = 0,\n\t\t_volume: number = 1,\n\t\t_callback?: (instance: number) => void,\n\t): Promise<number | null> {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Stop the audio and return the buffer to the availability FIFO queue\n\t *\n\t * @param instance is the number returned by the controlPlay() function\n\t */\n\tpublic static audioControlStop(_instance: number): void {}\n\n\t/**\n\t * Stop the audio and return the buffer to the availability FIFO queue\n\t *\n\t * @param type specify a specific type to stop (default is all types)\n\t */\n\tpublic static audioControlStopAll(type: GamingCanvasAudioType = GamingCanvasAudioType.ALL): void {}\n\n\t/**\n\t * Set the specific audio instance's volume\n\t *\n\t * @param instance is the number returned by the controlPlay() function\n\t * @param volume is between 0 and 1\n\t * @param durationInMs is how long it takes to apply the new value completely (default is 0 milliseconds)\n\t * @param callback is triggered when audio or fader is complete\n\t */\n\tpublic static audioControlVolume(_instance: number, _volume: number, _durationInMs: number = 0, _callback?: (instance: number) => void): void {}\n\n\t/**\n\t * @param assets Map<identifing number, Blob/DataURL/URL>\n\t */\n\tpublic static async audioLoad(_assets: Map<number, string>): Promise<void> {}\n\n\tpublic static isAudioMuted(): boolean {\n\t\treturn false;\n\t}\n\n\t/**\n\t * Mute or unmute all audio\n\t */\n\tpublic static audioMute(_enable: boolean): void {}\n\n\tpublic static isAudioPermitted(): boolean {\n\t\treturn false;\n\t}\n\n\t/**\n\t * @param volume must be between 0 and 1\n\t */\n\tpublic static audioVolumeGlobal(_volume: number, _type: GamingCanvasAudioType) {}\n\n\t/**\n\t * @return is undefined if not initialized yet\n\t */\n\tpublic static getCanvases(): HTMLCanvasElement[] {\n\t\treturn GamingCanvas.elementCanvases;\n\t}\n\n\t/**\n\t * Get notified when the browser toggles the permission to play audio\n\t */\n\tpublic static setCallbackIsAudioPermitted(callbackIsPermitted: (state: boolean) => void): void {}\n\n\t/**\n\t * Get notified when the browser changes fullscreen mode\n\t */\n\tpublic static setCallbackFullscreen(callbackFullscreen: (state: boolean) => void): void {\n\t\tGamingCanvas.callbackFullscreen = callbackFullscreen;\n\t}\n\n\t/**\n\t * Get notified when the browser changes mouse locked mode\n\t */\n\tpublic static setCallbackMouseLocked(callbackMouseLocked: (state: boolean) => void): void {\n\t\tGamingCanvasEngineMouse.callbackLocked = callbackMouseLocked;\n\t}\n\n\t/**\n\t * Is called on display changes\n\t */\n\tpublic static setCallbackReport(callbackReport: (report: GamingCanvasReport) => void): void {\n\t\tGamingCanvas.callbackReport = callbackReport;\n\t}\n\n\t/**\n\t * State false indicates events like the browser being minified to the taskbar or an app being backgrounded\n\t */\n\tpublic static setCallbackVisibility(callbackVisibility: (state: boolean) => void): void {\n\t\tGamingCanvas.callbackVisibility = callbackVisibility;\n\t}\n\n\tpublic static getCurrentOrientation(): GamingCanvasOrientation {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > getCurrentOrientation: not initialized yet');\n\t\t\treturn GamingCanvasOrientation.LANDSCAPE;\n\t\t}\n\t\treturn GamingCanvas.stateOrientation;\n\t}\n\n\tpublic static setDebug(state: boolean): void {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > setDebug: not initialized yet');\n\t\t\treturn;\n\t\t}\n\t\tif (state) {\n\t\t\tGamingCanvas.elementRotator1.style.background = 'repeating-linear-gradient(45deg, #404040, #000 10px';\n\n\t\t\tGamingCanvas.elementRotator2.style.backgroundColor = 'rgba(192,192,192,0.5)';\n\n\t\t\tfor (const canvas of GamingCanvas.elementCanvases) {\n\t\t\t\tcanvas.style.backgroundColor = 'rgba(255,0,255,0.5)';\n\t\t\t\tcanvas.style.boxShadow = 'inset -8px 8px 4px 4px rgb(0,255,0)';\n\t\t\t}\n\t\t} else {\n\t\t\tGamingCanvas.elementRotator1.style.background = 'unset';\n\n\t\t\tGamingCanvas.elementRotator2.style.backgroundColor = 'transparent';\n\n\t\t\tfor (const canvas of GamingCanvas.elementCanvases) {\n\t\t\t\tcanvas.style.backgroundColor = 'transparent';\n\t\t\t\tcanvas.style.boxShadow = 'none';\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * detectmobilebrowsers.com | unlicense | 'This is free and unencumbered software released into the public domain.' [10/08/25]\n\t *\n\t * @param type defaults to mobile and tablets\n\t */\n\tpublic static detectDevice(\n\t\ttypes: GamingCanvasOptionsDetectDeviceType[] = [GamingCanvasOptionsDetectDeviceType.MOBILE, GamingCanvasOptionsDetectDeviceType.TABLET],\n\t): boolean {\n\t\tlet id: string = navigator.userAgent || (<any>window).vendor || (<any>window).opera,\n\t\t\ttype: GamingCanvasOptionsDetectDeviceType;\n\n\t\tfor (type of types) {\n\t\t\tif (type === GamingCanvasOptionsDetectDeviceType.TABLET) {\n\t\t\t\tif (/android|ipad|playbook|silk/i.test(id) === true) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst m: boolean =\n\t\t\t\t\t/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(\n\t\t\t\t\t\tid,\n\t\t\t\t\t) ||\n\t\t\t\t\t/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(\n\t\t\t\t\t\tid.substring(0, 4),\n\t\t\t\t\t);\n\n\t\t\t\tif (type === GamingCanvasOptionsDetectDeviceType.MOBILE) {\n\t\t\t\t\tif (m === true) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (m === false) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tpublic static isInitialized(): boolean {\n\t\treturn GamingCanvas.elementContainer !== undefined;\n\t}\n\n\tpublic static getInputLimitPerMs(): number {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > getInputLimitPerMs: not initialized yet');\n\t\t\treturn 8;\n\t\t}\n\n\t\treturn GamingCanvas.options !== undefined ? <number>GamingCanvas.options.inputLimitPerMs : 8;\n\t}\n\n\t/**\n\t * Remove all the inputs from the queue\n\t */\n\tpublic static clearInputQueue(): void {\n\t\tGamingCanvas.inputQueue.clear();\n\t}\n\n\t/**\n\t * Gamepad and Keyboard events are global inputs and are not limited to the canvas element\n\t *\n\t * @return FIFO queue of input events as they occurred (serialized)\n\t */\n\tpublic static getInputQueue(): GamingCanvasFIFOQueue<GamingCanvasInput> {\n\t\treturn GamingCanvas.inputQueue;\n\t}\n\n\t/**\n\t * @param active means inputs will be put in the queue for processing\n\t */\n\tpublic static setInputState(enable: boolean, clearInputQueue?: boolean): void {\n\t\tclearInputQueue === true && GamingCanvas.inputQueue.clear();\n\n\t\tGamingCanvasEngineMouse.active = enable;\n\t\tGamingCanvasEngineKeyboard.active = enable;\n\t\tGamingCanvasEngineMouse.active = enable;\n\t\tGamingCanvasEngineTouch.active = enable;\n\n\t\tclearInputQueue === true && GamingCanvas.inputQueue.clear();\n\t}\n\n\tpublic static isFullscreen(): boolean {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > isFullscreen: not initialized yet');\n\t\t\treturn false;\n\t\t}\n\t\treturn GamingCanvas.stateFullscreen;\n\t}\n\n\t/**\n\t * @param element use this to fullscreen something other than the canvas element. Not needed when exiting fullscreen.\n\t */\n\tpublic static async setFullscreen(state: boolean, element?: HTMLElement): Promise<boolean> {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > setFullscreen: not initialized yet');\n\t\t\treturn true;\n\t\t} else if (GamingCanvas.stateFullscreen === state) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (state) {\n\t\t\ttry {\n\t\t\t\tawait (element || GamingCanvas.elementContainer).requestFullscreen();\n\t\t\t\treturn true;\n\t\t\t} catch (error) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tawait document.exitFullscreen();\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * @param unadjustedMovement when true, disables OS-level mouse acceleration and access raw mouse input\n\t */\n\tpublic static async mouseLock(_unadjustedMovement?: boolean): Promise<boolean> {\n\t\treturn false;\n\t}\n\n\tpublic static mouseUnlock(): void {}\n\n\tpublic static isMouseLocked(): boolean {\n\t\treturn false;\n\t}\n\n\tprivate static formatOptions(options: GamingCanvasOptions): GamingCanvasOptions {\n\t\toptions.aspectRatio = options.aspectRatio === undefined ? 16 / 9 : Number(options.aspectRatio) || 16 / 9;\n\t\toptions.audioBufferCount = options.audioBufferCount === undefined ? 20 : Math.max(5, Math.min(50, Number(options.audioBufferCount)));\n\t\toptions.audioEnable = options.audioEnable === undefined ? false : options.audioEnable === true;\n\t\toptions.callbackReportLimitPerMs = Math.max(0, Number(options.callbackReportLimitPerMs) || 8);\n\t\toptions.canvasCount = options.canvasCount === undefined ? 1 : Math.max(1, Number(options.canvasCount) || 0);\n\t\toptions.canvasSplit = options.canvasSplit === undefined ? [] : options.canvasSplit;\n\t\toptions.canvasSplitLandscapeVertical = options.canvasSplitLandscapeVertical === undefined ? true : options.canvasSplitLandscapeVertical === true;\n\t\toptions.debug = options.debug === undefined ? false : options.debug === true;\n\t\toptions.dpiSupportEnable = options.dpiSupportEnable === undefined ? false : options.dpiSupportEnable === true;\n\t\toptions.inputGamepadDeadbandStick =\n\t\t\toptions.inputGamepadDeadbandStick === undefined ? 0.08 : Math.max(0, Math.min(1, Number(options.inputGamepadDeadbandStick) || 0));\n\t\toptions.inputGamepadEnable = options.inputGamepadEnable === undefined ? false : options.inputGamepadEnable === true;\n\t\toptions.inputKeyboardEnable = options.inputKeyboardEnable === undefined ? false : options.inputKeyboardEnable === true;\n\t\toptions.inputKeyboardPreventAlt = options.inputKeyboardPreventAlt === undefined ? false : options.inputKeyboardPreventAlt === true;\n\t\toptions.inputKeyboardPreventCntrl = options.inputKeyboardPreventCntrl === undefined ? false : options.inputKeyboardPreventCntrl === true;\n\t\toptions.inputKeyboardPreventMeta = options.inputKeyboardPreventMeta === undefined ? false : options.inputKeyboardPreventMeta === true;\n\t\toptions.inputKeyboardPreventShift = options.inputKeyboardPreventShift === undefined ? false : options.inputKeyboardPreventShift === true;\n\t\toptions.inputKeyboardPreventTab = options.inputKeyboardPreventTab === undefined ? false : options.inputKeyboardPreventTab === true;\n\t\toptions.inputMouseEnable = options.inputMouseEnable === undefined ? false : options.inputMouseEnable === true;\n\t\toptions.inputMousePreventContextMenu = options.inputMousePreventContextMenu === undefined ? false : options.inputMousePreventContextMenu === true;\n\t\toptions.inputTouchEnable = options.inputTouchEnable === undefined ? false : options.inputTouchEnable === true;\n\t\toptions.inputLimitPerMs = options.inputLimitPerMs === undefined ? 8 : Math.max(0, Number(options.inputLimitPerMs) || 8);\n\t\toptions.orientation = options.orientation === undefined ? GamingCanvasOrientation.AUTO : options.orientation;\n\t\toptions.orientationCanvasRotateEnable = options.orientationCanvasRotateEnable === undefined ? true : options.orientationCanvasRotateEnable === true;\n\t\toptions.orientationCanvasPortaitRotateLeft =\n\t\t\toptions.orientationCanvasPortaitRotateLeft === undefined ? false : options.orientationCanvasPortaitRotateLeft === true;\n\t\toptions.renderStyle = options.renderStyle === undefined ? GamingCanvasRenderStyle.ANTIALIAS : options.renderStyle;\n\t\toptions.resolutionScaleToFit = options.resolutionScaleToFit === undefined ? true : options.resolutionScaleToFit === true;\n\t\toptions.resolutionWidthPx = options.resolutionWidthPx === undefined ? null : Number(options.resolutionWidthPx) | 0 || null;\n\n\t\treturn options;\n\t}\n\n\tpublic static getOptions(): GamingCanvasOptions {\n\t\treturn JSON.parse(JSON.stringify(GamingCanvas.options || {}));\n\t}\n\n\t/**\n\t * Options not mutabile after initialization:\n\t * \t- audio*\n\t *  - canvasCount\n\t * \t- elementInjectAsCanvas\n\t * \t- elementInjectAsOverlay\n\t *  - input*\n\t */\n\tpublic static setOptions(options: GamingCanvasOptions): void {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > setOptions: not initialized yet');\n\t\t\treturn;\n\t\t}\n\t\tGamingCanvas.options = GamingCanvas.formatOptions(options);\n\n\t\t// Apply\n\t\tGamingCanvas.setDebug(<boolean>GamingCanvas.options.debug);\n\n\t\t// Apply: Scale Type\n\t\tswitch (<GamingCanvasRenderStyle>options.renderStyle) {\n\t\t\tcase GamingCanvasRenderStyle.ANTIALIAS:\n\t\t\t\tGamingCanvas.elementContainerCanvas.style.imageRendering = 'smooth';\n\t\t\t\tbreak;\n\t\t\tcase GamingCanvasRenderStyle.PIXELATED:\n\t\t\t\tGamingCanvas.elementContainerCanvas.style.imageRendering = 'pixelated';\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Done\n\t\tGamingCanvas.stateOrientation = <any>undefined;\n\t\tGamingCanvas.go();\n\t}\n\n\tpublic static setOrientation(orientation: GamingCanvasOrientation) {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > setOrientation: not initialized yet');\n\t\t\treturn;\n\t\t}\n\t\tif (orientation !== GamingCanvas.stateOrientation) {\n\t\t\tGamingCanvas.options.orientation = orientation === undefined ? GamingCanvasOrientation.AUTO : orientation;\n\t\t\tGamingCanvas.stateOrientation = <any>undefined;\n\t\t\tGamingCanvas.go();\n\t\t}\n\t}\n\n\tpublic static isLandscape(): boolean {\n\t\treturn GamingCanvas.stateOrientation === GamingCanvasOrientation.LANDSCAPE;\n\t}\n\n\t/**\n\t * Apply rendering style to individual canvas contexts\n\t *\n\t * @param resolutionScaleType force a specific scale type\n\t * @param noTimeouts skips the re-apply after specific intervals\n\t */\n\tpublic static renderStyle(\n\t\tcontext: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n\t\tresolutionScaleType?: GamingCanvasRenderStyle,\n\t\tnoTimeouts?: boolean,\n\t): void {\n\t\tif (resolutionScaleType === undefined) {\n\t\t\tresolutionScaleType = GamingCanvas.options.renderStyle;\n\n\t\t\tif (resolutionScaleType === undefined) {\n\t\t\t\tconsole.error('GamingCanvas: failed to apply scale type as none was provided (applied within WebWorker?)');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tswitch (resolutionScaleType) {\n\t\t\tcase GamingCanvasRenderStyle.ANTIALIAS:\n\t\t\t\tcontext.imageSmoothingEnabled = true;\n\t\t\t\tbreak;\n\t\t\tcase GamingCanvasRenderStyle.PIXELATED:\n\t\t\t\tcontext.imageSmoothingEnabled = false;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (noTimeouts !== true) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tGamingCanvas.renderStyle(context, resolutionScaleType, true);\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tGamingCanvas.renderStyle(context, resolutionScaleType, true);\n\t\t\t\t}, 500);\n\t\t\t}, 100);\n\t\t}\n\t}\n\n\tpublic static getReport(): GamingCanvasReport {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > getReport: not initialized yet');\n\t\t\treturn <any>{};\n\t\t}\n\t\treturn JSON.parse(JSON.stringify(GamingCanvas.stateReport));\n\t}\n\n\tpublic static isVibrateSupported(): boolean {\n\t\treturn 'vibrate' in navigator;\n\t}\n\n\tpublic static isVisible(): boolean {\n\t\tif (!GamingCanvas.elementParent) {\n\t\t\tconsole.error('GamingCanvas > isVisible: not initialized yet');\n\t\t\treturn true;\n\t\t}\n\t\treturn GamingCanvas.stateVisibility;\n\t}\n\n\tpublic static isWakeLockSupported(): boolean {\n\t\treturn 'wakeLock' in navigator;\n\t}\n\n\t/**\n\t * @return object key is gamepadId\n\t */\n\tpublic static getGamepads(): { [key: string]: GamingCanvasInputGamepadState } {\n\t\treturn <{ [key: string]: GamingCanvasInputGamepadState }>(<unknown>undefined);\n\t}\n}\n", "/**\n * Statistical analysis stuff\n *\n * @author tknight-dev\n */\n\nexport enum GamingCanvasStatCalcType {\n\tAVERAGE, //Median\n\tMAX,\n\tMIN,\n\tQUARTILE,\n\tSTD_DEV,\n\tSUM,\n}\n\nexport enum GamingCanvasStatCalcPrecision {\n\t_16,\n\t_32,\n\t_64,\n}\n\nexport interface GamingCanvasStatQuartile {\n\tq0: number;\n\tq1: number;\n\tq2: number;\n\tq3: number;\n\tq4: number;\n}\n\n/**\n * Measure the performance of your algorithms to gauge where you need/want to improve\n */\nexport class GamingCanvasStat {\n\tprivate data: number[];\n\tprivate index: number;\n\tprivate size: number;\n\tprivate timer: number;\n\n\t/**\n\t * Samples determines how many values can be stored at one time: the more samples, the more cpu/memory, and the more accurate the measurement\n\t *\n\t * @param samples can be an array of data (also sets sample size to array length) or the number of samples you want the stat to contain\n\t */\n\tconstructor(samples: number | number[] = 5) {\n\t\tthis.index = 0;\n\n\t\tif (Array.isArray(samples) === true) {\n\t\t\tthis.data = samples;\n\t\t\tthis.size = samples.length;\n\t\t} else {\n\t\t\tthis.data = new Array(samples);\n\t\t\tthis.size = 0;\n\t\t}\n\t}\n\n\t/**\n\t * Manually add your own value\n\t */\n\tpublic add(value: number): void {\n\t\tthis.data[this.index++] = value;\n\t\tthis.size = Math.min(this.size + 1, this.data.length);\n\n\t\t// Reset array index back to start\n\t\tif (this.index !== 0 && this.index % this.data.length === 0) {\n\t\t\tthis.index = 0;\n\t\t}\n\t}\n\n\t/**\n\t * If samples is 100, but there is only 1 reading. Then you'll get just that 1 reading.\n\t *\n\t * If samples is 100, but there is only 2 readings. Then you'll get just the calc of those 2 readings.\n\t *\n\t * @param type default is average\n\t *\n\t * @return is 0 on no data available\n\t */\n\tpublic static calc(stat: GamingCanvasStat, type: GamingCanvasStatCalcType = GamingCanvasStatCalcType.AVERAGE): number | GamingCanvasStatQuartile {\n\t\tconst data: number[] = stat.data,\n\t\t\tsize: number = Math.min(data.length, stat.size);\n\n\t\tif (size !== 0) {\n\t\t\tlet value: number;\n\n\t\t\tswitch (type) {\n\t\t\t\tcase GamingCanvasStatCalcType.AVERAGE: // median\n\t\t\t\t\tvalue = 0;\n\t\t\t\t\tfor (let i = 0; i < size; i++) {\n\t\t\t\t\t\tvalue += data[i];\n\t\t\t\t\t}\n\t\t\t\t\treturn value / size;\n\t\t\t\tcase GamingCanvasStatCalcType.MAX:\n\t\t\t\t\tvalue = data[0];\n\t\t\t\t\tfor (let i = 1; i < size; i++) {\n\t\t\t\t\t\tif (data[i] > value) {\n\t\t\t\t\t\t\tvalue = data[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\tcase GamingCanvasStatCalcType.MIN:\n\t\t\t\t\tvalue = data[0];\n\t\t\t\t\tfor (let i = 1; i < size; i++) {\n\t\t\t\t\t\tif (data[i] < value) {\n\t\t\t\t\t\t\tvalue = data[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\tcase GamingCanvasStatCalcType.QUARTILE:\n\t\t\t\t\tconst dataAscending: number[] = data.sort((a, b) => a - b);\n\t\t\t\t\tlet base: number, position: number;\n\n\t\t\t\t\tconst calc = (quintile: number) => {\n\t\t\t\t\t\tposition = (dataAscending.length - 1) * quintile;\n\t\t\t\t\t\tbase = position | 0;\n\n\t\t\t\t\t\tif (dataAscending[base + 1] !== undefined) {\n\t\t\t\t\t\t\treturn dataAscending[base] + (position - base) * (dataAscending[base + 1] - dataAscending[base]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn dataAscending[base];\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tq0: calc(0),\n\t\t\t\t\t\tq1: calc(0.25),\n\t\t\t\t\t\tq2: calc(0.5),\n\t\t\t\t\t\tq3: calc(0.75),\n\t\t\t\t\t\tq4: calc(1),\n\t\t\t\t\t};\n\t\t\t\tcase GamingCanvasStatCalcType.STD_DEV:\n\t\t\t\t\tconst mean: number = data.reduce((a, b) => a + b) / data.length;\n\t\t\t\t\treturn Math.sqrt(data.map((x) => (x - mean) ** 2).reduce((a, b) => a + b) / data.length);\n\t\t\t\tcase GamingCanvasStatCalcType.SUM:\n\t\t\t\t\tvalue = 0;\n\t\t\t\t\tfor (let i = 0; i < size; i++) {\n\t\t\t\t\t\tvalue += data[i];\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\tdefault:\n\t\t\t\t\tconsole.error('GamingCanvasStat > calc: unknown type', type);\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t} else {\n\t\t\tif (type === GamingCanvasStatCalcType.QUARTILE) {\n\t\t\t\treturn {\n\t\t\t\t\tq0: 0,\n\t\t\t\t\tq1: 0,\n\t\t\t\t\tq2: 0,\n\t\t\t\t\tq3: 0,\n\t\t\t\t\tq4: 0,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Resets back to original state\n\t */\n\tpublic clear(): void {\n\t\tthis.index = 0;\n\t\tthis.size = 0;\n\t}\n\n\t/**\n\t * Returns a GamingCanvasStat instance from an encoded GamingCanvasStat (Float Array)\n\t */\n\tpublic static decode(data: Float16Array | Float32Array | Float64Array): GamingCanvasStat {\n\t\tlet i = 0,\n\t\t\tmax: number = data.length - 1,\n\t\t\tarray: number[] = new Array(data[max]),\n\t\t\tstat: GamingCanvasStat = new GamingCanvasStat(data[max]);\n\n\t\tstat.data = array;\n\t\tif (array.length !== 0 && array.length % max !== 0) {\n\t\t\tstat.index = array.length;\n\t\t}\n\t\tstat.size = array.length;\n\n\t\tfor (; i < max; i++) {\n\t\t\tarray[i] = data[i];\n\t\t}\n\n\t\treturn stat;\n\t}\n\n\t/**\n\t * Returns a Typed Array (TransferableObject) with the last element representing the original sample size\n\t */\n\tpublic encode(precision: GamingCanvasStatCalcPrecision = GamingCanvasStatCalcPrecision._32): Float16Array | Float32Array | Float64Array {\n\t\tlet array: Float16Array | Float32Array | Float64Array,\n\t\t\tdata: number[] = this.data,\n\t\t\ti: number = 0,\n\t\t\tsize: number = this.size;\n\n\t\tswitch (precision) {\n\t\t\tcase GamingCanvasStatCalcPrecision._16:\n\t\t\t\tarray = new Float16Array(this.size + 1);\n\t\t\t\tbreak;\n\t\t\tcase GamingCanvasStatCalcPrecision._32:\n\t\t\t\tarray = new Float32Array(this.size + 1);\n\t\t\t\tbreak;\n\t\t\tcase GamingCanvasStatCalcPrecision._64:\n\t\t\t\tarray = new Float64Array(this.size + 1);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tfor (; i < size; i++) {\n\t\t\tarray[i] = data[i] || 0;\n\t\t}\n\n\t\tarray[array.length - 1] = size;\n\n\t\treturn array;\n\t}\n\n\t/**\n\t * Contained data length\n\t */\n\tpublic get length(): number {\n\t\treturn this.size;\n\t}\n\n\t/**\n\t * Contained data length matches the requested sample size\n\t */\n\tpublic isFull(): boolean {\n\t\treturn this.size === this.data.length;\n\t}\n\n\tpublic getSamples(): number {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * Resets back to original state\n\t *\n\t * @param samples determines how many timing durations can be stored at one time: the more samples, the more cpu/memory, and the more accurate the measurement\n\t */\n\tpublic setSamples(samples: number): void {\n\t\tthis.data = new Array(Math.max(1, samples));\n\t\tthis.index = 0;\n\t\tthis.size = 0;\n\t}\n\n\t/**\n\t * Tracks the timing of an algorithm in milliseconds: start the clock\n\t */\n\tpublic watchStart(): void {\n\t\tthis.timer = performance.now();\n\t}\n\n\t/**\n\t * Tracks the timing of an algorithm in milliseconds: stop the clock and add the duration to the internal array\n\t */\n\tpublic watchStop(): void {\n\t\tthis.add(performance.now() - this.timer);\n\t}\n}\n", "/**\n * @author tknight-dev\n */\n\nimport { GamingCanvasConstPI_2_000 } from './const.js';\n\n/**\n * Dynamically increase array size without disturbing existing values\n *\n * Will catch browser errors if the increase request is too large, and will scale down the job into smaller segments\n *\n * @param increaseBy defines how much longer the array should be\n * @param fill remember that filling an array with an object will just put pointers to that same object in all the array elements\n */\nexport const GamingCanvasUtilArrayExpand = (array: any[], increaseBy: number, fill?: any): any[] => {\n\tif (increaseBy > 0) {\n\t\ttry {\n\t\t\t// Error thrown if increasing array size by too much at one time (browser dependent)\n\t\t\tArray.prototype.push.apply(array, new Array(increaseBy).fill(fill));\n\t\t\treturn array;\n\t\t} catch (error) {\n\t\t\t// Reduce increase size and try again\n\t\t\tconst reducer: number = (increaseBy / 2) | 0;\n\n\t\t\twhile (increaseBy > 0) {\n\t\t\t\tGamingCanvasUtilArrayExpand(array, Math.min(reducer, increaseBy));\n\t\t\t\tincreaseBy -= reducer;\n\t\t\t}\n\n\t\t\treturn array;\n\t\t}\n\t} else {\n\t\treturn array;\n\t}\n};\n\n/**\n * Generates a simple image for verifying your render logic\n */\nexport const GamingCanvasUtilDebugImage = (width: number, height?: number): OffscreenCanvas => {\n\twidth = width | 0;\n\theight = height === undefined ? width : height | 0;\n\n\tconst canvas: OffscreenCanvas = new OffscreenCanvas(width, height),\n\t\tcontext: OffscreenCanvasRenderingContext2D = <OffscreenCanvasRenderingContext2D>canvas.getContext('2d'),\n\t\theightHalf: number = (height / 2) | 0,\n\t\tminHalf: number = (Math.min(height, width) / 2) | 0,\n\t\twidthHalf: number = (width / 2) | 0;\n\n\tcanvas.height = height;\n\tcanvas.width = width;\n\n\tcontext.clearRect(0, 0, canvas.width, canvas.height);\n\tcontext.fillStyle = 'rgb(224,224,224)';\n\tcontext.fillRect(0, 0, width, height);\n\n\tcontext.fillStyle = 'red';\n\tcontext.fillRect(0, 0, minHalf, minHalf);\n\n\tcontext.fillStyle = 'blue';\n\tcontext.fillRect(width - minHalf, height - minHalf, minHalf, minHalf);\n\n\tcontext.fillStyle = 'green';\n\tcontext.beginPath();\n\tcontext.arc(widthHalf, heightHalf, minHalf / 2, 0, GamingCanvasConstPI_2_000);\n\tcontext.closePath();\n\tcontext.fill();\n\n\treturn canvas;\n};\n\n/**\n * Scale value between two ranges\n *\n * EG: value = 8\n * \t\tfromMin = 0, fromMax = 10\n * \t\t  toMin = 0,   toMax = 100\n * \t\treturn is 80\n */\nexport const GamingCanvasUtilScale = (value: number, fromMin: number, fromMax: number, toMin: number, toMax: number) => {\n\treturn ((value - fromMin) * (toMax - toMin)) / (fromMax - fromMin) + toMin;\n};\n\n/**\n * A simple alternative for `setTimeout()` that gives you more control over the clock checking and timing calculations\n *\n * Note: timing accuracy depends on the thread calling it (typically less accurate then just using `setTimeout()`)\n *\n * Note: non-static class as WebWorkers have their own `performance.now()` initial time (0 reference) that is unique to the WebWorker instant\n * \tof instantiation. Thus, every new instance of this class will be relative to the thread that created it\n */\nexport class GamingCanvasUtilTimers {\n\tprivate added: Map<number, number>;\n\tprivate counter: number = -1;\n\tprivate callbacks: Map<number, (durationInMs: number, id: number) => void>;\n\tprivate timesInMS: Map<number, number>;\n\tprivate timestampThen: number;\n\n\tconstructor(timestampNow: number = performance.now() | 0) {\n\t\tthis.added = new Map();\n\t\tthis.callbacks = new Map();\n\t\tthis.timesInMS = new Map();\n\t\tthis.timestampThen = timestampNow;\n\t}\n\n\t/**\n\t * @param callback this function is called with the overall duration of the timeout (original duration + clock updates [pauses])\n\t * @return id\n\t */\n\tpublic add(callback: (durationInMs: number, id: number) => void, durationInMS: number, id?: number): number {\n\t\tif (id === undefined) {\n\t\t\tid = ++this.counter;\n\t\t} else {\n\t\t\tthis.timesInMS.delete(id);\n\t\t\tthis.callbacks.delete(id);\n\t\t\tthis.added.delete(id);\n\t\t}\n\n\t\tthis.added.set(id, performance.now() | 0);\n\t\tthis.callbacks.set(id, callback);\n\t\tthis.timesInMS.set(id, durationInMS);\n\n\t\tif (id === -1) {\n\t\t\tthis.counter = 0;\n\t\t}\n\n\t\treturn id;\n\t}\n\n\t/**\n\t * Process callbacks asynchronously\n\t */\n\tprivate callback(callbacks: Map<number, (durationInMs: number, id: number) => void>, durationInMs: number, id: number): void {\n\t\tsetTimeout(() => {\n\t\t\tlet callback: ((durationInMs: number, id: number) => void) | undefined = callbacks.get(id);\n\n\t\t\tif (callback !== undefined) {\n\t\t\t\tcallback(durationInMs, id);\n\t\t\t\tcallbacks.delete(id);\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic clear(id: number = -1) {\n\t\tif (id !== -1) {\n\t\t\tthis.timesInMS.delete(id);\n\t\t\tthis.callbacks.delete(id);\n\t\t\tthis.added.delete(id);\n\t\t}\n\t}\n\n\tpublic clearAll() {\n\t\tthis.timesInMS.clear();\n\t\tthis.callbacks.clear();\n\t\tthis.added.clear();\n\t}\n\n\t/**\n\t * Update the interal clock without modifying the durations of the internal timer instances (effectively pauses the timers)\n\t */\n\tpublic clockUpdate(timestampNow: number = performance.now() | 0): void {\n\t\tthis.timestampThen = timestampNow;\n\t}\n\n\t/**\n\t * Check for completed timer instances\n\t */\n\tpublic tick(timestampNow: number = performance.now() | 0): void {\n\t\tif (this.timesInMS.size === 0) {\n\t\t\tthis.timestampThen = timestampNow;\n\t\t\treturn;\n\t\t}\n\n\t\tconst delta: number = timestampNow - this.timestampThen;\n\t\tif (delta === 0) {\n\t\t\treturn;\n\t\t}\n\t\tthis.timestampThen = timestampNow;\n\n\t\t// Process\n\t\tlet callbacks: Map<number, (durationInMs: number, id: number) => void> = this.callbacks,\n\t\t\tdurationInMs: number,\n\t\t\tid: number,\n\t\t\ttimesInMS: Map<number, number> = this.timesInMS;\n\n\t\tfor ([id, durationInMs] of timesInMS.entries()) {\n\t\t\tdurationInMs -= delta;\n\n\t\t\tif (durationInMs <= 0) {\n\t\t\t\tthis.callback(callbacks, timestampNow - <number>this.added.get(id), id);\n\t\t\t\tthis.added.delete(id);\n\t\t\t\ttimesInMS.delete(id);\n\t\t\t} else {\n\t\t\t\ttimesInMS.set(id, durationInMs);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic getClock(): number {\n\t\treturn this.timestampThen;\n\t}\n\n\tpublic getTimeRemaining(id: number): number | undefined {\n\t\treturn this.timesInMS.get(id);\n\t}\n}\n"],
  "mappings": "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",
  "names": ["main_exports", "__export", "GamingCanvas", "GamingCanvasAudioType", "GamingCanvasConstIntegerMaxSafe", "GamingCanvasConstIntegerMinSafe", "GamingCanvasConstPI_0_125", "GamingCanvasConstPI_0_250", "GamingCanvasConstPI_0_375", "GamingCanvasConstPI_0_500", "GamingCanvasConstPI_0_625", "GamingCanvasConstPI_0_750", "GamingCanvasConstPI_0_875", "GamingCanvasConstPI_1_000", "GamingCanvasConstPI_1_125", "GamingCanvasConstPI_1_250", "GamingCanvasConstPI_1_375", "GamingCanvasConstPI_1_500", "GamingCanvasConstPI_1_625", "GamingCanvasConstPI_1_750", "GamingCanvasConstPI_1_875", "GamingCanvasConstPI_2_000", "GamingCanvasDoubleLinkedList", "GamingCanvasFIFOQueue", "GamingCanvasInputGamepadControllerButtons", "GamingCanvasInputMouseAction", "GamingCanvasInputPositionClone", "GamingCanvasInputPositionDistance", "GamingCanvasInputPositionDistanceRelative", "GamingCanvasInputPositionsClone", "GamingCanvasInputTouchAction", "GamingCanvasInputType", "GamingCanvasOptions", "GamingCanvasOptionsDetectDeviceType", "GamingCanvasOrientation", "GamingCanvasRenderStyle", "GamingCanvasStat", "GamingCanvasStatCalcPrecision", "GamingCanvasStatCalcType", "GamingCanvasUtilArrayExpand", "GamingCanvasUtilDebugImage", "GamingCanvasUtilScale", "GamingCanvasUtilTimers", "__toCommonJS", "GamingCanvasFIFOQueue", "array", "data", "node", "start", "i", "callback", "limit", "GamingCanvasAudioType", "bufferCallbackPromise", "instance", "callback", "resolve", "faderCallback", "faderInternal", "pan", "faderCallbackPromise", "faderReset", "fader", "GamingCanvasEngineAudio", "_GamingCanvasEngineAudio", "GamingCanvasFIFOQueue", "_timestampNow", "buffer", "buffers", "changed", "faderId", "faders", "fadersActive", "intervalInMs", "limit", "timestampDelta", "timestampThen", "go", "timestampNow", "durationInMs", "panCurrent", "state", "assetId", "type", "loop", "positionInS", "volume", "asset", "audio", "volumeGlobal", "volumeEff", "volumeCurrent", "enable", "bufferCount", "audioContext", "permission", "buffersAvailable", "buffersByInstanceId", "context", "i", "panner", "source", "add", "assets", "id", "promises", "promisesIndex", "src", "loader", "resolver", "skip", "timeout", "loaded", "error", "callbackIsPermitted", "GamingCanvasConstIntegerMaxSafe", "GamingCanvasConstIntegerMinSafe", "GamingCanvasConstPI_0_125", "GamingCanvasConstPI_0_250", "GamingCanvasConstPI_0_375", "GamingCanvasConstPI_0_500", "GamingCanvasConstPI_0_625", "GamingCanvasConstPI_0_750", "GamingCanvasConstPI_0_875", "GamingCanvasConstPI_1_000", "GamingCanvasConstPI_1_125", "GamingCanvasConstPI_1_250", "GamingCanvasConstPI_1_375", "GamingCanvasConstPI_1_500", "GamingCanvasConstPI_1_625", "GamingCanvasConstPI_1_750", "GamingCanvasConstPI_1_875", "GamingCanvasConstPI_2_000", "_a", "GamingCanvasDoubleLinkedList", "array", "i", "length", "node", "data", "end", "start", "callback", "GamingCanvasInputPositionClone", "position", "GamingCanvasInputPositionsClone", "positions", "clone", "i", "GamingCanvasInputPositionDistance", "a", "b", "x", "y", "GamingCanvasInputPositionDistanceRelative", "GamingCanvasInputType", "GamingCanvasInputGamepadControllerButtons", "GamingCanvasEngineGamepad", "_GamingCanvasEngineGamepad", "queue", "deadbandStick", "connectionChange", "event", "gamepad", "connected", "id", "index", "state", "axes", "buttons", "buttonsChanged", "changedAxes", "changedButtons", "firefox", "gamepads", "i", "timestamp", "value", "axesByIndex", "buttonsByIndex", "statesByIndex", "scanner", "timestampNow", "GamingCanvasEngineKeyboard", "_GamingCanvasEngineKeyboard", "queue", "preventAlt", "preventCntrl", "preventMeta", "preventShift", "preventTab", "event", "GamingCanvasInputMouseAction", "GamingCanvasEngineMouse", "_GamingCanvasEngineMouse", "_event", "domRect", "domRectHeight", "domRectWidth", "xEff", "yEff", "calc", "event", "elInputs", "elInteractive", "queue", "preventContextMenu", "contextmenu", "clickAction", "mousedownAction", "mouseupAction", "unadjustedMovement", "error", "GamingCanvasInputTouchAction", "GamingCanvasEngineTouch", "_GamingCanvasEngineTouch", "_event", "domRect", "domRectHeight", "domRectWidth", "touch", "touchLength", "touchList", "touchPositions", "xEff", "yEff", "calc", "event", "i", "elInputs", "elInteractive", "inputLimitPerMs", "queue", "touchActive", "down", "positions", "touchmoveDiff", "touchmoveNow", "GamingCanvasOptionsDetectDeviceType", "GamingCanvasOptions", "GamingCanvasOrientation", "GamingCanvasRenderStyle", "GamingCanvas", "_GamingCanvas", "GamingCanvasFIFOQueue", "GamingCanvasEngineAudio", "GamingCanvasEngineGamepad", "GamingCanvasEngineMouse", "_", "_skipCallback", "aspectRatio", "canvas", "changed", "devicePixelRatio", "devicePixelRatioEff", "diff", "domRectContainerCanvas", "domRectRotator2", "heightContainer", "heightResolution", "initial", "now", "options", "report", "scaler", "splitRotateSpecial", "styleTransform", "widthContainer", "widthResolution", "go", "skipCallback", "elementParent", "state", "count", "i", "element", "GamingCanvasEngineKeyboard", "GamingCanvasEngineTouch", "_input", "a", "aRelative", "height", "position", "positions", "rotated", "rotatedLeft", "width", "relativizeInputToCanvas", "input", "skipCanvases", "canvasScreenshot", "canvasScreenshotContext", "canvasSplitLandscapeVertical", "canvases", "orientationCanvasRotateEnable", "orientationCanvasPortaitRotateLeft", "orientationLandscape", "pattern", "repeat", "repeatOffsetInMs", "durationInMs", "enable", "_instance", "_pan", "_durationInMs", "_callback", "_state", "_assetId", "_type", "_loop", "_positionInS", "_volume", "type", "_assets", "_enable", "callbackIsPermitted", "callbackFullscreen", "callbackMouseLocked", "callbackReport", "callbackVisibility", "types", "id", "m", "clearInputQueue", "_unadjustedMovement", "orientation", "context", "resolutionScaleType", "noTimeouts", "GamingCanvasStatCalcType", "GamingCanvasStatCalcPrecision", "GamingCanvasStat", "_GamingCanvasStat", "samples", "value", "stat", "type", "data", "size", "i", "dataAscending", "a", "b", "base", "position", "calc", "quintile", "mean", "x", "max", "array", "precision", "GamingCanvasUtilArrayExpand", "array", "increaseBy", "fill", "reducer", "GamingCanvasUtilDebugImage", "width", "height", "canvas", "context", "heightHalf", "minHalf", "widthHalf", "GamingCanvasConstPI_2_000", "GamingCanvasUtilScale", "value", "fromMin", "fromMax", "toMin", "toMax", "GamingCanvasUtilTimers", "timestampNow", "callback", "durationInMS", "id", "callbacks", "durationInMs", "delta", "timesInMS"]
}
