cacophony 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cacophony.d.ts +7 -3
- package/dist/context.d.ts +9 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +227 -204
- package/dist/index.mjs.map +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/AudioCache.html +6 -6
- package/docs/classes/Cacophony.html +17 -13
- package/docs/classes/Group.html +12 -12
- package/docs/classes/MicrophonePlayback.html +3 -3
- package/docs/classes/Playback.html +31 -31
- package/docs/classes/Sound.html +18 -18
- package/docs/classes/Synth.html +15 -15
- package/docs/classes/SynthGroup.html +2 -2
- package/docs/enums/SoundType.html +2 -2
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/AudioBuffer.html +2 -2
- package/docs/interfaces/AudioBufferSourceNode.html +4 -4
- package/docs/interfaces/AudioEventCallbacks.html +2 -2
- package/docs/interfaces/AudioListener.html +2 -2
- package/docs/interfaces/AudioNode.html +3 -3
- package/docs/interfaces/AudioParam.html +2 -2
- package/docs/interfaces/AudioWorkletNode.html +25 -0
- package/docs/interfaces/BaseAudioEvents.html +2 -2
- package/docs/interfaces/BaseContext.html +4 -2
- package/docs/interfaces/BaseSound.html +2 -2
- package/docs/interfaces/BiquadFilterNode.html +4 -4
- package/docs/interfaces/CacheErrorEvent.html +2 -2
- package/docs/interfaces/CacheHitEvent.html +2 -2
- package/docs/interfaces/CacheMissEvent.html +2 -2
- package/docs/interfaces/CacophonyEvents.html +2 -2
- package/docs/interfaces/ChannelMergerNode.html +24 -0
- package/docs/interfaces/ChannelSplitterNode.html +24 -0
- package/docs/interfaces/FadeStartEvent.html +2 -2
- package/docs/interfaces/GainNode.html +3 -3
- package/docs/interfaces/GlobalPlaybackEvent.html +2 -2
- package/docs/interfaces/LoadingCompleteEvent.html +2 -2
- package/docs/interfaces/LoadingErrorEvent.html +2 -2
- package/docs/interfaces/LoadingProgressEvent.html +2 -2
- package/docs/interfaces/LoadingStartEvent.html +2 -2
- package/docs/interfaces/MediaElementSourceNode.html +3 -3
- package/docs/interfaces/MediaStreamAudioSourceNode.html +3 -3
- package/docs/interfaces/OfflineOptions.html +2 -2
- package/docs/interfaces/OscillatorNode.html +4 -4
- package/docs/interfaces/PannerNode.html +3 -3
- package/docs/interfaces/PlayOptions.html +2 -2
- package/docs/interfaces/PlaybackErrorEvent.html +2 -2
- package/docs/interfaces/PlaybackEvents.html +2 -2
- package/docs/interfaces/RuntimeOptions.html +2 -2
- package/docs/interfaces/SoundCleanupHoldings.html +2 -2
- package/docs/interfaces/SoundErrorEvent.html +2 -2
- package/docs/interfaces/SoundEvents.html +2 -2
- package/docs/interfaces/StereoPannerNode.html +3 -3
- package/docs/interfaces/SynthEvents.html +2 -2
- package/docs/modules.html +3 -0
- package/docs/types/CacheEventCallback.html +1 -1
- package/docs/types/ErrorEventCallback.html +1 -1
- package/docs/types/FadeType.html +1 -1
- package/docs/types/LoadingEventCallback.html +1 -1
- package/docs/types/LoopCount.html +1 -1
- package/docs/types/Orientation.html +1 -1
- package/docs/types/PanType.html +1 -1
- package/docs/types/Position.html +1 -1
- package/docs/types/SourceNode.html +1 -1
- package/package.json +1 -1
package/dist/cacophony.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ICache } from './cache';
|
|
2
|
-
import { AudioBuffer, AudioListener, BaseContext, BiquadFilterNode, GainNode, PannerNode } from './context';
|
|
2
|
+
import { AudioBuffer, AudioListener, AudioWorkletNode, BaseContext, BiquadFilterNode, ChannelMergerNode, ChannelSplitterNode, GainNode, PannerNode } from './context';
|
|
3
3
|
import { CacophonyEvents } from './events';
|
|
4
4
|
import { Group } from './group';
|
|
5
5
|
import { MicrophoneStream } from './microphone';
|
|
@@ -83,7 +83,7 @@ export interface OfflineOptions {
|
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
85
|
export interface RuntimeOptions {
|
|
86
|
-
createAudioWorkletNode?: (context: BaseContext, name: string) => any;
|
|
86
|
+
createAudioWorkletNode?: (context: BaseContext, name: string, options?: AudioWorkletNodeOptions) => any;
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
89
|
* Resources belonging to a Sound that must be released when the Sound is
|
|
@@ -148,7 +148,9 @@ export declare class Cacophony {
|
|
|
148
148
|
emit<K extends keyof CacophonyEvents>(event: K, data: CacophonyEvents[K]): void;
|
|
149
149
|
emitAsync<K extends keyof CacophonyEvents>(event: K, data: CacophonyEvents[K]): Promise<void>;
|
|
150
150
|
loadWorklets(signal?: AbortSignal): Promise<void>;
|
|
151
|
-
|
|
151
|
+
loadStereoToBFormatWorklet(signal?: AbortSignal): Promise<void>;
|
|
152
|
+
createWorkletNode(name: string, url: string, signal?: AbortSignal, options?: AudioWorkletNodeOptions): Promise<AudioWorkletNode>;
|
|
153
|
+
createStereoToBFormatNode(signal?: AbortSignal): Promise<AudioWorkletNode>;
|
|
152
154
|
private createAbortError;
|
|
153
155
|
private createMediaSound;
|
|
154
156
|
clearMemoryCache(): void;
|
|
@@ -184,6 +186,8 @@ export declare class Cacophony {
|
|
|
184
186
|
*/
|
|
185
187
|
createStream(url: string, signal?: AbortSignal): Promise<Sound>;
|
|
186
188
|
createBiquadFilter: ({ type, frequency, gain, Q }: BiquadFilterOptions) => BiquadFilterNode;
|
|
189
|
+
createSplitter(numChannels?: number): ChannelSplitterNode;
|
|
190
|
+
createMerger(numChannels?: number): ChannelMergerNode;
|
|
187
191
|
/**
|
|
188
192
|
* Creates a PannerNode with the specified options.
|
|
189
193
|
* @param {PannerOptions} options - An object containing the options to use when creating the PannerNode.
|
package/dist/context.d.ts
CHANGED
|
@@ -58,6 +58,13 @@ export interface PannerNode extends AudioNode {
|
|
|
58
58
|
export interface StereoPannerNode extends AudioNode {
|
|
59
59
|
readonly pan: AudioParam;
|
|
60
60
|
}
|
|
61
|
+
export interface ChannelSplitterNode extends AudioNode {
|
|
62
|
+
}
|
|
63
|
+
export interface ChannelMergerNode extends AudioNode {
|
|
64
|
+
}
|
|
65
|
+
export interface AudioWorkletNode extends AudioNode {
|
|
66
|
+
readonly port: MessagePort;
|
|
67
|
+
}
|
|
61
68
|
export interface AudioBufferSourceNode extends AudioNode {
|
|
62
69
|
buffer: AudioBuffer | null;
|
|
63
70
|
loop: boolean;
|
|
@@ -116,6 +123,8 @@ export interface BaseContext {
|
|
|
116
123
|
createBiquadFilter(): BiquadFilterNode;
|
|
117
124
|
createPanner(): PannerNode;
|
|
118
125
|
createStereoPanner(): StereoPannerNode;
|
|
126
|
+
createChannelSplitter?(numberOfOutputs?: number): ChannelSplitterNode;
|
|
127
|
+
createChannelMerger?(numberOfInputs?: number): ChannelMergerNode;
|
|
119
128
|
createOscillator(): OscillatorNode;
|
|
120
129
|
decodeAudioData(audioData: ArrayBuffer): Promise<AudioBuffer>;
|
|
121
130
|
decodeAudioData(audioData: ArrayBuffer, successCallback: (buffer: AudioBuffer) => void, errorCallback?: (error: DOMException) => void): Promise<AudioBuffer>;
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class R{maxSize;cache;constructor(e){this.maxSize=e,this.cache=new Map}get(e){if(!this.cache.has(e))return;const t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}this.cache.set(e,t)}has(e){return this.cache.has(e)}}const V=100;function K(c){if(!c)return null;const e=c.match(/max-age\s*=\s*"?(\d+)"?/i);return e?parseInt(e[1],10):null}function E(c){return c?/(?:^|,)\s*(no-cache|no-store|must-revalidate)\s*(?:,|$)/i.test(c):!1}function k(c){return c instanceof DOMException&&c.name==="AbortError"?"abort":c instanceof Error?"network":"unknown"}class C{static pendingRequests=new Map;static pendingCallbacks=new Map;static decodedBuffers=new R(V);static cacheExpirationTime=1440*60*1e3;static setCacheExpirationTime(e){C.cacheExpirationTime=e}static async openCache(){try{return await caches.open("audio-cache")}catch(e){throw console.error("Failed to open cache:",e),e}}static callAllCallbacks(e,t,s){const o=C.pendingCallbacks.get(e);o&&o.forEach(g=>{const i=g[t];if(i)try{i(s)}catch(a){console.error(`Error in ${t} callback:`,a)}})}static async getOrCreatePendingRequest(e,t,s,o){if(s?.aborted)throw new DOMException("Operation was aborted","AbortError");if(o){const i=C.pendingCallbacks.get(e)||[];i.push(o),C.pendingCallbacks.set(e,i)}const g=C.pendingRequests.get(e);if(!g){const i=(async()=>{try{const a=await t();if(a===void 0)throw new Error("Failed to create audio buffer.");return a}finally{C.pendingRequests.delete(e),C.pendingCallbacks.delete(e)}})();return s?.addEventListener("abort",()=>{s.aborted&&(C.pendingRequests.delete(e),C.pendingCallbacks.delete(e))},{once:!0}),C.pendingRequests.set(e,i),i}return g}static async updateMetadata(e,t,s){const o={url:t,timestamp:Date.now(),...s};await e.put(`${t}:meta`,new Response(JSON.stringify(o),{headers:{"Content-Type":"application/json"}}))}static async getBufferFromCache(e,t){try{const s=await t.match(e);return s?.ok?await s.arrayBuffer():null}catch(s){return console.error("Failed to get data from cache:",s),null}}static async fetchAndCacheBuffer(e,t,s,o,g,i){const a=new Headers;s&&a.append("If-None-Match",s),o&&a.append("If-Modified-Since",o),console.debug(`[AudioCache] Fetching ${e}`,{headers:Object.fromEntries(a.entries()),hasEtag:!!s,hasLastModified:!!o});const n=await fetch(e,{headers:a,signal:g});if(console.debug(`[AudioCache] Response ${e}`,{status:n.status,statusText:n.statusText,etag:n.headers?.get("ETag"),lastModified:n.headers?.get("Last-Modified"),cacheControl:n.headers?.get("Cache-Control")}),n.status===304){const I=await t.match(e);if(I){i?.onCacheHit&&i.onCacheHit({url:e,cacheType:"conditional",timestamp:Date.now()});const r=Date.now(),l=n.headers?.get("Cache-Control");return await C.updateMetadata(t,e,{timestamp:r,etag:s,lastModified:o,...l?{cacheControl:l}:{}}),await I.arrayBuffer()}else{console.warn(`Cache inconsistency detected for ${e}: 304 response but no cached body. Re-fetching.`);const r=await fetch(e,{signal:g});if(r.status===200){const l=r.clone(),A=r.headers.get("ETag"),u=r.headers.get("Last-Modified"),p=r.headers.get("Cache-Control");try{await Promise.all([t.put(e,l),C.updateMetadata(t,e,{timestamp:Date.now(),etag:A||void 0,lastModified:u||void 0,cacheControl:p||void 0})])}catch(d){throw await t.delete(e),await t.delete(`${e}:meta`),d}if(r.body){const{stream:d,total:B}=C.createProgressTrackingStream(r,e);return await C.collectStreamToArrayBuffer(d,B||void 0)}else return await r.arrayBuffer()}else throw new Error(`Failed to fetch resource after cache inconsistency: ${r.status} ${r.statusText}`)}}if(n.status===200){const I=n.clone(),r=n.headers.get("ETag"),l=n.headers.get("Last-Modified"),A=n.headers.get("Cache-Control");try{await Promise.all([t.put(e,I),C.updateMetadata(t,e,{timestamp:Date.now(),etag:r||void 0,lastModified:l||void 0,cacheControl:A||void 0})])}catch(u){throw await t.delete(e),await t.delete(`${e}:meta`),u}}if(g?.aborted)throw new DOMException("Operation was aborted","AbortError");if(n.body){const{stream:I,total:r}=C.createProgressTrackingStream(n,e);return await C.collectStreamToArrayBuffer(I,r||void 0)}else return await n.arrayBuffer()}static createProgressTrackingStream(e,t){const s=e.headers.get("content-length"),o=s?parseInt(s,10):null;let g=0;if(!e.body)throw new Error("Response body is null");const i=e.body.getReader();return{stream:new ReadableStream({start(n){function I(){return i.read().then(({done:r,value:l})=>{if(r){C.callAllCallbacks(t,"onLoadingProgress",{url:t,loaded:g,total:o,progress:o?1:-1,timestamp:Date.now()}),n.close();return}if(l){g+=l.byteLength;const A=o?g/o:-1;C.callAllCallbacks(t,"onLoadingProgress",{url:t,loaded:g,total:o,progress:A,timestamp:Date.now()}),n.enqueue(l)}return I()}).catch(r=>{n.error(r)})}return I()},cancel(n){return i.cancel(n)}}),total:o}}static async collectStreamToArrayBuffer(e,t){const s=e.getReader();try{if(t!==void 0&&t>0){const o=new ArrayBuffer(t),g=new Uint8Array(o);let i=0;for(;;){const{done:a,value:n}=await s.read();if(a)break;n&&(g.set(n,i),i+=n.byteLength)}return o}else{let o=new Uint8Array(8192),g=0;for(;;){const{done:i,value:a}=await s.read();if(i)break;if(a){if(g+a.byteLength>o.length){const n=Math.max(o.length*2,g+a.byteLength),I=new Uint8Array(n);I.set(o.subarray(0,g)),o=I}o.set(a,g),g+=a.byteLength}}return o.slice(0,g).buffer}}finally{s.releaseLock()}}static async decodeAudioData(e,t){try{return await e.decodeAudioData(t)}catch(s){throw console.error("Failed to decode audio data:",s),s}}static async getMetadataFromCache(e,t){try{const s=await t.match(`${e}:meta`);return s?.ok?await s.json():null}catch(s){return console.error("Failed to get metadata from cache:",s),null}}async getAudioBuffer(e,t,s,o){if(o?.onLoadingStart&&o.onLoadingStart({url:t,timestamp:Date.now()}),C.decodedBuffers.has(t))return o?.onCacheHit&&o.onCacheHit({url:t,cacheType:"memory",timestamp:Date.now()}),C.decodedBuffers.get(t);if(t.startsWith("data:")){const n=t.split(",")[1],I=Uint8Array.from(atob(n),l=>l.charCodeAt(0)).buffer,r=await C.decodeAudioData(e,I);return C.decodedBuffers.set(t,r),r}const g=await C.openCache(),i=await C.getMetadataFromCache(t,g),a=(()=>{if(!i||E(i.cacheControl))return!0;const n=K(i.cacheControl);if(n!==null){const I=(Date.now()-i.timestamp)/1e3;if(n>0&&I<n)return!1}return i.etag||i.lastModified?!0:Date.now()-i.timestamp>C.cacheExpirationTime})();return C.getOrCreatePendingRequest(t,async()=>{if(a){o?.onCacheMiss&&o.onCacheMiss({url:t,reason:i?"expired":"not-found",timestamp:Date.now()});try{const n=await C.fetchAndCacheBuffer(t,g,i?.etag,i?.lastModified,s,{onCacheHit:o?.onCacheHit});let I;try{I=await C.decodeAudioData(e,n)}catch(r){throw o?.onLoadingError&&o.onLoadingError({url:t,error:r,errorType:"decode",timestamp:Date.now()}),r}return o?.onLoadingComplete&&o.onLoadingComplete({url:t,duration:I.duration,size:n.byteLength,timestamp:Date.now()}),C.decodedBuffers.set(t,I),I}catch(n){throw o?.onLoadingError&&o.onLoadingError({url:t,error:n,errorType:k(n),timestamp:Date.now()}),o?.onCacheError&&o.onCacheError({url:t,error:n,operation:"get",timestamp:Date.now()}),n}}else{const n=await C.getBufferFromCache(t,g);if(n){o?.onCacheHit&&o.onCacheHit({url:t,cacheType:"browser",timestamp:Date.now()});const I=await C.decodeAudioData(e,n);return C.decodedBuffers.set(t,I),I}else{o?.onCacheError&&o.onCacheError({url:t,error:new Error("Cache inconsistency: metadata exists but body is missing"),operation:"get",timestamp:Date.now()});try{const I=await C.fetchAndCacheBuffer(t,g,i?.etag,i?.lastModified,s,{onCacheHit:o?.onCacheHit});let r;try{r=await C.decodeAudioData(e,I)}catch(l){throw o?.onLoadingError&&o.onLoadingError({url:t,error:l,errorType:"decode",timestamp:Date.now()}),l}return o?.onLoadingComplete&&o.onLoadingComplete({url:t,duration:r.duration,size:I.byteLength,timestamp:Date.now()}),C.decodedBuffers.set(t,r),r}catch(I){throw o?.onLoadingError&&o.onLoadingError({url:t,error:I,errorType:k(I),timestamp:Date.now()}),I}}}},s,{onLoadingProgress:o?.onLoadingProgress})}clearMemoryCache(){C.decodedBuffers=new R(V),C.pendingRequests.clear()}}const N="data:text/javascript;base64,dmFyIHBoYXNlVm9jb2RlciA9IChmdW5jdGlvbiAoZXhwb3J0cykgewoJJ3VzZSBzdHJpY3QnOwoKCWZ1bmN0aW9uIGdldERlZmF1bHRFeHBvcnRGcm9tQ2pzICh4KSB7CgkJcmV0dXJuIHggJiYgeC5fX2VzTW9kdWxlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnZGVmYXVsdCcpID8geFsnZGVmYXVsdCddIDogeDsKCX0KCglmdW5jdGlvbiBGRlQoc2l6ZSkgewoJICB0aGlzLnNpemUgPSBzaXplIHwgMDsKCSAgaWYgKHRoaXMuc2l6ZSA8PSAxIHx8ICh0aGlzLnNpemUgJiAodGhpcy5zaXplIC0gMSkpICE9PSAwKQoJICAgIHRocm93IG5ldyBFcnJvcignRkZUIHNpemUgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBhbmQgYmlnZ2VyIHRoYW4gMScpOwoKCSAgdGhpcy5fY3NpemUgPSBzaXplIDw8IDE7CgoJICAvLyBOT1RFOiBVc2Ugb2YgYHZhcmAgaXMgaW50ZW50aW9uYWwgZm9yIG9sZCBWOCB2ZXJzaW9ucwoJICB2YXIgdGFibGUgPSBuZXcgQXJyYXkodGhpcy5zaXplICogMik7CgkgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFibGUubGVuZ3RoOyBpICs9IDIpIHsKCSAgICBjb25zdCBhbmdsZSA9IE1hdGguUEkgKiBpIC8gdGhpcy5zaXplOwoJICAgIHRhYmxlW2ldID0gTWF0aC5jb3MoYW5nbGUpOwoJICAgIHRhYmxlW2kgKyAxXSA9IC1NYXRoLnNpbihhbmdsZSk7CgkgIH0KCSAgdGhpcy50YWJsZSA9IHRhYmxlOwoKCSAgLy8gRmluZCBzaXplJ3MgcG93ZXIgb2YgdHdvCgkgIHZhciBwb3dlciA9IDA7CgkgIGZvciAodmFyIHQgPSAxOyB0aGlzLnNpemUgPiB0OyB0IDw8PSAxKQoJICAgIHBvd2VyKys7CgoJICAvLyBDYWxjdWxhdGUgaW5pdGlhbCBzdGVwJ3Mgd2lkdGg6CgkgIC8vICAgKiBJZiB3ZSBhcmUgZnVsbCByYWRpeC00IC0gaXQgaXMgMnggc21hbGxlciB0byBnaXZlIGluaXRhbCBsZW49OAoJICAvLyAgICogT3RoZXJ3aXNlIGl0IGlzIHRoZSBzYW1lIGFzIGBwb3dlcmAgdG8gZ2l2ZSBsZW49NAoJICB0aGlzLl93aWR0aCA9IHBvd2VyICUgMiA9PT0gMCA/IHBvd2VyIC0gMSA6IHBvd2VyOwoKCSAgLy8gUHJlLWNvbXB1dGUgYml0LXJldmVyc2FsIHBhdHRlcm5zCgkgIHRoaXMuX2JpdHJldiA9IG5ldyBBcnJheSgxIDw8IHRoaXMuX3dpZHRoKTsKCSAgZm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLl9iaXRyZXYubGVuZ3RoOyBqKyspIHsKCSAgICB0aGlzLl9iaXRyZXZbal0gPSAwOwoJICAgIGZvciAodmFyIHNoaWZ0ID0gMDsgc2hpZnQgPCB0aGlzLl93aWR0aDsgc2hpZnQgKz0gMikgewoJICAgICAgdmFyIHJldlNoaWZ0ID0gdGhpcy5fd2lkdGggLSBzaGlmdCAtIDI7CgkgICAgICB0aGlzLl9iaXRyZXZbal0gfD0gKChqID4+PiBzaGlmdCkgJiAzKSA8PCByZXZTaGlmdDsKCSAgICB9CgkgIH0KCgkgIHRoaXMuX291dCA9IG51bGw7CgkgIHRoaXMuX2RhdGEgPSBudWxsOwoJICB0aGlzLl9pbnYgPSAwOwoJfQoJdmFyIGZmdCA9IEZGVDsKCglGRlQucHJvdG90eXBlLmZyb21Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiBmcm9tQ29tcGxleEFycmF5KGNvbXBsZXgsIHN0b3JhZ2UpIHsKCSAgdmFyIHJlcyA9IHN0b3JhZ2UgfHwgbmV3IEFycmF5KGNvbXBsZXgubGVuZ3RoID4+PiAxKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb21wbGV4Lmxlbmd0aDsgaSArPSAyKQoJICAgIHJlc1tpID4+PiAxXSA9IGNvbXBsZXhbaV07CgkgIHJldHVybiByZXM7Cgl9OwoKCUZGVC5wcm90b3R5cGUuY3JlYXRlQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gY3JlYXRlQ29tcGxleEFycmF5KCkgewoJICBjb25zdCByZXMgPSBuZXcgQXJyYXkodGhpcy5fY3NpemUpOwoJICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkrKykKCSAgICByZXNbaV0gPSAwOwoJICByZXR1cm4gcmVzOwoJfTsKCglGRlQucHJvdG90eXBlLnRvQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gdG9Db21wbGV4QXJyYXkoaW5wdXQsIHN0b3JhZ2UpIHsKCSAgdmFyIHJlcyA9IHN0b3JhZ2UgfHwgdGhpcy5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpICs9IDIpIHsKCSAgICByZXNbaV0gPSBpbnB1dFtpID4+PiAxXTsKCSAgICByZXNbaSArIDFdID0gMDsKCSAgfQoJICByZXR1cm4gcmVzOwoJfTsKCglGRlQucHJvdG90eXBlLmNvbXBsZXRlU3BlY3RydW0gPSBmdW5jdGlvbiBjb21wbGV0ZVNwZWN0cnVtKHNwZWN0cnVtKSB7CgkgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgkgIHZhciBoYWxmID0gc2l6ZSA+Pj4gMTsKCSAgZm9yICh2YXIgaSA9IDI7IGkgPCBoYWxmOyBpICs9IDIpIHsKCSAgICBzcGVjdHJ1bVtzaXplIC0gaV0gPSBzcGVjdHJ1bVtpXTsKCSAgICBzcGVjdHJ1bVtzaXplIC0gaSArIDFdID0gLXNwZWN0cnVtW2kgKyAxXTsKCSAgfQoJfTsKCglGRlQucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uIHRyYW5zZm9ybShvdXQsIGRhdGEpIHsKCSAgaWYgKG91dCA9PT0gZGF0YSkKCSAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKCSAgdGhpcy5fb3V0ID0gb3V0OwoJICB0aGlzLl9kYXRhID0gZGF0YTsKCSAgdGhpcy5faW52ID0gMDsKCSAgdGhpcy5fdHJhbnNmb3JtNCgpOwoJICB0aGlzLl9vdXQgPSBudWxsOwoJICB0aGlzLl9kYXRhID0gbnVsbDsKCX07CgoJRkZULnByb3RvdHlwZS5yZWFsVHJhbnNmb3JtID0gZnVuY3Rpb24gcmVhbFRyYW5zZm9ybShvdXQsIGRhdGEpIHsKCSAgaWYgKG91dCA9PT0gZGF0YSkKCSAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKCSAgdGhpcy5fb3V0ID0gb3V0OwoJICB0aGlzLl9kYXRhID0gZGF0YTsKCSAgdGhpcy5faW52ID0gMDsKCSAgdGhpcy5fcmVhbFRyYW5zZm9ybTQoKTsKCSAgdGhpcy5fb3V0ID0gbnVsbDsKCSAgdGhpcy5fZGF0YSA9IG51bGw7Cgl9OwoKCUZGVC5wcm90b3R5cGUuaW52ZXJzZVRyYW5zZm9ybSA9IGZ1bmN0aW9uIGludmVyc2VUcmFuc2Zvcm0ob3V0LCBkYXRhKSB7CgkgIGlmIChvdXQgPT09IGRhdGEpCgkgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgbXVzdCBiZSBkaWZmZXJlbnQnKTsKCgkgIHRoaXMuX291dCA9IG91dDsKCSAgdGhpcy5fZGF0YSA9IGRhdGE7CgkgIHRoaXMuX2ludiA9IDE7CgkgIHRoaXMuX3RyYW5zZm9ybTQoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXQubGVuZ3RoOyBpKyspCgkgICAgb3V0W2ldIC89IHRoaXMuc2l6ZTsKCSAgdGhpcy5fb3V0ID0gbnVsbDsKCSAgdGhpcy5fZGF0YSA9IG51bGw7Cgl9OwoKCS8vIHJhZGl4LTQgaW1wbGVtZW50YXRpb24KCS8vCgkvLyBOT1RFOiBVc2VzIG9mIGB2YXJgIGFyZSBpbnRlbnRpb25hbCBmb3Igb2xkZXIgVjggdmVyc2lvbiB0aGF0IGRvIG5vdAoJLy8gc3VwcG9ydCBib3RoIGBsZXQgY29tcG91bmQgYXNzaWdubWVudHNgIGFuZCBgY29uc3QgcGhpYAoJRkZULnByb3RvdHlwZS5fdHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF90cmFuc2Zvcm00KCkgewoJICB2YXIgb3V0ID0gdGhpcy5fb3V0OwoJICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKCSAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCgkgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwoJICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CgkgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgoJICB2YXIgb3V0T2ZmOwoJICB2YXIgdDsKCSAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKCSAgaWYgKGxlbiA9PT0gNCkgewoJICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewoJICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwoJICAgICAgdGhpcy5fc2luZ2xlVHJhbnNmb3JtMihvdXRPZmYsIG9mZiwgc3RlcCk7CgkgICAgfQoJICB9IGVsc2UgewoJICAgIC8vIGxlbiA9PT0gOAoJICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewoJICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwoJICAgICAgdGhpcy5fc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwgc3RlcCk7CgkgICAgfQoJICB9CgoJICAvLyBMb29wIHRocm91Z2ggc3RlcHMgaW4gZGVjcmVhc2luZyBvcmRlcgoJICB2YXIgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICB2YXIgdGFibGUgPSB0aGlzLnRhYmxlOwoJICBmb3IgKHN0ZXAgPj49IDI7IHN0ZXAgPj0gMjsgc3RlcCA+Pj0gMikgewoJICAgIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCSAgICB2YXIgcXVhcnRlckxlbiA9IGxlbiA+Pj4gMjsKCgkgICAgLy8gTG9vcCB0aHJvdWdoIG9mZnNldHMgaW4gdGhlIGRhdGEKCSAgICBmb3IgKG91dE9mZiA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4pIHsKCSAgICAgIC8vIEZ1bGwgY2FzZQoJICAgICAgdmFyIGxpbWl0ID0gb3V0T2ZmICsgcXVhcnRlckxlbjsKCSAgICAgIGZvciAodmFyIGkgPSBvdXRPZmYsIGsgPSAwOyBpIDwgbGltaXQ7IGkgKz0gMiwgayArPSBzdGVwKSB7CgkgICAgICAgIGNvbnN0IEEgPSBpOwoJICAgICAgICBjb25zdCBCID0gQSArIHF1YXJ0ZXJMZW47CgkgICAgICAgIGNvbnN0IEMgPSBCICsgcXVhcnRlckxlbjsKCSAgICAgICAgY29uc3QgRCA9IEMgKyBxdWFydGVyTGVuOwoKCSAgICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgICAgICAgIGNvbnN0IEFyID0gb3V0W0FdOwoJICAgICAgICBjb25zdCBBaSA9IG91dFtBICsgMV07CgkgICAgICAgIGNvbnN0IEJyID0gb3V0W0JdOwoJICAgICAgICBjb25zdCBCaSA9IG91dFtCICsgMV07CgkgICAgICAgIGNvbnN0IENyID0gb3V0W0NdOwoJICAgICAgICBjb25zdCBDaSA9IG91dFtDICsgMV07CgkgICAgICAgIGNvbnN0IERyID0gb3V0W0RdOwoJICAgICAgICBjb25zdCBEaSA9IG91dFtEICsgMV07CgoJICAgICAgICAvLyBNaWRkbGUgdmFsdWVzCgkgICAgICAgIGNvbnN0IE1BciA9IEFyOwoJICAgICAgICBjb25zdCBNQWkgPSBBaTsKCgkgICAgICAgIGNvbnN0IHRhYmxlQnIgPSB0YWJsZVtrXTsKCSAgICAgICAgY29uc3QgdGFibGVCaSA9IGludiAqIHRhYmxlW2sgKyAxXTsKCSAgICAgICAgY29uc3QgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwoJICAgICAgICBjb25zdCBNQmkgPSBCciAqIHRhYmxlQmkgKyBCaSAqIHRhYmxlQnI7CgoJICAgICAgICBjb25zdCB0YWJsZUNyID0gdGFibGVbMiAqIGtdOwoJICAgICAgICBjb25zdCB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKCSAgICAgICAgY29uc3QgTUNyID0gQ3IgKiB0YWJsZUNyIC0gQ2kgKiB0YWJsZUNpOwoJICAgICAgICBjb25zdCBNQ2kgPSBDciAqIHRhYmxlQ2kgKyBDaSAqIHRhYmxlQ3I7CgoJICAgICAgICBjb25zdCB0YWJsZURyID0gdGFibGVbMyAqIGtdOwoJICAgICAgICBjb25zdCB0YWJsZURpID0gaW52ICogdGFibGVbMyAqIGsgKyAxXTsKCSAgICAgICAgY29uc3QgTURyID0gRHIgKiB0YWJsZURyIC0gRGkgKiB0YWJsZURpOwoJICAgICAgICBjb25zdCBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgoJICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgICAgICAgIGNvbnN0IFQwciA9IE1BciArIE1DcjsKCSAgICAgICAgY29uc3QgVDBpID0gTUFpICsgTUNpOwoJICAgICAgICBjb25zdCBUMXIgPSBNQXIgLSBNQ3I7CgkgICAgICAgIGNvbnN0IFQxaSA9IE1BaSAtIE1DaTsKCSAgICAgICAgY29uc3QgVDJyID0gTUJyICsgTURyOwoJICAgICAgICBjb25zdCBUMmkgPSBNQmkgKyBNRGk7CgkgICAgICAgIGNvbnN0IFQzciA9IGludiAqIChNQnIgLSBNRHIpOwoJICAgICAgICBjb25zdCBUM2kgPSBpbnYgKiAoTUJpIC0gTURpKTsKCgkgICAgICAgIC8vIEZpbmFsIHZhbHVlcwoJICAgICAgICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CgkgICAgICAgIGNvbnN0IEZBaSA9IFQwaSArIFQyaTsKCgkgICAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCSAgICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKCSAgICAgICAgY29uc3QgRkJyID0gVDFyICsgVDNpOwoJICAgICAgICBjb25zdCBGQmkgPSBUMWkgLSBUM3I7CgoJICAgICAgICBjb25zdCBGRHIgPSBUMXIgLSBUM2k7CgkgICAgICAgIGNvbnN0IEZEaSA9IFQxaSArIFQzcjsKCgkgICAgICAgIG91dFtBXSA9IEZBcjsKCSAgICAgICAgb3V0W0EgKyAxXSA9IEZBaTsKCSAgICAgICAgb3V0W0JdID0gRkJyOwoJICAgICAgICBvdXRbQiArIDFdID0gRkJpOwoJICAgICAgICBvdXRbQ10gPSBGQ3I7CgkgICAgICAgIG91dFtDICsgMV0gPSBGQ2k7CgkgICAgICAgIG91dFtEXSA9IEZEcjsKCSAgICAgICAgb3V0W0QgKyAxXSA9IEZEaTsKCSAgICAgIH0KCSAgICB9CgkgIH0KCX07CgoJLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgoJLy8KCS8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAoJRkZULnByb3RvdHlwZS5fc2luZ2xlVHJhbnNmb3JtMiA9IGZ1bmN0aW9uIF9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCgkgIGNvbnN0IGV2ZW5SID0gZGF0YVtvZmZdOwoJICBjb25zdCBldmVuSSA9IGRhdGFbb2ZmICsgMV07CgkgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoJICBjb25zdCBvZGRJID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CgoJICBjb25zdCBsZWZ0UiA9IGV2ZW5SICsgb2RkUjsKCSAgY29uc3QgbGVmdEkgPSBldmVuSSArIG9kZEk7CgkgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCSAgY29uc3QgcmlnaHRJID0gZXZlbkkgLSBvZGRJOwoKCSAgb3V0W291dE9mZl0gPSBsZWZ0UjsKCSAgb3V0W291dE9mZiArIDFdID0gbGVmdEk7CgkgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKCSAgb3V0W291dE9mZiArIDNdID0gcmlnaHRJOwoJfTsKCgkvLyByYWRpeC00CgkvLwoJLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj04CglGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTQob3V0T2ZmLCBvZmYsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewoJICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CgkgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoJICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CgkgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CgkgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgoJICAvLyBPcmlnaW5hbCB2YWx1ZXMKCSAgY29uc3QgQXIgPSBkYXRhW29mZl07CgkgIGNvbnN0IEFpID0gZGF0YVtvZmYgKyAxXTsKCSAgY29uc3QgQnIgPSBkYXRhW29mZiArIHN0ZXBdOwoJICBjb25zdCBCaSA9IGRhdGFbb2ZmICsgc3RlcCArIDFdOwoJICBjb25zdCBDciA9IGRhdGFbb2ZmICsgc3RlcDJdOwoJICBjb25zdCBDaSA9IGRhdGFbb2ZmICsgc3RlcDIgKyAxXTsKCSAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCSAgY29uc3QgRGkgPSBkYXRhW29mZiArIHN0ZXAzICsgMV07CgoJICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgIGNvbnN0IFQwciA9IEFyICsgQ3I7CgkgIGNvbnN0IFQwaSA9IEFpICsgQ2k7CgkgIGNvbnN0IFQxciA9IEFyIC0gQ3I7CgkgIGNvbnN0IFQxaSA9IEFpIC0gQ2k7CgkgIGNvbnN0IFQyciA9IEJyICsgRHI7CgkgIGNvbnN0IFQyaSA9IEJpICsgRGk7CgkgIGNvbnN0IFQzciA9IGludiAqIChCciAtIERyKTsKCSAgY29uc3QgVDNpID0gaW52ICogKEJpIC0gRGkpOwoKCSAgLy8gRmluYWwgdmFsdWVzCgkgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCSAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKCSAgY29uc3QgRkJyID0gVDFyICsgVDNpOwoJICBjb25zdCBGQmkgPSBUMWkgLSBUM3I7CgoJICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CgkgIGNvbnN0IEZDaSA9IFQwaSAtIFQyaTsKCgkgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKCSAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKCSAgb3V0W291dE9mZl0gPSBGQXI7CgkgIG91dFtvdXRPZmYgKyAxXSA9IEZBaTsKCSAgb3V0W291dE9mZiArIDJdID0gRkJyOwoJICBvdXRbb3V0T2ZmICsgM10gPSBGQmk7CgkgIG91dFtvdXRPZmYgKyA0XSA9IEZDcjsKCSAgb3V0W291dE9mZiArIDVdID0gRkNpOwoJICBvdXRbb3V0T2ZmICsgNl0gPSBGRHI7CgkgIG91dFtvdXRPZmYgKyA3XSA9IEZEaTsKCX07CgoJLy8gUmVhbCBpbnB1dCByYWRpeC00IGltcGxlbWVudGF0aW9uCglGRlQucHJvdG90eXBlLl9yZWFsVHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF9yZWFsVHJhbnNmb3JtNCgpIHsKCSAgdmFyIG91dCA9IHRoaXMuX291dDsKCSAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKCgkgIC8vIEluaXRpYWwgc3RlcCAocGVybXV0ZSBhbmQgdHJhbnNmb3JtKQoJICB2YXIgd2lkdGggPSB0aGlzLl93aWR0aDsKCSAgdmFyIHN0ZXAgPSAxIDw8IHdpZHRoOwoJICB2YXIgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwoKCSAgdmFyIG91dE9mZjsKCSAgdmFyIHQ7CgkgIHZhciBiaXRyZXYgPSB0aGlzLl9iaXRyZXY7CgkgIGlmIChsZW4gPT09IDQpIHsKCSAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKCSAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKCSAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKCSAgICB9CgkgIH0gZWxzZSB7CgkgICAgLy8gbGVuID09PSA4CgkgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CgkgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CgkgICAgICB0aGlzLl9zaW5nbGVSZWFsVHJhbnNmb3JtNChvdXRPZmYsIG9mZiA+Pj4gMSwgc3RlcCA+Pj4gMSk7CgkgICAgfQoJICB9CgoJICAvLyBMb29wIHRocm91Z2ggc3RlcHMgaW4gZGVjcmVhc2luZyBvcmRlcgoJICB2YXIgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICB2YXIgdGFibGUgPSB0aGlzLnRhYmxlOwoJICBmb3IgKHN0ZXAgPj49IDI7IHN0ZXAgPj0gMjsgc3RlcCA+Pj0gMikgewoJICAgIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCSAgICB2YXIgaGFsZkxlbiA9IGxlbiA+Pj4gMTsKCSAgICB2YXIgcXVhcnRlckxlbiA9IGhhbGZMZW4gPj4+IDE7CgkgICAgdmFyIGhxdWFydGVyTGVuID0gcXVhcnRlckxlbiA+Pj4gMTsKCgkgICAgLy8gTG9vcCB0aHJvdWdoIG9mZnNldHMgaW4gdGhlIGRhdGEKCSAgICBmb3IgKG91dE9mZiA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4pIHsKCSAgICAgIGZvciAodmFyIGkgPSAwLCBrID0gMDsgaSA8PSBocXVhcnRlckxlbjsgaSArPSAyLCBrICs9IHN0ZXApIHsKCSAgICAgICAgdmFyIEEgPSBvdXRPZmYgKyBpOwoJICAgICAgICB2YXIgQiA9IEEgKyBxdWFydGVyTGVuOwoJICAgICAgICB2YXIgQyA9IEIgKyBxdWFydGVyTGVuOwoJICAgICAgICB2YXIgRCA9IEMgKyBxdWFydGVyTGVuOwoKCSAgICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgICAgICAgIHZhciBBciA9IG91dFtBXTsKCSAgICAgICAgdmFyIEFpID0gb3V0W0EgKyAxXTsKCSAgICAgICAgdmFyIEJyID0gb3V0W0JdOwoJICAgICAgICB2YXIgQmkgPSBvdXRbQiArIDFdOwoJICAgICAgICB2YXIgQ3IgPSBvdXRbQ107CgkgICAgICAgIHZhciBDaSA9IG91dFtDICsgMV07CgkgICAgICAgIHZhciBEciA9IG91dFtEXTsKCSAgICAgICAgdmFyIERpID0gb3V0W0QgKyAxXTsKCgkgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKCSAgICAgICAgdmFyIE1BciA9IEFyOwoJICAgICAgICB2YXIgTUFpID0gQWk7CgoJICAgICAgICB2YXIgdGFibGVCciA9IHRhYmxlW2tdOwoJICAgICAgICB2YXIgdGFibGVCaSA9IGludiAqIHRhYmxlW2sgKyAxXTsKCSAgICAgICAgdmFyIE1CciA9IEJyICogdGFibGVCciAtIEJpICogdGFibGVCaTsKCSAgICAgICAgdmFyIE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCgkgICAgICAgIHZhciB0YWJsZUNyID0gdGFibGVbMiAqIGtdOwoJICAgICAgICB2YXIgdGFibGVDaSA9IGludiAqIHRhYmxlWzIgKiBrICsgMV07CgkgICAgICAgIHZhciBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CgkgICAgICAgIHZhciBNQ2kgPSBDciAqIHRhYmxlQ2kgKyBDaSAqIHRhYmxlQ3I7CgoJICAgICAgICB2YXIgdGFibGVEciA9IHRhYmxlWzMgKiBrXTsKCSAgICAgICAgdmFyIHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwoJICAgICAgICB2YXIgTURyID0gRHIgKiB0YWJsZURyIC0gRGkgKiB0YWJsZURpOwoJICAgICAgICB2YXIgTURpID0gRHIgKiB0YWJsZURpICsgRGkgKiB0YWJsZURyOwoKCSAgICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwoJICAgICAgICB2YXIgVDByID0gTUFyICsgTUNyOwoJICAgICAgICB2YXIgVDBpID0gTUFpICsgTUNpOwoJICAgICAgICB2YXIgVDFyID0gTUFyIC0gTUNyOwoJICAgICAgICB2YXIgVDFpID0gTUFpIC0gTUNpOwoJICAgICAgICB2YXIgVDJyID0gTUJyICsgTURyOwoJICAgICAgICB2YXIgVDJpID0gTUJpICsgTURpOwoJICAgICAgICB2YXIgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CgkgICAgICAgIHZhciBUM2kgPSBpbnYgKiAoTUJpIC0gTURpKTsKCgkgICAgICAgIC8vIEZpbmFsIHZhbHVlcwoJICAgICAgICB2YXIgRkFyID0gVDByICsgVDJyOwoJICAgICAgICB2YXIgRkFpID0gVDBpICsgVDJpOwoKCSAgICAgICAgdmFyIEZCciA9IFQxciArIFQzaTsKCSAgICAgICAgdmFyIEZCaSA9IFQxaSAtIFQzcjsKCgkgICAgICAgIG91dFtBXSA9IEZBcjsKCSAgICAgICAgb3V0W0EgKyAxXSA9IEZBaTsKCSAgICAgICAgb3V0W0JdID0gRkJyOwoJICAgICAgICBvdXRbQiArIDFdID0gRkJpOwoKCSAgICAgICAgLy8gT3V0cHV0IGZpbmFsIG1pZGRsZSBwb2ludAoJICAgICAgICBpZiAoaSA9PT0gMCkgewoJICAgICAgICAgIHZhciBGQ3IgPSBUMHIgLSBUMnI7CgkgICAgICAgICAgdmFyIEZDaSA9IFQwaSAtIFQyaTsKCSAgICAgICAgICBvdXRbQ10gPSBGQ3I7CgkgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKCSAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgfQoKCSAgICAgICAgLy8gRG8gbm90IG92ZXJ3cml0ZSBvdXJzZWx2ZXMKCSAgICAgICAgaWYgKGkgPT09IGhxdWFydGVyTGVuKQoJICAgICAgICAgIGNvbnRpbnVlOwoKCSAgICAgICAgLy8gSW4gdGhlIGZsaXBwZWQgY2FzZToKCSAgICAgICAgLy8gTUFpID0gLU1BaQoJICAgICAgICAvLyBNQnI9LU1CaSwgTUJpPS1NQnIKCSAgICAgICAgLy8gTUNyPS1NQ3IKCSAgICAgICAgLy8gTURyPU1EaSwgTURpPU1EcgoJICAgICAgICB2YXIgU1QwciA9IFQxcjsKCSAgICAgICAgdmFyIFNUMGkgPSAtVDFpOwoJICAgICAgICB2YXIgU1QxciA9IFQwcjsKCSAgICAgICAgdmFyIFNUMWkgPSAtVDBpOwoJICAgICAgICB2YXIgU1QyciA9IC1pbnYgKiBUM2k7CgkgICAgICAgIHZhciBTVDJpID0gLWludiAqIFQzcjsKCSAgICAgICAgdmFyIFNUM3IgPSAtaW52ICogVDJpOwoJICAgICAgICB2YXIgU1QzaSA9IC1pbnYgKiBUMnI7CgoJICAgICAgICB2YXIgU0ZBciA9IFNUMHIgKyBTVDJyOwoJICAgICAgICB2YXIgU0ZBaSA9IFNUMGkgKyBTVDJpOwoKCSAgICAgICAgdmFyIFNGQnIgPSBTVDFyICsgU1QzaTsKCSAgICAgICAgdmFyIFNGQmkgPSBTVDFpIC0gU1QzcjsKCgkgICAgICAgIHZhciBTQSA9IG91dE9mZiArIHF1YXJ0ZXJMZW4gLSBpOwoJICAgICAgICB2YXIgU0IgPSBvdXRPZmYgKyBoYWxmTGVuIC0gaTsKCgkgICAgICAgIG91dFtTQV0gPSBTRkFyOwoJICAgICAgICBvdXRbU0EgKyAxXSA9IFNGQWk7CgkgICAgICAgIG91dFtTQl0gPSBTRkJyOwoJICAgICAgICBvdXRbU0IgKyAxXSA9IFNGQmk7CgkgICAgICB9CgkgICAgfQoJICB9Cgl9OwoKCS8vIHJhZGl4LTIgaW1wbGVtZW50YXRpb24KCS8vCgkvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTQKCUZGVC5wcm90b3R5cGUuX3NpbmdsZVJlYWxUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVJlYWxUcmFuc2Zvcm0yKG91dE9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCgkgIGNvbnN0IGV2ZW5SID0gZGF0YVtvZmZdOwoJICBjb25zdCBvZGRSID0gZGF0YVtvZmYgKyBzdGVwXTsKCgkgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwoJICBjb25zdCByaWdodFIgPSBldmVuUiAtIG9kZFI7CgoJICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwoJICBvdXRbb3V0T2ZmICsgMV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgMl0gPSByaWdodFI7CgkgIG91dFtvdXRPZmYgKyAzXSA9IDA7Cgl9OwoKCS8vIHJhZGl4LTQKCS8vCgkvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKCUZGVC5wcm90b3R5cGUuX3NpbmdsZVJlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCSAgY29uc3QgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICBjb25zdCBzdGVwMiA9IHN0ZXAgKiAyOwoJICBjb25zdCBzdGVwMyA9IHN0ZXAgKiAzOwoKCSAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgIGNvbnN0IEFyID0gZGF0YVtvZmZdOwoJICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CgkgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CgkgIGNvbnN0IERyID0gZGF0YVtvZmYgKyBzdGVwM107CgoJICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgIGNvbnN0IFQwciA9IEFyICsgQ3I7CgkgIGNvbnN0IFQxciA9IEFyIC0gQ3I7CgkgIGNvbnN0IFQyciA9IEJyICsgRHI7CgkgIGNvbnN0IFQzciA9IGludiAqIChCciAtIERyKTsKCgkgIC8vIEZpbmFsIHZhbHVlcwoJICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CgoJICBjb25zdCBGQnIgPSBUMXI7CgkgIGNvbnN0IEZCaSA9IC1UM3I7CgoJICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CgoJICBjb25zdCBGRHIgPSBUMXI7CgkgIGNvbnN0IEZEaSA9IFQzcjsKCgkgIG91dFtvdXRPZmZdID0gRkFyOwoJICBvdXRbb3V0T2ZmICsgMV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CgkgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKCSAgb3V0W291dE9mZiArIDRdID0gRkNyOwoJICBvdXRbb3V0T2ZmICsgNV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgNl0gPSBGRHI7CgkgIG91dFtvdXRPZmYgKyA3XSA9IEZEaTsKCX07CgoJdmFyIEZGVCQxID0gLypAX19QVVJFX18qL2dldERlZmF1bHRFeHBvcnRGcm9tQ2pzKGZmdCk7CgoJY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKCWNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwoJLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KCWNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CgkgICAgbmJJbnB1dHM7CgkgICAgbmJPdXRwdXRzOwoJICAgIGJsb2NrU2l6ZTsKCSAgICBob3BTaXplOwoJICAgIG5iT3ZlcmxhcHM7CgkgICAgaW5wdXRCdWZmZXJzID0gW107CgkgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwoJICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwoJICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKCSAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwoJICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKCSAgICAgICAgc3VwZXIob3B0aW9ucyk7CgkgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CgkgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKCSAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKCSAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKCSAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CgkgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKCSAgICB9CgkgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwoJICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwoJICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwoJICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwoJICAgICAgICB9CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwoJICAgICAgICB9CgkgICAgfQoJICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CgkgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CgkgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CgkgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGNvbnN0IG5iQ2hhbm5lbHMgPSBpbnB1dHNbaV0ubGVuZ3RoOwoJICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIG5iQ2hhbm5lbHMpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgY29uc3QgbmJDaGFubmVscyA9IG91dHB1dHNbaV0ubGVuZ3RoOwoJICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlT3V0cHV0Q2hhbm5lbHMoaSwgbmJDaGFubmVscyk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmVhZElucHV0cyhpbnB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICBjb25zdCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewoJICAgICAgICAgICAgICAgIGNvbnN0IHdlYkF1ZGlvQmxvY2sgPSBvdXRwdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHdlYkF1ZGlvQmxvY2suc2V0KHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXS5zdWJhcnJheSgwLCBXRUJBVURJT19CTE9DS19TSVpFKSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgc2hpZnRJbnB1dEJ1ZmZlcnMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaV1bal0uY29weVdpdGhpbigwLCBXRUJBVURJT19CTE9DS19TSVpFKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgICBzaGlmdE91dHB1dEJ1ZmZlcnMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uY29weVdpdGhpbigwLCBXRUJBVURJT19CTE9DS19TSVpFKTsKCSAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uZmlsbCgwLCB0aGlzLmJsb2NrU2l6ZSAtIFdFQkFVRElPX0JMT0NLX1NJWkUpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHByZXBhcmVJbnB1dEJ1ZmZlcnNUb1NlbmQoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaV1bal0uc2V0KHRoaXMuaW5wdXRCdWZmZXJzSGVhZFtpXVtqXSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHRoaXMuYmxvY2tTaXplOyBrKyspIHsKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdW2tdICs9IHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbaV1bal1ba10gLyB0aGlzLm5iT3ZlcmxhcHM7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CgkgICAgICAgIHRoaXMucmVhbGxvY2F0ZUNoYW5uZWxzSWZOZWVkZWQoaW5wdXRzLCBvdXRwdXRzKTsKCSAgICAgICAgdGhpcy5yZWFkSW5wdXRzKGlucHV0cyk7CgkgICAgICAgIHRoaXMuc2hpZnRJbnB1dEJ1ZmZlcnMoKTsKCSAgICAgICAgdGhpcy5wcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCk7CgkgICAgICAgIHRoaXMucHJvY2Vzc09MQSh0aGlzLmlucHV0QnVmZmVyc1RvU2VuZCwgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSwgcGFyYW1ldGVycyk7CgkgICAgICAgIHRoaXMuaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKTsKCSAgICAgICAgdGhpcy53cml0ZU91dHB1dHMob3V0cHV0cyk7CgkgICAgICAgIHRoaXMuc2hpZnRPdXRwdXRCdWZmZXJzKCk7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCX0KCgljb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKCWZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CgkgICAgY29uc3Qgd2luID0gbmV3IEZsb2F0MzJBcnJheShsZW5ndGgpOwoJICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKCSAgICAgICAgd2luW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcygoMiAqIE1hdGguUEkgKiBpKSAvIGxlbmd0aCkpOwoJICAgIH0KCSAgICByZXR1cm4gd2luOwoJfQoJY2xhc3MgUGhhc2VWb2NvZGVyUHJvY2Vzc29yIGV4dGVuZHMgT0xBUHJvY2Vzc29yIHsKCSAgICBmZnRTaXplOwoJICAgIHRpbWVDdXJzb3I7CgkgICAgaGFubldpbmRvdzsKCSAgICBmZnQ7CgkgICAgZnJlcUNvbXBsZXhCdWZmZXI7CgkgICAgZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkOwoJICAgIHRpbWVDb21wbGV4QnVmZmVyOwoJICAgIG1hZ25pdHVkZXM7CgkgICAgcGVha0luZGV4ZXM7CgkgICAgbmJQZWFrczsKCSAgICBzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkgewoJICAgICAgICByZXR1cm4gWwoJICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgIG5hbWU6ICJwaXRjaEZhY3RvciIsCgkgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAsCgkgICAgICAgICAgICB9LAoJICAgICAgICBdOwoJICAgIH0KCSAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CgkgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKCSAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKCSAgICAgICAgfTsKCSAgICAgICAgc3VwZXIob3B0aW9ucyk7CgkgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwoJICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwoJICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCgkgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CgkgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwoJICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKCSAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwoJICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwoJICAgIH0KCSAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewoJICAgICAgICBjb25zdCBwaXRjaEZhY3RvciA9IHBhcmFtZXRlcnMucGl0Y2hGYWN0b3JbcGFyYW1ldGVycy5waXRjaEZhY3Rvci5sZW5ndGggLSAxXTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gaW5wdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHZhciBvdXRwdXQgPSBvdXRwdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KGlucHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmZmdC5yZWFsVHJhbnNmb3JtKHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIsIGlucHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmNvbXB1dGVNYWduaXR1ZGVzKCk7CgkgICAgICAgICAgICAgICAgdGhpcy5maW5kUGVha3MoKTsKCSAgICAgICAgICAgICAgICB0aGlzLnNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmNvbXBsZXRlU3BlY3RydW0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmludmVyc2VUcmFuc2Zvcm0odGhpcy50aW1lQ29tcGxleEJ1ZmZlciwgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmZyb21Db21wbGV4QXJyYXkodGhpcy50aW1lQ29tcGxleEJ1ZmZlciwgb3V0cHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmFwcGx5SGFubldpbmRvdyhvdXRwdXQpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHRoaXMudGltZUN1cnNvciArPSB0aGlzLmhvcFNpemU7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCSAgICBhcHBseUhhbm5XaW5kb3coaW5wdXQpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKSB7CgkgICAgICAgICAgICBpbnB1dFtpXSAqPSB0aGlzLmhhbm5XaW5kb3dbaV07CgkgICAgICAgIH0KCSAgICB9CgkgICAgY29tcHV0ZU1hZ25pdHVkZXMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IHRoaXMubWFnbml0dWRlcy5sZW5ndGg7IGkrKywgaiArPSAyKSB7CgkgICAgICAgICAgICBjb25zdCByZWFsID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltqXTsKCSAgICAgICAgICAgIGNvbnN0IGltYWcgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2ogKyAxXTsKCSAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpXSA9IHJlYWwgKiogMiArIGltYWcgKiogMjsKCSAgICAgICAgfQoJICAgIH0KCSAgICBmaW5kUGVha3MoKSB7CgkgICAgICAgIHRoaXMubmJQZWFrcyA9IDA7CgkgICAgICAgIGZvciAobGV0IGkgPSAyLCBlbmQgPSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoIC0gMjsgaSA8IGVuZDsgaSsrKSB7CgkgICAgICAgICAgICBjb25zdCBtYWcgPSB0aGlzLm1hZ25pdHVkZXNbaV07CgkgICAgICAgICAgICBpZiAodGhpcy5tYWduaXR1ZGVzW2kgLSAxXSA+PSBtYWcgfHwKCSAgICAgICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fAoJICAgICAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpICsgMV0gPj0gbWFnIHx8CgkgICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2kgKyAyXSA+PSBtYWcpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRoaXMucGVha0luZGV4ZXNbdGhpcy5uYlBlYWtzKytdID0gaTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBzaGlmdFBlYWtzKHBpdGNoRmFjdG9yKSB7CgkgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkLmZpbGwoMCk7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYlBlYWtzOyBpKyspIHsKCSAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleCA9IHRoaXMucGVha0luZGV4ZXNbaV07CgkgICAgICAgICAgICBjb25zdCBwZWFrSW5kZXhTaGlmdGVkID0gTWF0aC5yb3VuZChwZWFrSW5kZXggKiBwaXRjaEZhY3Rvcik7CgkgICAgICAgICAgICBpZiAocGVha0luZGV4U2hpZnRlZCA+IHRoaXMubWFnbml0dWRlcy5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvbnN0IHN0YXJ0SW5kZXggPSBpID4gMCA/IHBlYWtJbmRleCAtIE1hdGguZmxvb3IoKHBlYWtJbmRleCAtIHRoaXMucGVha0luZGV4ZXNbaSAtIDFdKSAvIDIpIDogMDsKCSAgICAgICAgICAgIGNvbnN0IGVuZEluZGV4ID0gaSA8IHRoaXMubmJQZWFrcyAtIDEgPyBwZWFrSW5kZXggKyBNYXRoLmNlaWwoKHRoaXMucGVha0luZGV4ZXNbaSArIDFdIC0gcGVha0luZGV4KSAvIDIpIDogdGhpcy5mZnRTaXplOwoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IHN0YXJ0SW5kZXggLSBwZWFrSW5kZXg7IGogPCBlbmRJbmRleCAtIHBlYWtJbmRleDsgaisrKSB7CgkgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXggPSBwZWFrSW5kZXggKyBqOwoJICAgICAgICAgICAgICAgIGNvbnN0IGJpbkluZGV4U2hpZnRlZCA9IHBlYWtJbmRleFNoaWZ0ZWQgKyBqOwoJICAgICAgICAgICAgICAgIGlmIChiaW5JbmRleFNoaWZ0ZWQgPj0gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY29uc3Qgb21lZ2FEZWx0YSA9ICgyICogTWF0aC5QSSAqIChiaW5JbmRleFNoaWZ0ZWQgLSBiaW5JbmRleCkpIC8gdGhpcy5mZnRTaXplOwoJICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CgkgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKCSAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CgkgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKCSAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CgkgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwoJICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwoJICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwoJICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwoJICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKCSAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwoJICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9Cgl9CgkvLyBAdHMtZXhwZWN0LWVycm9yCglyZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7Cgljb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCglleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCglyZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGhhc2Utdm9jb2Rlci1idW5kbGUuanMubWFwCg==";class b{listeners={};on(e,t){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:t,once:!1}),()=>this.off(e,t)}once(e,t){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:t,once:!0}),()=>this.off(e,t)}off(e,t){const s=this.listeners[e];s&&(this.listeners[e]=s.filter(o=>o.fn!==t))}emit(e,t){const s=this.listeners[e];s&&(s.forEach(o=>o.fn(t)),this.listeners[e]=s.filter(o=>!o.once))}emitAsync(e,t){const s=this.listeners[e];if(s){const o=s.map(g=>Promise.resolve().then(()=>g.fn(t)).catch(i=>console.error(`Error in listener for event ${e}:`,i)));return this.listeners[e]=s.filter(g=>!g.once),Promise.all(o).then(()=>{})}return Promise.resolve()}removeAllListeners(){this.listeners={}}}class S{constructor(e=[]){this.sounds=e}_position=[0,0,0];loopCount=0;playIndex=0;preplayRandom(){if(this.sounds.length===0)return;const t=this.randomSound().preplay();return t.length>0?t[0]:void 0}playRandom(){const e=this.preplayRandom();return e&&e.play(),e}preplayOrdered(e=!0){if(this.sounds.length===0||this.playIndex>=this.sounds.length)return;const s=this.sounds[this.playIndex].preplay();if(s.length!==0)return this.playIndex=(this.playIndex+1)%this.sounds.length,!e&&this.playIndex===0&&(this.playIndex=this.sounds.length),s[0]}playOrdered(e=!0){const t=this.preplayOrdered(e);return t&&t.play(),t}get duration(){return this.sounds.map(e=>e.duration).reduce((e,t)=>Math.max(e,t),0)}seek(e){this.sounds.forEach(t=>t.seek?.(e))}addSound(e){this.sounds.push(e)}randomSound(){if(this.sounds.length===0)throw new Error("Cannot get a random sound from an empty group");const e=Math.floor(Math.random()*this.sounds.length);return this.sounds[e]}preplay(){return this.sounds.map(t=>t.preplay()).flat()}play(){const e=[];return this.preplay().forEach(t=>{t.play(),e.push(t)}),e}get isPlaying(){return this.sounds.some(e=>e.isPlaying)}stop(){this.sounds.forEach(e=>e.stop())}pause(){this.sounds.forEach(e=>e.pause())}fadeTo(e,t,s){return Promise.all(this.sounds.map(o=>o.fadeTo(e,t,s))).then(()=>{})}fadeIn(e,t){return Promise.all(this.sounds.map(s=>s.fadeIn(e,t))).then(()=>{})}fadeOut(e,t){return Promise.all(this.sounds.map(s=>s.fadeOut(e,t))).then(()=>{})}stopWithFade(e,t){return Promise.all(this.sounds.map(s=>s.stopWithFade(e,t))).then(()=>{})}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.sounds.forEach(t=>t.loop(e)),this.loopCount)}addFilter(e){this.sounds.forEach(t=>t.addFilter(e))}removeFilter(e){this.sounds.forEach(t=>t.removeFilter(e))}set position(e){this._position=e,this.sounds.forEach(t=>t.position=this._position)}get position(){return this._position}get volume(){return this.sounds.length===0?1:this.sounds.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.sounds.length}set volume(e){this.sounds.forEach(t=>t.volume=e)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(e){this.sounds.forEach(t=>t.playbackRate=e)}}class y{_filters=[];addFilter(e){if(this._filters.includes(e))throw new Error("Cannot add the same filter instance twice");this._filters.push(e)}removeFilter(e){const t=this._filters.length;if(this._filters=this._filters.filter(s=>s!==e),this._filters.length===t)throw new Error("Cannot remove filter that was never added to this container")}applyFilters(e){return this._filters.reduce((t,s)=>(t.connect(s),s),e),this._filters.length>0?this._filters[this._filters.length-1]:e}get filters(){return this._filters}addFilters(e){e.forEach(t=>this.addFilter(t))}removeFilters(e){e.forEach(t=>this.removeFilter(t))}cleanup(){this._filters.forEach(e=>e.disconnect()),this._filters=[]}}class w extends y{context;source;gainNode;panner;constructor(e,t,s,o=0){super(),this.source=e,this.gainNode=t,this.context=s,this.panner=s.createPanner(),e.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}get isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(e){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=e}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!0)}addFilter(e){super.addFilter(e),this.refreshFilters()}removeFilter(e){super.removeFilter(e),this.refreshFilters()}set position(e){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[t,s,o]=e;this.panner.positionX.value=t,this.panner.positionY.value=s,this.panner.positionZ.value=o}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(e){}}class Y extends y{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(e,t){super(),this.context=e,this.microphoneGainNode=this.context.createGain(),t&&(this.stream=t,this.streamSource=this.createStreamSource(t))}createStreamSource(e){if(!this.context.createMediaStreamSource)throw new Error("Media stream sources are not supported on this audio context (e.g. OfflineAudioContext).");return this.context.createMediaStreamSource(e)}play(){return this.stream?(this.streamPlayback||(this.streamSource=this.streamSource??this.createStreamSource(this.stream),this.streamPlayback=new w(this.streamSource,this.microphoneGainNode,this.context)),[this.streamPlayback]):(navigator.mediaDevices.getUserMedia({audio:!0}).then(e=>{this.stream=e,this.streamSource=this.createStreamSource(this.stream),this.streamPlayback=new w(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(e=>{console.error("Error initializing microphone stream:",e)}),[])}get duration(){return 0}seek(e){}get isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(e){this.streamPlayback&&this.streamPlayback.addFilter(e)}removeFilter(e){this.streamPlayback&&this.streamPlayback.removeFilter(e)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(e){this.streamPlayback&&(this.streamPlayback.volume=e)}get position(){return[0,0,0]}set position(e){}loop(e){return 0}get playbackRate(){return 1}set playbackRate(e){}}function v(c){class e extends c{playbacks=[];_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};_volume=1;play(){const s=this.preplay();return s.forEach(o=>o.play()),s}stop(){this.playbacks.forEach(s=>{s.stop(),s.cleanup()}),this.playbacks=[]}pause(){this.playbacks.forEach(s=>s.pause())}addFilter(s){super.addFilter(s)}removeFilter(s){super.removeFilter(s)}get isPlaying(){return this.playbacks.some(s=>s.isPlaying)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(s){this._threeDOptions.positionX=s[0],this._threeDOptions.positionY=s[1],this._threeDOptions.positionZ=s[2],this.playbacks.forEach(o=>o.position=s)}get threeDOptions(){return this._threeDOptions}set threeDOptions(s){this._threeDOptions={...this._threeDOptions,...s},this.playbacks.forEach(o=>o.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(s){this._stereoPan=s,this.playbacks.forEach(o=>o.stereoPan=s)}get volume(){return this._volume}set volume(s){this._volume=s,this.playbacks.forEach(o=>o.volume=s)}fadeTo(s,o,g){return this._volume=s,Promise.all(this.playbacks.map(i=>i.fadeTo(s,o,g))).then(()=>{})}fadeIn(s,o){return Promise.all(this.playbacks.map(g=>g.fadeIn(s,o))).then(()=>{})}fadeOut(s,o){return Promise.all(this.playbacks.map(g=>g.fadeOut(s,o))).then(()=>{})}stopWithFade(s,o){return this.fadeOut(s,o).then(()=>this.stop())}}return e}function J(c){class e extends c{panner;_panType="stereo";get panType(){return this._panType}setPanType(s,o){this._panType===s&&this.panner||(this.panner&&this.panner.disconnect(),this._panType=s,s==="stereo"?this.panner=o.createStereoPanner():this.panner=o.createPanner())}setPannerNode(s){this.panner=s}get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(s){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");if(s<-1||s>1)throw new RangeError("Stereo pan must be between -1 and 1.");this.panner.pan.setValueAtTime(s,this.panner.context.currentTime)}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const s=this.panner;return{coneInnerAngle:s.coneInnerAngle,coneOuterAngle:s.coneOuterAngle,coneOuterGain:s.coneOuterGain,distanceModel:s.distanceModel,maxDistance:s.maxDistance,channelCount:this.panner.channelCount,channelCountMode:s.channelCountMode,channelInterpretation:s.channelInterpretation,panningModel:s.panningModel,refDistance:s.refDistance,rolloffFactor:s.rolloffFactor,positionX:s.positionX.value,positionY:s.positionY.value,positionZ:s.positionZ.value,orientationX:s.orientationX.value,orientationY:s.orientationY.value,orientationZ:s.orientationZ.value}}set threeDOptions(s){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const o=this.panner;o.coneInnerAngle=s.coneInnerAngle!==void 0?s.coneInnerAngle:o.coneInnerAngle,o.coneOuterAngle=s.coneOuterAngle!==void 0?s.coneOuterAngle:o.coneOuterAngle,o.coneOuterGain=s.coneOuterGain!==void 0?s.coneOuterGain:o.coneOuterGain,o.distanceModel=s.distanceModel||o.distanceModel,o.maxDistance=s.maxDistance!==void 0?s.maxDistance:o.maxDistance,o.channelCount=s.channelCount!==void 0?s.channelCount:o.channelCount,o.channelCountMode=s.channelCountMode||o.channelCountMode,o.channelInterpretation=s.channelInterpretation||o.channelInterpretation,o.panningModel=s.panningModel||o.panningModel,o.refDistance=s.refDistance!==void 0?s.refDistance:o.refDistance,o.rolloffFactor=s.rolloffFactor!==void 0?s.rolloffFactor:o.rolloffFactor,o.positionX.value=s.positionX!==void 0?s.positionX:o.positionX.value,o.positionY.value=s.positionY!==void 0?s.positionY:o.positionY.value,o.positionZ.value=s.positionZ!==void 0?s.positionZ:o.positionZ.value,o.orientationX.value=s.orientationX!==void 0?s.orientationX:o.orientationX.value,o.orientationY.value=s.orientationY!==void 0?s.orientationY:o.orientationY.value,o.orientationZ.value=s.orientationZ!==void 0?s.orientationZ:o.orientationZ.value}set position(s){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[o,g,i]=s,a=this.panner;a.positionX.value=o,a.positionY.value=g,a.positionZ.value=i}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const s=this.panner;return[s.positionX.value,s.positionY.value,s.positionZ.value]}cleanup(){this.panner&&(this.panner.disconnect(),this.panner=void 0),super.cleanup()}}return e}function W(c){class e extends c{gainNode;_fadeTimeout;_isFading=!1;setGainNode(s){this.gainNode=s}cleanup(){this.cancelFade(),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),super.cleanup()}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(s){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.cancelFade(),this.gainNode.gain.value=s}get isFading(){return this._isFading}fadeTo(s,o,g="linear"){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");this.cancelFade();const i=this.gainNode.context.currentTime,a=i+o/1e3;return this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,i),g==="exponential"?this.gainNode.gain.exponentialRampToValueAtTime(s===0?1e-4:s,a):this.gainNode.gain.linearRampToValueAtTime(s,a),this._isFading=!0,new Promise(n=>{this._fadeTimeout=setTimeout(()=>{this._isFading=!1,s===0&&g==="exponential"&&this.gainNode&&(this.gainNode.gain.value=0),n()},o)})}cancelFade(){if(this._fadeTimeout&&(clearTimeout(this._fadeTimeout),this._fadeTimeout=void 0),this._isFading&&this.gainNode){const s=this.gainNode.context.currentTime;this.gainNode.gain.cancelScheduledValues(s),this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,s)}this._isFading=!1}fadeIn(s,o){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");const g=this.gainNode.gain.value;return this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(g,s,o)}fadeOut(s,o){return this.fadeTo(0,s,o)}}return e}class F extends J(W(y)){source;_playing=!1;origin;eventEmitter=new b;constructor(){super()}get isPlaying(){return this.source?this._playing:!1}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}fadeTo(e,t,s="linear"){return this.emit("fadeStart",{target:e,duration:t,type:s}),super.fadeTo(e,t,s).then(()=>{this.emit("fadeEnd",void 0)})}cancelFade(){const e=this._isFading;super.cancelFade(),e&&this.emit("fadeCancel",void 0)}cleanup(){this.eventEmitter.removeAllListeners(),super.cleanup()}}class Z extends F{constructor(e,t,s){super(),this.origin=e,this.context=e.context,this.loopCount=e.loopCount,this.setPanType(e.panType,e.context),this.source=t,"buffer"in t&&t.buffer&&(this.buffer=t.buffer),this.setupSourceNode(t),this.source.connect(this.panner),this.setGainNode(s),this.panner.connect(this.gainNode),this.refreshFilters()}context;loopCount=0;currentLoop=0;buffer;_offset=0;_startTime=0;_state=0;_playbackRate=1;_fadeInConfig;_fadeOutConfig;_loopEndCallback;setupSourceNode(e){if("mediaElement"in e&&e.mediaElement)e.mediaElement.onended=this.loopEnded;else if("onended"in e)e.onended=this.loopEnded;else throw new Error("Unsupported source type")}get isPlaying(){return this._state===1}get duration(){if(!this.source)throw new Error("Cannot get duration of a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.duration:this.buffer?this.buffer.duration||NaN:NaN}get playbackRate(){return this._playbackRate}get volume(){return super.volume}set volume(e){super.volume=e,this.emit("volumeChange",e)}set playbackRate(e){if(e<=0)throw new Error("Playback rate must be greater than 0");if(this._state===1){const t=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=t,this._startTime=this.context.currentTime}this._playbackRate=e,this.source&&("playbackRate"in this.source&&(this.source.playbackRate.value=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=e))}loopEnded=()=>{!this.source||this._state!==1||(this.currentLoop++,this.loopCount!=="infinite"&&this.currentLoop>this.loopCount?(this.emit("ended",void 0),this._fadeOutConfig?this.fadeOut(this._fadeOutConfig.duration,this._fadeOutConfig.type).then(()=>{this.stop(),this.removeFromOrigin()}):(this.stop(),this.removeFromOrigin())):(this._loopEndCallback?.(),this.seek(0),this._state!==1&&!("mediaElement"in this.source)&&this.play(),this._fadeInConfig?.perLoop&&this.gainNode&&(this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(this._fadeInConfig.targetVolume,this._fadeInConfig.duration,this._fadeInConfig.type))))};play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");if(this._state===1)return[this];const e=this._state===2;try{let t;if(this._state===2?"mediaElement"in this.source&&this.source.mediaElement?t=this.source.mediaElement.play():(this.recreateSource(),"start"in this.source&&this.source.start&&this.source.start(0,this._offset)):"mediaElement"in this.source&&this.source.mediaElement?(this.source.mediaElement.currentTime=this._offset,t=this.source.mediaElement.play()):"start"in this.source&&this.source.start&&(this.recreateSource(),this.source.start(0,this._offset)),t){const s=this._state;t.then(()=>{this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),e&&this.emit("resume",void 0),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()})},o=>{this._state=s,this.emitAsync("error",{error:o,errorType:"source",timestamp:Date.now(),recoverable:!0})})}else this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),e&&this.emit("resume",void 0),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()});return[this]}catch(t){throw this.emitAsync("error",{error:t,errorType:"source",timestamp:Date.now(),recoverable:!0}),t}}pause(){if(!this.source||this._state!==1)return;const e=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=e,"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.pause():"stop"in this.source&&this.source.stop(),this._state=2,this.emit("pause",void 0),this.origin.cacophony?.emit("globalPause",{source:this.origin,timestamp:Date.now()})}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this._state===3||this._state===0||(this.cancelFade(),"stop"in this.source&&this._state===1&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this._offset=0,this._startTime=0,this._state=3,this.emit("stop",void 0),this.origin.cacophony?.emit("globalStop",{source:this.origin,timestamp:Date.now()}))}fadeIn(e,t,s){return s?.perLoop&&(this._fadeInConfig={duration:e,type:t||"linear",perLoop:!0,targetVolume:this.gainNode.gain.value}),super.fadeIn(e,t)}configureFadeOut(e,t){this._fadeOutConfig={duration:e,type:t||"linear"}}stopWithFade(e,t){return this.fadeOut(e,t).then(()=>this.stop())}seek(e){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");if(!Number.isFinite(e)||e<0)throw new Error("Invalid time value for seek");const t=this._state===1;t&&this.pause(),this._offset=e,"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.currentTime=e),t&&this.play()}get currentTime(){if(this._state===1){const e=(this.context.currentTime-this._startTime)*this._playbackRate;return this._offset+e}else return this._offset}removeFromOrigin(){const e=this.origin.playbacks.indexOf(this);e!==-1&&this.origin.playbacks.splice(e,1)}recreateSource(){if(!this.buffer||!this.panner||!this.context||!this.gainNode)throw new Error("Cannot recreate source of a sound that has been cleaned up");try{this.source&&(!("mediaElement"in this.source)&&"onended"in this.source&&(this.source.onended=null),this.source.disconnect()),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.source.connect(this.panner),this.source.onended=this.loopEnded,this.playbackRate=this._playbackRate,this.refreshFilters()}catch(e){throw this.emitAsync("error",{error:e,errorType:"source",timestamp:Date.now(),recoverable:!1}),e}}set sourceLoop(e){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=e)}cleanup(){this.source&&("mediaElement"in this.source&&this.source.mediaElement?(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0,this.source.mediaElement.loop=!1,this.source.mediaElement.onended=null):"onended"in this.source&&(this.source.onended=null),this._offset=0,this._startTime=0,this._state=3,this.currentLoop=0,this.source.disconnect(),this.source=void 0,super.cleanup())}assertNotCleanedUp(){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot perform operation on a sound that has been cleaned up")}addFilter(e){this.assertNotCleanedUp(),super.addFilter(e),this.refreshFilters()}removeFilter(e){this.assertNotCleanedUp(),super.removeFilter(e),this.refreshFilters()}loop(e){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(e!==void 0&&(this.loopCount=e==="infinite"?"infinite":Math.max(0,e),this.currentLoop=0),"mediaElement"in this.source&&this.source.mediaElement){const t=this.source.mediaElement;t.loop=this.loopCount==="infinite"}else if("loop"in this.source)this.source.loop=this.loopCount==="infinite",this.source.buffer&&(this.source.loopEnd=this.source.buffer.duration,this.source.loopStart=0);else throw new Error("Unsupported source type");return this.loopCount}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get outputNode(){if(!this.gainNode)throw new Error("Cannot access output node of a playback that has been cleaned up");return this.gainNode}connect(e){return this.outputNode.connect(e)}disconnect(e){e?this.outputNode.disconnect(e):this.outputNode.disconnect()}clone(e={}){if(!this.source||!this.gainNode||!this.context)throw new Error("Cannot clone a sound that has been cleaned up");const t=e.panType||this.panType,s=this.context.createGain();let o;if("buffer"in this.source&&this.source.buffer)o=this.context.createBufferSource(),o.buffer=this.source.buffer;else if("mediaElement"in this.source&&this.source.mediaElement){if(!this.context.createMediaElementSource)throw new Error("Media element sources are not supported on this audio context.");o=this.context.createMediaElementSource(this.source.mediaElement)}else throw new Error("Unsupported source type");const g=e.loopCount!==void 0?e.loopCount:this.loopCount,i=new Z(this.origin,o,s);return i.loopCount=g,i.currentLoop=this.currentLoop,i.setPanType(t,this.context),i.volume=this.volume,i.playbackRate=this._playbackRate,i._offset=this._offset,i._state=this._state,this._filters.forEach(a=>{const n=this.context.createBiquadFilter();n.type=a.type,n.frequency.value=a.frequency.value,n.Q.value=a.Q.value,n.gain.value=a.gain.value,i.addFilter(n)}),this._state===1&&i.play(),i}}class m extends v(y){constructor(e,t,s,o,g=f.Buffer,i="HRTF",a){super(),this.url=e,this.globalGainNode=o,this.soundType=g,this.panType=i,this._cacophony=a,this.buffer=t,this.context=s,this._cacophony?.registerSoundForCleanup(this,this._holdings,this._unregisterToken)}buffer;context;loopCount=0;_playbackRate=1;eventEmitter=new b;_holdings={sources:[],gainNodes:[],mediaElements:[]};_unregisterToken={};get cacophony(){return this._cacophony}get volume(){return super.volume}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}clone(e={}){const t=e.panType||this.panType,s=e.stereoPan!==void 0?e.stereoPan:this.stereoPan,o=e.threeDOptions||this.threeDOptions,g=e.loopCount!==void 0?e.loopCount:this.loopCount,i=e.playbackRate||this.playbackRate,a=e.volume!==void 0?e.volume:this.volume,n=e.position!==void 0?e.position:this.position,I=e.filters?.length?e.filters:this._filters,r=new m(this.url,this.buffer,this.context,this.globalGainNode,this.soundType,t,this.cacophony);return r.loop(g),r.playbackRate=i,r.volume=a,t==="HRTF"?(r.threeDOptions=o,r.position=n):r.stereoPan=s,r.addFilters(I),r}preplay(){try{let e;if(this.buffer)e=this.context.createBufferSource(),e.buffer=this.buffer;else{if(!this.context.createMediaElementSource)throw new Error("Media element sources are not supported on this audio context (e.g. OfflineAudioContext). Use buffer-based sounds instead.");const o=new Audio;o.crossOrigin="anonymous",o.src=this.url,o.preload="auto",e=this.context.createMediaElementSource(o)}const t=this.context.createGain();t.connect(this.globalGainNode);const s=new Z(this,e,t);return this._holdings.sources.push(e),this._holdings.gainNodes.push(t),"mediaElement"in e&&e.mediaElement&&this._holdings.mediaElements.push(e.mediaElement),s.setGainNode(t),s.volume=this.volume,s.playbackRate=this.playbackRate,this._filters.forEach(o=>{const g=this.context.createBiquadFilter();g.type=o.type,g.frequency.value=o.frequency.value,g.Q.value=o.Q.value,g.gain.value=o.gain.value,s.addFilter(g)}),this.panType==="HRTF"?(s.threeDOptions=this.threeDOptions,s.position=this.position):this.panType==="stereo"&&(s.stereoPan=this.stereoPan),s.on("ended",()=>{this.emit("ended",void 0)}),s._loopEndCallback=()=>{this.emit("loopEnd",void 0)},s.on("error",o=>{this.emitAsync("soundError",{url:this.url,error:o.error,errorType:"playback",timestamp:o.timestamp,recoverable:o.recoverable})}),this.playbacks.push(s),[s]}catch(e){const t={url:this.url,error:e,errorType:"playback",timestamp:Date.now(),recoverable:!0};throw this.emitAsync("soundError",t),e}}play(e){const t=this.preplay();for(const s of t){const o=i=>{g(),this.emit("play",i)},g=()=>{s.off("play",o),s.off("error",g)};s.on("play",o),s.on("error",g);try{s.play()}catch(i){throw g(),i}}if(e)for(const s of t)e.fadeIn!==void 0&&s.fadeIn(e.fadeIn,e.fadeType,{perLoop:e.fadeInPerLoop}),e.fadeOut!==void 0&&s.configureFadeOut(e.fadeOut,e.fadeType);return t}stop(){this._holdings.sources.length=0,this._holdings.gainNodes.length=0,this._holdings.mediaElements.length=0,super.stop(),this.emit("stop",void 0)}pause(){super.pause(),this.emit("pause",void 0)}resume(){this.playbacks.forEach(e=>e.play()),this.emit("resume",void 0)}seek(e){this.playbacks.forEach(t=>t.seek(e))}get duration(){return this.playbacks.length>0?this.playbacks[0].duration:this.buffer?.duration||NaN}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.playbacks.forEach(t=>t.loop(e)),this.loopCount)}get playbackRate(){return this._playbackRate}set playbackRate(e){this._playbackRate=e,this.playbacks.forEach(t=>t.playbackRate=e),this.emit("rateChange",e)}set volume(e){super.volume=e,this.emit("volumeChange",e)}cleanup(){this._cacophony?.unregisterSoundCleanup(this._unregisterToken),this._holdings.sources.length=0,this._holdings.gainNodes.length=0,this._holdings.mediaElements.length=0,this.playbacks.forEach(e=>e.cleanup()),this.playbacks=[],this.eventEmitter.removeAllListeners()}}function D(c){class e extends F{_oscillatorOptions={};get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(s){this._oscillatorOptions=s,this.source&&(this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type))}play(){if(!this.source)throw new Error("No source node found");return this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type),this.source.start(),this._playing=!0,[this]}stop(){this.source?.stop&&(this.source.stop(),this._playing=!1)}pause(){this.stop()}get frequency(){return this.source.frequency.value}set frequency(s){this.source.frequency.value=s,this.oscillatorOptions.frequency=s}get detune(){return this.source.detune.value}set detune(s){this.source.detune.value=s,this.oscillatorOptions.detune=s}get type(){return this.source.type}set type(s){this.source.type=s,this.oscillatorOptions.type=s}}return e}class T extends D(J(W(y))){constructor(e,t,s){super(),this.origin=e,this.source=t,this.context=e.context,this.setPanType(e.panType,e.context),this.source.connect(this.panner),this.setGainNode(s),this.panner.connect(this.gainNode),this.refreshFilters(),this.oscillatorOptions={detune:t.detune.value,frequency:t.frequency.value,type:t.type}}context;_state=0;play(){if(!this.source||!this.panner)throw new Error("Cannot play a synth that has been cleaned up");return this._state===1?[this]:((this._state===2||this._state===3)&&this.recreateSource(),this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type),this.source.start(),this._playing=!0,this._state=1,[this])}pause(){!this.source||this._state!==1||(this.source.stop(),this._playing=!1,this._state=2)}stop(){!this.source||this._state===0||this._state===3||(this._state===1&&this.source.stop(),this._playing=!1,this._state=3)}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}cleanup(){this.panner&&this.gainNode&&(this.source.disconnect(this.panner),this.panner.disconnect(),this.gainNode.disconnect()),this.eventEmitter.removeAllListeners()}recreateSource(){if(!this.panner)throw new Error("Cannot recreate source of a synth that has been cleaned up");this.source.disconnect(),this.source=this.context.createOscillator(),this.source.connect(this.panner)}}class G extends v(y){constructor(e,t,s=f.Oscillator,o="HRTF",g={},i){super(),this.context=e,this.globalGainNode=t,this.soundType=s,this.panType=o,this.cacophony=i,this.context=e,this._oscillatorOptions=g}_oscillatorOptions;playbacks=[];eventEmitter=new b;on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}clone(e={}){const t=e.panType||this.panType,s=e.stereoPan!==void 0?e.stereoPan:this.stereoPan??0,o=e.threeDOptions||this.threeDOptions,g=e.volume!==void 0?e.volume:this.volume,i=e.position?.length?e.position:this.position,a=e.filters?.length?e.filters:this._filters,n=e.oscillatorOptions||this._oscillatorOptions,I=new G(this.context,this.globalGainNode,this.soundType,t,n,this.cacophony);return I._volume=g,I._position=i,I._stereoPan=s,I._threeDOptions=o,I.addFilters(a),I}preplay(){const e=this.context.createOscillator();return this.createPlayback(e)}createPlayback(e){this.oscillatorOptions.detune!==void 0&&(e.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(e.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(e.type=this.oscillatorOptions.type);const t=this.context.createGain();t.connect(this.globalGainNode);const s=new T(this,e,t);return s.volume=this.volume,this._filters.forEach(o=>{const g=this.context.createBiquadFilter();g.type=o.type,g.frequency.value=o.frequency.value,g.Q.value=o.Q.value,g.gain.value=o.gain.value,s.addFilter(g)}),this.panType==="HRTF"?(s.threeDOptions=this.threeDOptions,s.position=this.position):this.panType==="stereo"&&(s.stereoPan=this.stereoPan),this.playbacks.push(s),[s]}play(){const e=super.play();return this.emit("play",e[0]),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()}),e}stop(){super.stop(),this.emit("stop",void 0),this.cacophony?.emit("globalStop",{source:this,timestamp:Date.now()})}pause(){super.pause(),this.emit("pause",void 0),this.cacophony?.emit("globalPause",{source:this,timestamp:Date.now()})}resume(){this.playbacks.forEach(e=>e.play()),this.emit("resume",void 0),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()})}get volume(){return super.volume}set volume(e){super.volume=e,this.emit("volumeChange",e)}get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(e){this._oscillatorOptions=e,this.playbacks.forEach(t=>{t.source&&(this.oscillatorOptions.detune!==void 0&&(t.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(t.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(t.source.type=this.oscillatorOptions.type))})}get frequency(){return this.oscillatorOptions.frequency??440}set frequency(e){this._oscillatorOptions.frequency=e,this.playbacks.forEach(t=>t.frequency=e),this.emit("frequencyChange",e)}get detune(){return this.oscillatorOptions.detune}set detune(e){this._oscillatorOptions.detune=e,this.playbacks.forEach(t=>t.detune=e),this.emit("detuneChange",e)}get type(){return this.oscillatorOptions.type||"sine"}set type(e){this._oscillatorOptions.type=e,this.playbacks.forEach(t=>t.type=e),this.emit("typeChange",e)}}var f=(c=>(c.HTML="HTML",c.Streaming="Streaming",c.Buffer="Buffer",c.Oscillator="oscillator",c))(f||{});class X{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;eventEmitter=new b;cache;createAudioWorkletNode;constructor(e,t,s={}){this.context=e||new AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.cache=t||new C,this.createAudioWorkletNode=s.createAudioWorkletNode||((o,g)=>new AudioWorkletNode(o,g)),this.finalizationRegistry=new FinalizationRegistry(o=>{for(const g of o.sources)g.disconnect();for(const g of o.gainNodes)g.disconnect();for(const g of o.mediaElements)g.pause(),g.removeAttribute("src"),g.load()})}registerSoundForCleanup(e,t,s){this.finalizationRegistry.register(e,t,s)}unregisterSoundCleanup(e){this.finalizationRegistry.unregister(e)}static createOffline(e,t){const s=e.context||new OfflineAudioContext(e.numberOfChannels,e.length,e.sampleRate);return new X(s,t)}get isOffline(){return typeof this.context.startRendering=="function"}async startRendering(){if(typeof this.context.startRendering!="function")throw new Error("startRendering() is only available on offline audio contexts. Use Cacophony.createOffline() to create one.");return this.context.startRendering()}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}async loadWorklets(e){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",N,e):console.warn("AudioWorklet not supported")}async createWorkletNode(e,t,s){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return this.createAudioWorkletNode(this.context,e)}catch(o){console.error(o),console.log("Loading worklet from url",t);try{await this.context.audioWorklet.addModule(t,{credentials:"same-origin",...s&&{signal:s}})}catch(g){throw console.error(g),g}return this.createAudioWorkletNode(this.context,e)}}createAbortError(){return new DOMException("Operation was aborted","AbortError")}createMediaSound(e,t,s,o){return o?.aborted?Promise.reject(this.createAbortError()):new Promise((g,i)=>{const a=new Audio;let n=!1;const I=()=>{a.removeEventListener("loadedmetadata",A),a.removeEventListener("error",u),o?.removeEventListener("abort",p)},r=()=>{a.pause(),a.src="",a.load()},l=d=>{n||(n=!0,I(),d())},A=()=>{l(()=>{g(new m(e,void 0,this.context,this.globalGainNode,t,s,this))})},u=()=>{const d=new Error(`Failed to load audio from ${e}`);l(()=>{r(),i(d)})},p=()=>{const d=this.createAbortError();l(()=>{r(),i(d)})};a.crossOrigin="anonymous",a.preload="auto",a.addEventListener("loadedmetadata",A),a.addEventListener("error",u),o?.addEventListener("abort",p,{once:!0}),a.src=e,a.load()})}clearMemoryCache(){this.cache.clearMemoryCache()}createOscillator(e,t="HRTF"){return new G(this.context,this.globalGainNode,"oscillator",t,e,this)}async createSound(e,t="Buffer",s="HRTF",o){if(typeof e=="object")return Promise.resolve(new m("",e,this.context,this.globalGainNode,"Buffer",s,this));const g=e;return t==="HTML"?this.createMediaSound(g,"HTML",s,o):t==="Streaming"?this.createMediaSound(g,"Streaming",s,o):this.cache.getAudioBuffer(this.context,g,o,{onLoadingStart:i=>this.emitAsync("loadingStart",i),onLoadingProgress:i=>this.emitAsync("loadingProgress",i),onLoadingComplete:i=>this.emitAsync("loadingComplete",i),onLoadingError:i=>this.emitAsync("loadingError",i),onCacheHit:i=>this.emitAsync("cacheHit",i),onCacheMiss:i=>this.emitAsync("cacheMiss",i),onCacheError:i=>this.emitAsync("cacheError",i)}).then(i=>new m(g,i,this.context,this.globalGainNode,t,s,this))}async createGroup(e){const t=new S;return e.forEach(s=>t.addSound(s)),t}async createGroupFromUrls(e,t="Buffer",s="HRTF",o){const g=new S;return(await Promise.all(e.map(a=>this.createSound(a,t,s,o)))).forEach(a=>g.addSound(a)),g}async createStream(e,t){return this.createMediaSound(e,"Streaming","HRTF",t)}createBiquadFilter=({type:e,frequency:t,gain:s,Q:o})=>{t===void 0&&(t=350);const g=this.context.createBiquadFilter();return g.type=e||"lowpass",g.frequency.value=t,g.gain.value=s||0,g.Q.value=o||1,g};createPanner({coneInnerAngle:e,coneOuterAngle:t,coneOuterGain:s,distanceModel:o,maxDistance:g,channelCount:i,channelCountMode:a,channelInterpretation:n,panningModel:I,refDistance:r,rolloffFactor:l,positionX:A,positionY:u,positionZ:p,orientationX:d,orientationY:B,orientationZ:H}){const h=this.context.createPanner();return h.coneInnerAngle=e||360,h.coneOuterAngle=t||360,h.coneOuterGain=s||0,h.distanceModel=o||"inverse",h.maxDistance=g||1e4,h.channelCount=i||2,h.channelCountMode=a||"clamped-max",h.channelInterpretation=n||"speakers",h.panningModel=I||"HRTF",h.refDistance=r||1,h.rolloffFactor=l||1,h.positionX.value=A||0,h.positionY.value=u||0,h.positionZ.value=p||0,h.orientationX.value=d||0,h.orientationY.value=B||0,h.orientationZ.value=H||0,h}pause(){this.context.suspend&&(this.context.suspend(),this.emit("suspend",void 0))}resume(){this.context.resume&&(this.context.resume(),this.emit("resume",void 0))}setGlobalVolume(e){this.globalGainNode.gain.value!==e&&(this.globalGainNode.gain.value=e,this.emit("volumeChange",e))}get volume(){return this.globalGainNode.gain.value}set volume(e){if(this.muted){this.prevVolume=e;return}this.setGlobalVolume(e)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0),this.emit("mute",void 0))}unmute(){this.muted&&(this.setGlobalVolume(this.prevVolume),this.emit("unmute",void 0))}get muted(){return this.globalGainNode.gain.value===0}set muted(e){e!==this.muted&&(e?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((e,t)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(s=>{const o=new Y(this.context,s);e(o)}).catch(s=>{t(s)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(e){const{forward:t,up:s}=e,[o,g,i]=t,[a,n,I]=s;this.listener.forwardX.value=o,this.listener.forwardY.value=g,this.listener.forwardZ.value=i,this.listener.upX.value=a,this.listener.upY.value=n,this.listener.upZ.value=I}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(e){const[t,s,o]=e;this.listener.upX.value=t,this.listener.upY.value=s,this.listener.upZ.value=o}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(e){const[t,s,o]=e;this.listener.forwardX.value=t,this.listener.forwardY.value=s,this.listener.forwardZ.value=o}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(e){const[t,s,o]=e,g=this.context.currentTime;this.listener.positionX.setValueAtTime(t,g),this.listener.positionY.setValueAtTime(s,g),this.listener.positionZ.setValueAtTime(o,g)}}class O{constructor(e=[]){this.synths=e}addSynth(e){this.synths.push(e)}removeSynth(e){const t=this.synths.indexOf(e);if(t!==-1)this.synths.splice(t,1);else throw new Error("Synth not found in group")}play(){return this.synths.flatMap(e=>e.play())}stop(){this.synths.forEach(e=>e.stop())}pause(){this.synths.forEach(e=>e.pause())}resume(){this.synths.forEach(e=>e.resume())}get isPlaying(){return this.synths.some(e=>e.isPlaying)}addFilter(e){this.synths.forEach(t=>t.addFilter(e))}removeFilter(e){this.synths.forEach(t=>t.removeFilter(e))}fadeTo(e,t,s){return Promise.all(this.synths.map(o=>o.fadeTo(e,t,s))).then(()=>{})}fadeIn(e,t){return Promise.all(this.synths.map(s=>s.fadeIn(e,t))).then(()=>{})}fadeOut(e,t){return Promise.all(this.synths.map(s=>s.fadeOut(e,t))).then(()=>{})}stopWithFade(e,t){return Promise.all(this.synths.map(s=>s.stopWithFade(e,t))).then(()=>{})}get volume(){return this.synths.length===0?1:this.synths.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.synths.length}set volume(e){this.synths.forEach(t=>t.volume=e)}get stereoPan(){return this.synths.length===0?null:this.synths[0].stereoPan}set stereoPan(e){this.synths.forEach(t=>t.stereoPan=e)}get position(){return this.synths.length===0?[0,0,0]:this.synths[0].position}set position(e){this.synths.forEach(t=>t.position=e)}get frequency(){return this.synths.length===0?440:this.synths[0].frequency}set frequency(e){this.synths.forEach(t=>t.frequency=e)}get detune(){return this.synths[0]?.detune}set detune(e){this.synths.forEach(t=>t.detune=e)}get type(){return this.synths.length===0?"sine":this.synths[0].type}set type(e){this.synths.forEach(t=>t.type=e)}}exports.AudioCache=C;exports.Cacophony=X;exports.Group=S;exports.MicrophonePlayback=w;exports.Playback=Z;exports.Sound=m;exports.SoundType=f;exports.Synth=G;exports.SynthGroup=O;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class R{maxSize;cache;constructor(e){this.maxSize=e,this.cache=new Map}get(e){if(!this.cache.has(e))return;const t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}this.cache.set(e,t)}has(e){return this.cache.has(e)}}const V=100;function N(c){if(!c)return null;const e=c.match(/max-age\s*=\s*"?(\d+)"?/i);return e?parseInt(e[1],10):null}function E(c){return c?/(?:^|,)\s*(no-cache|no-store|must-revalidate)\s*(?:,|$)/i.test(c):!1}function k(c){return c instanceof DOMException&&c.name==="AbortError"?"abort":c instanceof Error?"network":"unknown"}class C{static pendingRequests=new Map;static pendingCallbacks=new Map;static decodedBuffers=new R(V);static cacheExpirationTime=1440*60*1e3;static setCacheExpirationTime(e){C.cacheExpirationTime=e}static async openCache(){try{return await caches.open("audio-cache")}catch(e){throw console.error("Failed to open cache:",e),e}}static callAllCallbacks(e,t,s){const g=C.pendingCallbacks.get(e);g&&g.forEach(o=>{const i=o[t];if(i)try{i(s)}catch(a){console.error(`Error in ${t} callback:`,a)}})}static async getOrCreatePendingRequest(e,t,s,g){if(s?.aborted)throw new DOMException("Operation was aborted","AbortError");if(g){const i=C.pendingCallbacks.get(e)||[];i.push(g),C.pendingCallbacks.set(e,i)}const o=C.pendingRequests.get(e);if(!o){const i=(async()=>{try{const a=await t();if(a===void 0)throw new Error("Failed to create audio buffer.");return a}finally{C.pendingRequests.delete(e),C.pendingCallbacks.delete(e)}})();return s?.addEventListener("abort",()=>{s.aborted&&(C.pendingRequests.delete(e),C.pendingCallbacks.delete(e))},{once:!0}),C.pendingRequests.set(e,i),i}return o}static async updateMetadata(e,t,s){const g={url:t,timestamp:Date.now(),...s};await e.put(`${t}:meta`,new Response(JSON.stringify(g),{headers:{"Content-Type":"application/json"}}))}static async getBufferFromCache(e,t){try{const s=await t.match(e);return s?.ok?await s.arrayBuffer():null}catch(s){return console.error("Failed to get data from cache:",s),null}}static async fetchAndCacheBuffer(e,t,s,g,o,i){const a=new Headers;s&&a.append("If-None-Match",s),g&&a.append("If-Modified-Since",g),console.debug(`[AudioCache] Fetching ${e}`,{headers:Object.fromEntries(a.entries()),hasEtag:!!s,hasLastModified:!!g});const n=await fetch(e,{headers:a,signal:o});if(console.debug(`[AudioCache] Response ${e}`,{status:n.status,statusText:n.statusText,etag:n.headers?.get("ETag"),lastModified:n.headers?.get("Last-Modified"),cacheControl:n.headers?.get("Cache-Control")}),n.status===304){const I=await t.match(e);if(I){i?.onCacheHit&&i.onCacheHit({url:e,cacheType:"conditional",timestamp:Date.now()});const r=Date.now(),l=n.headers?.get("Cache-Control");return await C.updateMetadata(t,e,{timestamp:r,etag:s,lastModified:g,...l?{cacheControl:l}:{}}),await I.arrayBuffer()}else{console.warn(`Cache inconsistency detected for ${e}: 304 response but no cached body. Re-fetching.`);const r=await fetch(e,{signal:o});if(r.status===200){const l=r.clone(),A=r.headers.get("ETag"),u=r.headers.get("Last-Modified"),p=r.headers.get("Cache-Control");try{await Promise.all([t.put(e,l),C.updateMetadata(t,e,{timestamp:Date.now(),etag:A||void 0,lastModified:u||void 0,cacheControl:p||void 0})])}catch(d){throw await t.delete(e),await t.delete(`${e}:meta`),d}if(r.body){const{stream:d,total:f}=C.createProgressTrackingStream(r,e);return await C.collectStreamToArrayBuffer(d,f||void 0)}else return await r.arrayBuffer()}else throw new Error(`Failed to fetch resource after cache inconsistency: ${r.status} ${r.statusText}`)}}if(n.status===200){const I=n.clone(),r=n.headers.get("ETag"),l=n.headers.get("Last-Modified"),A=n.headers.get("Cache-Control");try{await Promise.all([t.put(e,I),C.updateMetadata(t,e,{timestamp:Date.now(),etag:r||void 0,lastModified:l||void 0,cacheControl:A||void 0})])}catch(u){throw await t.delete(e),await t.delete(`${e}:meta`),u}}if(o?.aborted)throw new DOMException("Operation was aborted","AbortError");if(n.body){const{stream:I,total:r}=C.createProgressTrackingStream(n,e);return await C.collectStreamToArrayBuffer(I,r||void 0)}else return await n.arrayBuffer()}static createProgressTrackingStream(e,t){const s=e.headers.get("content-length"),g=s?parseInt(s,10):null;let o=0;if(!e.body)throw new Error("Response body is null");const i=e.body.getReader();return{stream:new ReadableStream({start(n){function I(){return i.read().then(({done:r,value:l})=>{if(r){C.callAllCallbacks(t,"onLoadingProgress",{url:t,loaded:o,total:g,progress:g?1:-1,timestamp:Date.now()}),n.close();return}if(l){o+=l.byteLength;const A=g?o/g:-1;C.callAllCallbacks(t,"onLoadingProgress",{url:t,loaded:o,total:g,progress:A,timestamp:Date.now()}),n.enqueue(l)}return I()}).catch(r=>{n.error(r)})}return I()},cancel(n){return i.cancel(n)}}),total:g}}static async collectStreamToArrayBuffer(e,t){const s=e.getReader();try{if(t!==void 0&&t>0){const g=new ArrayBuffer(t),o=new Uint8Array(g);let i=0;for(;;){const{done:a,value:n}=await s.read();if(a)break;n&&(o.set(n,i),i+=n.byteLength)}return g}else{let g=new Uint8Array(8192),o=0;for(;;){const{done:i,value:a}=await s.read();if(i)break;if(a){if(o+a.byteLength>g.length){const n=Math.max(g.length*2,o+a.byteLength),I=new Uint8Array(n);I.set(g.subarray(0,o)),g=I}g.set(a,o),o+=a.byteLength}}return g.slice(0,o).buffer}}finally{s.releaseLock()}}static async decodeAudioData(e,t){try{return await e.decodeAudioData(t)}catch(s){throw console.error("Failed to decode audio data:",s),s}}static async getMetadataFromCache(e,t){try{const s=await t.match(`${e}:meta`);return s?.ok?await s.json():null}catch(s){return console.error("Failed to get metadata from cache:",s),null}}async getAudioBuffer(e,t,s,g){if(g?.onLoadingStart&&g.onLoadingStart({url:t,timestamp:Date.now()}),C.decodedBuffers.has(t))return g?.onCacheHit&&g.onCacheHit({url:t,cacheType:"memory",timestamp:Date.now()}),C.decodedBuffers.get(t);if(t.startsWith("data:")){const n=t.split(",")[1],I=Uint8Array.from(atob(n),l=>l.charCodeAt(0)).buffer,r=await C.decodeAudioData(e,I);return C.decodedBuffers.set(t,r),r}const o=await C.openCache(),i=await C.getMetadataFromCache(t,o),a=(()=>{if(!i||E(i.cacheControl))return!0;const n=N(i.cacheControl);if(n!==null){const I=(Date.now()-i.timestamp)/1e3;if(n>0&&I<n)return!1}return i.etag||i.lastModified?!0:Date.now()-i.timestamp>C.cacheExpirationTime})();return C.getOrCreatePendingRequest(t,async()=>{if(a){g?.onCacheMiss&&g.onCacheMiss({url:t,reason:i?"expired":"not-found",timestamp:Date.now()});try{const n=await C.fetchAndCacheBuffer(t,o,i?.etag,i?.lastModified,s,{onCacheHit:g?.onCacheHit});let I;try{I=await C.decodeAudioData(e,n)}catch(r){throw g?.onLoadingError&&g.onLoadingError({url:t,error:r,errorType:"decode",timestamp:Date.now()}),r}return g?.onLoadingComplete&&g.onLoadingComplete({url:t,duration:I.duration,size:n.byteLength,timestamp:Date.now()}),C.decodedBuffers.set(t,I),I}catch(n){throw g?.onLoadingError&&g.onLoadingError({url:t,error:n,errorType:k(n),timestamp:Date.now()}),g?.onCacheError&&g.onCacheError({url:t,error:n,operation:"get",timestamp:Date.now()}),n}}else{const n=await C.getBufferFromCache(t,o);if(n){g?.onCacheHit&&g.onCacheHit({url:t,cacheType:"browser",timestamp:Date.now()});const I=await C.decodeAudioData(e,n);return C.decodedBuffers.set(t,I),I}else{g?.onCacheError&&g.onCacheError({url:t,error:new Error("Cache inconsistency: metadata exists but body is missing"),operation:"get",timestamp:Date.now()});try{const I=await C.fetchAndCacheBuffer(t,o,i?.etag,i?.lastModified,s,{onCacheHit:g?.onCacheHit});let r;try{r=await C.decodeAudioData(e,I)}catch(l){throw g?.onLoadingError&&g.onLoadingError({url:t,error:l,errorType:"decode",timestamp:Date.now()}),l}return g?.onLoadingComplete&&g.onLoadingComplete({url:t,duration:r.duration,size:I.byteLength,timestamp:Date.now()}),C.decodedBuffers.set(t,r),r}catch(I){throw g?.onLoadingError&&g.onLoadingError({url:t,error:I,errorType:k(I),timestamp:Date.now()}),I}}}},s,{onLoadingProgress:g?.onLoadingProgress})}clearMemoryCache(){C.decodedBuffers=new R(V),C.pendingRequests.clear()}}const Y="data:text/javascript;base64,dmFyIHBoYXNlVm9jb2RlciA9IChmdW5jdGlvbiAoZXhwb3J0cykgewoJJ3VzZSBzdHJpY3QnOwoKCWZ1bmN0aW9uIGdldERlZmF1bHRFeHBvcnRGcm9tQ2pzICh4KSB7CgkJcmV0dXJuIHggJiYgeC5fX2VzTW9kdWxlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnZGVmYXVsdCcpID8geFsnZGVmYXVsdCddIDogeDsKCX0KCglmdW5jdGlvbiBGRlQoc2l6ZSkgewoJICB0aGlzLnNpemUgPSBzaXplIHwgMDsKCSAgaWYgKHRoaXMuc2l6ZSA8PSAxIHx8ICh0aGlzLnNpemUgJiAodGhpcy5zaXplIC0gMSkpICE9PSAwKQoJICAgIHRocm93IG5ldyBFcnJvcignRkZUIHNpemUgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBhbmQgYmlnZ2VyIHRoYW4gMScpOwoKCSAgdGhpcy5fY3NpemUgPSBzaXplIDw8IDE7CgoJICAvLyBOT1RFOiBVc2Ugb2YgYHZhcmAgaXMgaW50ZW50aW9uYWwgZm9yIG9sZCBWOCB2ZXJzaW9ucwoJICB2YXIgdGFibGUgPSBuZXcgQXJyYXkodGhpcy5zaXplICogMik7CgkgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFibGUubGVuZ3RoOyBpICs9IDIpIHsKCSAgICBjb25zdCBhbmdsZSA9IE1hdGguUEkgKiBpIC8gdGhpcy5zaXplOwoJICAgIHRhYmxlW2ldID0gTWF0aC5jb3MoYW5nbGUpOwoJICAgIHRhYmxlW2kgKyAxXSA9IC1NYXRoLnNpbihhbmdsZSk7CgkgIH0KCSAgdGhpcy50YWJsZSA9IHRhYmxlOwoKCSAgLy8gRmluZCBzaXplJ3MgcG93ZXIgb2YgdHdvCgkgIHZhciBwb3dlciA9IDA7CgkgIGZvciAodmFyIHQgPSAxOyB0aGlzLnNpemUgPiB0OyB0IDw8PSAxKQoJICAgIHBvd2VyKys7CgoJICAvLyBDYWxjdWxhdGUgaW5pdGlhbCBzdGVwJ3Mgd2lkdGg6CgkgIC8vICAgKiBJZiB3ZSBhcmUgZnVsbCByYWRpeC00IC0gaXQgaXMgMnggc21hbGxlciB0byBnaXZlIGluaXRhbCBsZW49OAoJICAvLyAgICogT3RoZXJ3aXNlIGl0IGlzIHRoZSBzYW1lIGFzIGBwb3dlcmAgdG8gZ2l2ZSBsZW49NAoJICB0aGlzLl93aWR0aCA9IHBvd2VyICUgMiA9PT0gMCA/IHBvd2VyIC0gMSA6IHBvd2VyOwoKCSAgLy8gUHJlLWNvbXB1dGUgYml0LXJldmVyc2FsIHBhdHRlcm5zCgkgIHRoaXMuX2JpdHJldiA9IG5ldyBBcnJheSgxIDw8IHRoaXMuX3dpZHRoKTsKCSAgZm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLl9iaXRyZXYubGVuZ3RoOyBqKyspIHsKCSAgICB0aGlzLl9iaXRyZXZbal0gPSAwOwoJICAgIGZvciAodmFyIHNoaWZ0ID0gMDsgc2hpZnQgPCB0aGlzLl93aWR0aDsgc2hpZnQgKz0gMikgewoJICAgICAgdmFyIHJldlNoaWZ0ID0gdGhpcy5fd2lkdGggLSBzaGlmdCAtIDI7CgkgICAgICB0aGlzLl9iaXRyZXZbal0gfD0gKChqID4+PiBzaGlmdCkgJiAzKSA8PCByZXZTaGlmdDsKCSAgICB9CgkgIH0KCgkgIHRoaXMuX291dCA9IG51bGw7CgkgIHRoaXMuX2RhdGEgPSBudWxsOwoJICB0aGlzLl9pbnYgPSAwOwoJfQoJdmFyIGZmdCA9IEZGVDsKCglGRlQucHJvdG90eXBlLmZyb21Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiBmcm9tQ29tcGxleEFycmF5KGNvbXBsZXgsIHN0b3JhZ2UpIHsKCSAgdmFyIHJlcyA9IHN0b3JhZ2UgfHwgbmV3IEFycmF5KGNvbXBsZXgubGVuZ3RoID4+PiAxKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb21wbGV4Lmxlbmd0aDsgaSArPSAyKQoJICAgIHJlc1tpID4+PiAxXSA9IGNvbXBsZXhbaV07CgkgIHJldHVybiByZXM7Cgl9OwoKCUZGVC5wcm90b3R5cGUuY3JlYXRlQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gY3JlYXRlQ29tcGxleEFycmF5KCkgewoJICBjb25zdCByZXMgPSBuZXcgQXJyYXkodGhpcy5fY3NpemUpOwoJICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkrKykKCSAgICByZXNbaV0gPSAwOwoJICByZXR1cm4gcmVzOwoJfTsKCglGRlQucHJvdG90eXBlLnRvQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gdG9Db21wbGV4QXJyYXkoaW5wdXQsIHN0b3JhZ2UpIHsKCSAgdmFyIHJlcyA9IHN0b3JhZ2UgfHwgdGhpcy5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpICs9IDIpIHsKCSAgICByZXNbaV0gPSBpbnB1dFtpID4+PiAxXTsKCSAgICByZXNbaSArIDFdID0gMDsKCSAgfQoJICByZXR1cm4gcmVzOwoJfTsKCglGRlQucHJvdG90eXBlLmNvbXBsZXRlU3BlY3RydW0gPSBmdW5jdGlvbiBjb21wbGV0ZVNwZWN0cnVtKHNwZWN0cnVtKSB7CgkgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgkgIHZhciBoYWxmID0gc2l6ZSA+Pj4gMTsKCSAgZm9yICh2YXIgaSA9IDI7IGkgPCBoYWxmOyBpICs9IDIpIHsKCSAgICBzcGVjdHJ1bVtzaXplIC0gaV0gPSBzcGVjdHJ1bVtpXTsKCSAgICBzcGVjdHJ1bVtzaXplIC0gaSArIDFdID0gLXNwZWN0cnVtW2kgKyAxXTsKCSAgfQoJfTsKCglGRlQucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uIHRyYW5zZm9ybShvdXQsIGRhdGEpIHsKCSAgaWYgKG91dCA9PT0gZGF0YSkKCSAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKCSAgdGhpcy5fb3V0ID0gb3V0OwoJICB0aGlzLl9kYXRhID0gZGF0YTsKCSAgdGhpcy5faW52ID0gMDsKCSAgdGhpcy5fdHJhbnNmb3JtNCgpOwoJICB0aGlzLl9vdXQgPSBudWxsOwoJICB0aGlzLl9kYXRhID0gbnVsbDsKCX07CgoJRkZULnByb3RvdHlwZS5yZWFsVHJhbnNmb3JtID0gZnVuY3Rpb24gcmVhbFRyYW5zZm9ybShvdXQsIGRhdGEpIHsKCSAgaWYgKG91dCA9PT0gZGF0YSkKCSAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKCSAgdGhpcy5fb3V0ID0gb3V0OwoJICB0aGlzLl9kYXRhID0gZGF0YTsKCSAgdGhpcy5faW52ID0gMDsKCSAgdGhpcy5fcmVhbFRyYW5zZm9ybTQoKTsKCSAgdGhpcy5fb3V0ID0gbnVsbDsKCSAgdGhpcy5fZGF0YSA9IG51bGw7Cgl9OwoKCUZGVC5wcm90b3R5cGUuaW52ZXJzZVRyYW5zZm9ybSA9IGZ1bmN0aW9uIGludmVyc2VUcmFuc2Zvcm0ob3V0LCBkYXRhKSB7CgkgIGlmIChvdXQgPT09IGRhdGEpCgkgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgbXVzdCBiZSBkaWZmZXJlbnQnKTsKCgkgIHRoaXMuX291dCA9IG91dDsKCSAgdGhpcy5fZGF0YSA9IGRhdGE7CgkgIHRoaXMuX2ludiA9IDE7CgkgIHRoaXMuX3RyYW5zZm9ybTQoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXQubGVuZ3RoOyBpKyspCgkgICAgb3V0W2ldIC89IHRoaXMuc2l6ZTsKCSAgdGhpcy5fb3V0ID0gbnVsbDsKCSAgdGhpcy5fZGF0YSA9IG51bGw7Cgl9OwoKCS8vIHJhZGl4LTQgaW1wbGVtZW50YXRpb24KCS8vCgkvLyBOT1RFOiBVc2VzIG9mIGB2YXJgIGFyZSBpbnRlbnRpb25hbCBmb3Igb2xkZXIgVjggdmVyc2lvbiB0aGF0IGRvIG5vdAoJLy8gc3VwcG9ydCBib3RoIGBsZXQgY29tcG91bmQgYXNzaWdubWVudHNgIGFuZCBgY29uc3QgcGhpYAoJRkZULnByb3RvdHlwZS5fdHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF90cmFuc2Zvcm00KCkgewoJICB2YXIgb3V0ID0gdGhpcy5fb3V0OwoJICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKCSAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCgkgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwoJICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CgkgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgoJICB2YXIgb3V0T2ZmOwoJICB2YXIgdDsKCSAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKCSAgaWYgKGxlbiA9PT0gNCkgewoJICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewoJICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwoJICAgICAgdGhpcy5fc2luZ2xlVHJhbnNmb3JtMihvdXRPZmYsIG9mZiwgc3RlcCk7CgkgICAgfQoJICB9IGVsc2UgewoJICAgIC8vIGxlbiA9PT0gOAoJICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewoJICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwoJICAgICAgdGhpcy5fc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwgc3RlcCk7CgkgICAgfQoJICB9CgoJICAvLyBMb29wIHRocm91Z2ggc3RlcHMgaW4gZGVjcmVhc2luZyBvcmRlcgoJICB2YXIgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICB2YXIgdGFibGUgPSB0aGlzLnRhYmxlOwoJICBmb3IgKHN0ZXAgPj49IDI7IHN0ZXAgPj0gMjsgc3RlcCA+Pj0gMikgewoJICAgIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCSAgICB2YXIgcXVhcnRlckxlbiA9IGxlbiA+Pj4gMjsKCgkgICAgLy8gTG9vcCB0aHJvdWdoIG9mZnNldHMgaW4gdGhlIGRhdGEKCSAgICBmb3IgKG91dE9mZiA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4pIHsKCSAgICAgIC8vIEZ1bGwgY2FzZQoJICAgICAgdmFyIGxpbWl0ID0gb3V0T2ZmICsgcXVhcnRlckxlbjsKCSAgICAgIGZvciAodmFyIGkgPSBvdXRPZmYsIGsgPSAwOyBpIDwgbGltaXQ7IGkgKz0gMiwgayArPSBzdGVwKSB7CgkgICAgICAgIGNvbnN0IEEgPSBpOwoJICAgICAgICBjb25zdCBCID0gQSArIHF1YXJ0ZXJMZW47CgkgICAgICAgIGNvbnN0IEMgPSBCICsgcXVhcnRlckxlbjsKCSAgICAgICAgY29uc3QgRCA9IEMgKyBxdWFydGVyTGVuOwoKCSAgICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgICAgICAgIGNvbnN0IEFyID0gb3V0W0FdOwoJICAgICAgICBjb25zdCBBaSA9IG91dFtBICsgMV07CgkgICAgICAgIGNvbnN0IEJyID0gb3V0W0JdOwoJICAgICAgICBjb25zdCBCaSA9IG91dFtCICsgMV07CgkgICAgICAgIGNvbnN0IENyID0gb3V0W0NdOwoJICAgICAgICBjb25zdCBDaSA9IG91dFtDICsgMV07CgkgICAgICAgIGNvbnN0IERyID0gb3V0W0RdOwoJICAgICAgICBjb25zdCBEaSA9IG91dFtEICsgMV07CgoJICAgICAgICAvLyBNaWRkbGUgdmFsdWVzCgkgICAgICAgIGNvbnN0IE1BciA9IEFyOwoJICAgICAgICBjb25zdCBNQWkgPSBBaTsKCgkgICAgICAgIGNvbnN0IHRhYmxlQnIgPSB0YWJsZVtrXTsKCSAgICAgICAgY29uc3QgdGFibGVCaSA9IGludiAqIHRhYmxlW2sgKyAxXTsKCSAgICAgICAgY29uc3QgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwoJICAgICAgICBjb25zdCBNQmkgPSBCciAqIHRhYmxlQmkgKyBCaSAqIHRhYmxlQnI7CgoJICAgICAgICBjb25zdCB0YWJsZUNyID0gdGFibGVbMiAqIGtdOwoJICAgICAgICBjb25zdCB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKCSAgICAgICAgY29uc3QgTUNyID0gQ3IgKiB0YWJsZUNyIC0gQ2kgKiB0YWJsZUNpOwoJICAgICAgICBjb25zdCBNQ2kgPSBDciAqIHRhYmxlQ2kgKyBDaSAqIHRhYmxlQ3I7CgoJICAgICAgICBjb25zdCB0YWJsZURyID0gdGFibGVbMyAqIGtdOwoJICAgICAgICBjb25zdCB0YWJsZURpID0gaW52ICogdGFibGVbMyAqIGsgKyAxXTsKCSAgICAgICAgY29uc3QgTURyID0gRHIgKiB0YWJsZURyIC0gRGkgKiB0YWJsZURpOwoJICAgICAgICBjb25zdCBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgoJICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgICAgICAgIGNvbnN0IFQwciA9IE1BciArIE1DcjsKCSAgICAgICAgY29uc3QgVDBpID0gTUFpICsgTUNpOwoJICAgICAgICBjb25zdCBUMXIgPSBNQXIgLSBNQ3I7CgkgICAgICAgIGNvbnN0IFQxaSA9IE1BaSAtIE1DaTsKCSAgICAgICAgY29uc3QgVDJyID0gTUJyICsgTURyOwoJICAgICAgICBjb25zdCBUMmkgPSBNQmkgKyBNRGk7CgkgICAgICAgIGNvbnN0IFQzciA9IGludiAqIChNQnIgLSBNRHIpOwoJICAgICAgICBjb25zdCBUM2kgPSBpbnYgKiAoTUJpIC0gTURpKTsKCgkgICAgICAgIC8vIEZpbmFsIHZhbHVlcwoJICAgICAgICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CgkgICAgICAgIGNvbnN0IEZBaSA9IFQwaSArIFQyaTsKCgkgICAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCSAgICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKCSAgICAgICAgY29uc3QgRkJyID0gVDFyICsgVDNpOwoJICAgICAgICBjb25zdCBGQmkgPSBUMWkgLSBUM3I7CgoJICAgICAgICBjb25zdCBGRHIgPSBUMXIgLSBUM2k7CgkgICAgICAgIGNvbnN0IEZEaSA9IFQxaSArIFQzcjsKCgkgICAgICAgIG91dFtBXSA9IEZBcjsKCSAgICAgICAgb3V0W0EgKyAxXSA9IEZBaTsKCSAgICAgICAgb3V0W0JdID0gRkJyOwoJICAgICAgICBvdXRbQiArIDFdID0gRkJpOwoJICAgICAgICBvdXRbQ10gPSBGQ3I7CgkgICAgICAgIG91dFtDICsgMV0gPSBGQ2k7CgkgICAgICAgIG91dFtEXSA9IEZEcjsKCSAgICAgICAgb3V0W0QgKyAxXSA9IEZEaTsKCSAgICAgIH0KCSAgICB9CgkgIH0KCX07CgoJLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgoJLy8KCS8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAoJRkZULnByb3RvdHlwZS5fc2luZ2xlVHJhbnNmb3JtMiA9IGZ1bmN0aW9uIF9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCgkgIGNvbnN0IGV2ZW5SID0gZGF0YVtvZmZdOwoJICBjb25zdCBldmVuSSA9IGRhdGFbb2ZmICsgMV07CgkgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoJICBjb25zdCBvZGRJID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CgoJICBjb25zdCBsZWZ0UiA9IGV2ZW5SICsgb2RkUjsKCSAgY29uc3QgbGVmdEkgPSBldmVuSSArIG9kZEk7CgkgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCSAgY29uc3QgcmlnaHRJID0gZXZlbkkgLSBvZGRJOwoKCSAgb3V0W291dE9mZl0gPSBsZWZ0UjsKCSAgb3V0W291dE9mZiArIDFdID0gbGVmdEk7CgkgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKCSAgb3V0W291dE9mZiArIDNdID0gcmlnaHRJOwoJfTsKCgkvLyByYWRpeC00CgkvLwoJLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj04CglGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTQob3V0T2ZmLCBvZmYsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewoJICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CgkgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoJICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CgkgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CgkgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgoJICAvLyBPcmlnaW5hbCB2YWx1ZXMKCSAgY29uc3QgQXIgPSBkYXRhW29mZl07CgkgIGNvbnN0IEFpID0gZGF0YVtvZmYgKyAxXTsKCSAgY29uc3QgQnIgPSBkYXRhW29mZiArIHN0ZXBdOwoJICBjb25zdCBCaSA9IGRhdGFbb2ZmICsgc3RlcCArIDFdOwoJICBjb25zdCBDciA9IGRhdGFbb2ZmICsgc3RlcDJdOwoJICBjb25zdCBDaSA9IGRhdGFbb2ZmICsgc3RlcDIgKyAxXTsKCSAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCSAgY29uc3QgRGkgPSBkYXRhW29mZiArIHN0ZXAzICsgMV07CgoJICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgIGNvbnN0IFQwciA9IEFyICsgQ3I7CgkgIGNvbnN0IFQwaSA9IEFpICsgQ2k7CgkgIGNvbnN0IFQxciA9IEFyIC0gQ3I7CgkgIGNvbnN0IFQxaSA9IEFpIC0gQ2k7CgkgIGNvbnN0IFQyciA9IEJyICsgRHI7CgkgIGNvbnN0IFQyaSA9IEJpICsgRGk7CgkgIGNvbnN0IFQzciA9IGludiAqIChCciAtIERyKTsKCSAgY29uc3QgVDNpID0gaW52ICogKEJpIC0gRGkpOwoKCSAgLy8gRmluYWwgdmFsdWVzCgkgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCSAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKCSAgY29uc3QgRkJyID0gVDFyICsgVDNpOwoJICBjb25zdCBGQmkgPSBUMWkgLSBUM3I7CgoJICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CgkgIGNvbnN0IEZDaSA9IFQwaSAtIFQyaTsKCgkgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKCSAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKCSAgb3V0W291dE9mZl0gPSBGQXI7CgkgIG91dFtvdXRPZmYgKyAxXSA9IEZBaTsKCSAgb3V0W291dE9mZiArIDJdID0gRkJyOwoJICBvdXRbb3V0T2ZmICsgM10gPSBGQmk7CgkgIG91dFtvdXRPZmYgKyA0XSA9IEZDcjsKCSAgb3V0W291dE9mZiArIDVdID0gRkNpOwoJICBvdXRbb3V0T2ZmICsgNl0gPSBGRHI7CgkgIG91dFtvdXRPZmYgKyA3XSA9IEZEaTsKCX07CgoJLy8gUmVhbCBpbnB1dCByYWRpeC00IGltcGxlbWVudGF0aW9uCglGRlQucHJvdG90eXBlLl9yZWFsVHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF9yZWFsVHJhbnNmb3JtNCgpIHsKCSAgdmFyIG91dCA9IHRoaXMuX291dDsKCSAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKCgkgIC8vIEluaXRpYWwgc3RlcCAocGVybXV0ZSBhbmQgdHJhbnNmb3JtKQoJICB2YXIgd2lkdGggPSB0aGlzLl93aWR0aDsKCSAgdmFyIHN0ZXAgPSAxIDw8IHdpZHRoOwoJICB2YXIgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwoKCSAgdmFyIG91dE9mZjsKCSAgdmFyIHQ7CgkgIHZhciBiaXRyZXYgPSB0aGlzLl9iaXRyZXY7CgkgIGlmIChsZW4gPT09IDQpIHsKCSAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKCSAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKCSAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKCSAgICB9CgkgIH0gZWxzZSB7CgkgICAgLy8gbGVuID09PSA4CgkgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CgkgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CgkgICAgICB0aGlzLl9zaW5nbGVSZWFsVHJhbnNmb3JtNChvdXRPZmYsIG9mZiA+Pj4gMSwgc3RlcCA+Pj4gMSk7CgkgICAgfQoJICB9CgoJICAvLyBMb29wIHRocm91Z2ggc3RlcHMgaW4gZGVjcmVhc2luZyBvcmRlcgoJICB2YXIgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICB2YXIgdGFibGUgPSB0aGlzLnRhYmxlOwoJICBmb3IgKHN0ZXAgPj49IDI7IHN0ZXAgPj0gMjsgc3RlcCA+Pj0gMikgewoJICAgIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCSAgICB2YXIgaGFsZkxlbiA9IGxlbiA+Pj4gMTsKCSAgICB2YXIgcXVhcnRlckxlbiA9IGhhbGZMZW4gPj4+IDE7CgkgICAgdmFyIGhxdWFydGVyTGVuID0gcXVhcnRlckxlbiA+Pj4gMTsKCgkgICAgLy8gTG9vcCB0aHJvdWdoIG9mZnNldHMgaW4gdGhlIGRhdGEKCSAgICBmb3IgKG91dE9mZiA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4pIHsKCSAgICAgIGZvciAodmFyIGkgPSAwLCBrID0gMDsgaSA8PSBocXVhcnRlckxlbjsgaSArPSAyLCBrICs9IHN0ZXApIHsKCSAgICAgICAgdmFyIEEgPSBvdXRPZmYgKyBpOwoJICAgICAgICB2YXIgQiA9IEEgKyBxdWFydGVyTGVuOwoJICAgICAgICB2YXIgQyA9IEIgKyBxdWFydGVyTGVuOwoJICAgICAgICB2YXIgRCA9IEMgKyBxdWFydGVyTGVuOwoKCSAgICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgICAgICAgIHZhciBBciA9IG91dFtBXTsKCSAgICAgICAgdmFyIEFpID0gb3V0W0EgKyAxXTsKCSAgICAgICAgdmFyIEJyID0gb3V0W0JdOwoJICAgICAgICB2YXIgQmkgPSBvdXRbQiArIDFdOwoJICAgICAgICB2YXIgQ3IgPSBvdXRbQ107CgkgICAgICAgIHZhciBDaSA9IG91dFtDICsgMV07CgkgICAgICAgIHZhciBEciA9IG91dFtEXTsKCSAgICAgICAgdmFyIERpID0gb3V0W0QgKyAxXTsKCgkgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKCSAgICAgICAgdmFyIE1BciA9IEFyOwoJICAgICAgICB2YXIgTUFpID0gQWk7CgoJICAgICAgICB2YXIgdGFibGVCciA9IHRhYmxlW2tdOwoJICAgICAgICB2YXIgdGFibGVCaSA9IGludiAqIHRhYmxlW2sgKyAxXTsKCSAgICAgICAgdmFyIE1CciA9IEJyICogdGFibGVCciAtIEJpICogdGFibGVCaTsKCSAgICAgICAgdmFyIE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCgkgICAgICAgIHZhciB0YWJsZUNyID0gdGFibGVbMiAqIGtdOwoJICAgICAgICB2YXIgdGFibGVDaSA9IGludiAqIHRhYmxlWzIgKiBrICsgMV07CgkgICAgICAgIHZhciBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CgkgICAgICAgIHZhciBNQ2kgPSBDciAqIHRhYmxlQ2kgKyBDaSAqIHRhYmxlQ3I7CgoJICAgICAgICB2YXIgdGFibGVEciA9IHRhYmxlWzMgKiBrXTsKCSAgICAgICAgdmFyIHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwoJICAgICAgICB2YXIgTURyID0gRHIgKiB0YWJsZURyIC0gRGkgKiB0YWJsZURpOwoJICAgICAgICB2YXIgTURpID0gRHIgKiB0YWJsZURpICsgRGkgKiB0YWJsZURyOwoKCSAgICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwoJICAgICAgICB2YXIgVDByID0gTUFyICsgTUNyOwoJICAgICAgICB2YXIgVDBpID0gTUFpICsgTUNpOwoJICAgICAgICB2YXIgVDFyID0gTUFyIC0gTUNyOwoJICAgICAgICB2YXIgVDFpID0gTUFpIC0gTUNpOwoJICAgICAgICB2YXIgVDJyID0gTUJyICsgTURyOwoJICAgICAgICB2YXIgVDJpID0gTUJpICsgTURpOwoJICAgICAgICB2YXIgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CgkgICAgICAgIHZhciBUM2kgPSBpbnYgKiAoTUJpIC0gTURpKTsKCgkgICAgICAgIC8vIEZpbmFsIHZhbHVlcwoJICAgICAgICB2YXIgRkFyID0gVDByICsgVDJyOwoJICAgICAgICB2YXIgRkFpID0gVDBpICsgVDJpOwoKCSAgICAgICAgdmFyIEZCciA9IFQxciArIFQzaTsKCSAgICAgICAgdmFyIEZCaSA9IFQxaSAtIFQzcjsKCgkgICAgICAgIG91dFtBXSA9IEZBcjsKCSAgICAgICAgb3V0W0EgKyAxXSA9IEZBaTsKCSAgICAgICAgb3V0W0JdID0gRkJyOwoJICAgICAgICBvdXRbQiArIDFdID0gRkJpOwoKCSAgICAgICAgLy8gT3V0cHV0IGZpbmFsIG1pZGRsZSBwb2ludAoJICAgICAgICBpZiAoaSA9PT0gMCkgewoJICAgICAgICAgIHZhciBGQ3IgPSBUMHIgLSBUMnI7CgkgICAgICAgICAgdmFyIEZDaSA9IFQwaSAtIFQyaTsKCSAgICAgICAgICBvdXRbQ10gPSBGQ3I7CgkgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKCSAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgfQoKCSAgICAgICAgLy8gRG8gbm90IG92ZXJ3cml0ZSBvdXJzZWx2ZXMKCSAgICAgICAgaWYgKGkgPT09IGhxdWFydGVyTGVuKQoJICAgICAgICAgIGNvbnRpbnVlOwoKCSAgICAgICAgLy8gSW4gdGhlIGZsaXBwZWQgY2FzZToKCSAgICAgICAgLy8gTUFpID0gLU1BaQoJICAgICAgICAvLyBNQnI9LU1CaSwgTUJpPS1NQnIKCSAgICAgICAgLy8gTUNyPS1NQ3IKCSAgICAgICAgLy8gTURyPU1EaSwgTURpPU1EcgoJICAgICAgICB2YXIgU1QwciA9IFQxcjsKCSAgICAgICAgdmFyIFNUMGkgPSAtVDFpOwoJICAgICAgICB2YXIgU1QxciA9IFQwcjsKCSAgICAgICAgdmFyIFNUMWkgPSAtVDBpOwoJICAgICAgICB2YXIgU1QyciA9IC1pbnYgKiBUM2k7CgkgICAgICAgIHZhciBTVDJpID0gLWludiAqIFQzcjsKCSAgICAgICAgdmFyIFNUM3IgPSAtaW52ICogVDJpOwoJICAgICAgICB2YXIgU1QzaSA9IC1pbnYgKiBUMnI7CgoJICAgICAgICB2YXIgU0ZBciA9IFNUMHIgKyBTVDJyOwoJICAgICAgICB2YXIgU0ZBaSA9IFNUMGkgKyBTVDJpOwoKCSAgICAgICAgdmFyIFNGQnIgPSBTVDFyICsgU1QzaTsKCSAgICAgICAgdmFyIFNGQmkgPSBTVDFpIC0gU1QzcjsKCgkgICAgICAgIHZhciBTQSA9IG91dE9mZiArIHF1YXJ0ZXJMZW4gLSBpOwoJICAgICAgICB2YXIgU0IgPSBvdXRPZmYgKyBoYWxmTGVuIC0gaTsKCgkgICAgICAgIG91dFtTQV0gPSBTRkFyOwoJICAgICAgICBvdXRbU0EgKyAxXSA9IFNGQWk7CgkgICAgICAgIG91dFtTQl0gPSBTRkJyOwoJICAgICAgICBvdXRbU0IgKyAxXSA9IFNGQmk7CgkgICAgICB9CgkgICAgfQoJICB9Cgl9OwoKCS8vIHJhZGl4LTIgaW1wbGVtZW50YXRpb24KCS8vCgkvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTQKCUZGVC5wcm90b3R5cGUuX3NpbmdsZVJlYWxUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVJlYWxUcmFuc2Zvcm0yKG91dE9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCgkgIGNvbnN0IGV2ZW5SID0gZGF0YVtvZmZdOwoJICBjb25zdCBvZGRSID0gZGF0YVtvZmYgKyBzdGVwXTsKCgkgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwoJICBjb25zdCByaWdodFIgPSBldmVuUiAtIG9kZFI7CgoJICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwoJICBvdXRbb3V0T2ZmICsgMV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgMl0gPSByaWdodFI7CgkgIG91dFtvdXRPZmYgKyAzXSA9IDA7Cgl9OwoKCS8vIHJhZGl4LTQKCS8vCgkvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKCUZGVC5wcm90b3R5cGUuX3NpbmdsZVJlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCSAgY29uc3QgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICBjb25zdCBzdGVwMiA9IHN0ZXAgKiAyOwoJICBjb25zdCBzdGVwMyA9IHN0ZXAgKiAzOwoKCSAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgIGNvbnN0IEFyID0gZGF0YVtvZmZdOwoJICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CgkgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CgkgIGNvbnN0IERyID0gZGF0YVtvZmYgKyBzdGVwM107CgoJICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgIGNvbnN0IFQwciA9IEFyICsgQ3I7CgkgIGNvbnN0IFQxciA9IEFyIC0gQ3I7CgkgIGNvbnN0IFQyciA9IEJyICsgRHI7CgkgIGNvbnN0IFQzciA9IGludiAqIChCciAtIERyKTsKCgkgIC8vIEZpbmFsIHZhbHVlcwoJICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CgoJICBjb25zdCBGQnIgPSBUMXI7CgkgIGNvbnN0IEZCaSA9IC1UM3I7CgoJICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CgoJICBjb25zdCBGRHIgPSBUMXI7CgkgIGNvbnN0IEZEaSA9IFQzcjsKCgkgIG91dFtvdXRPZmZdID0gRkFyOwoJICBvdXRbb3V0T2ZmICsgMV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CgkgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKCSAgb3V0W291dE9mZiArIDRdID0gRkNyOwoJICBvdXRbb3V0T2ZmICsgNV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgNl0gPSBGRHI7CgkgIG91dFtvdXRPZmYgKyA3XSA9IEZEaTsKCX07CgoJdmFyIEZGVCQxID0gLypAX19QVVJFX18qL2dldERlZmF1bHRFeHBvcnRGcm9tQ2pzKGZmdCk7CgoJY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKCWNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwoJLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KCWNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CgkgICAgbmJJbnB1dHM7CgkgICAgbmJPdXRwdXRzOwoJICAgIGJsb2NrU2l6ZTsKCSAgICBob3BTaXplOwoJICAgIG5iT3ZlcmxhcHM7CgkgICAgaW5wdXRCdWZmZXJzID0gW107CgkgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwoJICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwoJICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKCSAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwoJICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKCSAgICAgICAgc3VwZXIob3B0aW9ucyk7CgkgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CgkgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKCSAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKCSAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKCSAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CgkgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKCSAgICB9CgkgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwoJICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwoJICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwoJICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwoJICAgICAgICB9CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwoJICAgICAgICB9CgkgICAgfQoJICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CgkgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CgkgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CgkgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGNvbnN0IG5iQ2hhbm5lbHMgPSBpbnB1dHNbaV0ubGVuZ3RoOwoJICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIG5iQ2hhbm5lbHMpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgY29uc3QgbmJDaGFubmVscyA9IG91dHB1dHNbaV0ubGVuZ3RoOwoJICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlT3V0cHV0Q2hhbm5lbHMoaSwgbmJDaGFubmVscyk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmVhZElucHV0cyhpbnB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICBjb25zdCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewoJICAgICAgICAgICAgICAgIGNvbnN0IHdlYkF1ZGlvQmxvY2sgPSBvdXRwdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHdlYkF1ZGlvQmxvY2suc2V0KHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXS5zdWJhcnJheSgwLCBXRUJBVURJT19CTE9DS19TSVpFKSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgc2hpZnRJbnB1dEJ1ZmZlcnMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaV1bal0uY29weVdpdGhpbigwLCBXRUJBVURJT19CTE9DS19TSVpFKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgICBzaGlmdE91dHB1dEJ1ZmZlcnMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uY29weVdpdGhpbigwLCBXRUJBVURJT19CTE9DS19TSVpFKTsKCSAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uZmlsbCgwLCB0aGlzLmJsb2NrU2l6ZSAtIFdFQkFVRElPX0JMT0NLX1NJWkUpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHByZXBhcmVJbnB1dEJ1ZmZlcnNUb1NlbmQoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaV1bal0uc2V0KHRoaXMuaW5wdXRCdWZmZXJzSGVhZFtpXVtqXSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHRoaXMuYmxvY2tTaXplOyBrKyspIHsKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdW2tdICs9IHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbaV1bal1ba10gLyB0aGlzLm5iT3ZlcmxhcHM7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CgkgICAgICAgIHRoaXMucmVhbGxvY2F0ZUNoYW5uZWxzSWZOZWVkZWQoaW5wdXRzLCBvdXRwdXRzKTsKCSAgICAgICAgdGhpcy5yZWFkSW5wdXRzKGlucHV0cyk7CgkgICAgICAgIHRoaXMuc2hpZnRJbnB1dEJ1ZmZlcnMoKTsKCSAgICAgICAgdGhpcy5wcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCk7CgkgICAgICAgIHRoaXMucHJvY2Vzc09MQSh0aGlzLmlucHV0QnVmZmVyc1RvU2VuZCwgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSwgcGFyYW1ldGVycyk7CgkgICAgICAgIHRoaXMuaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKTsKCSAgICAgICAgdGhpcy53cml0ZU91dHB1dHMob3V0cHV0cyk7CgkgICAgICAgIHRoaXMuc2hpZnRPdXRwdXRCdWZmZXJzKCk7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCX0KCgljb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKCWZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CgkgICAgY29uc3Qgd2luID0gbmV3IEZsb2F0MzJBcnJheShsZW5ndGgpOwoJICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKCSAgICAgICAgd2luW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcygoMiAqIE1hdGguUEkgKiBpKSAvIGxlbmd0aCkpOwoJICAgIH0KCSAgICByZXR1cm4gd2luOwoJfQoJY2xhc3MgUGhhc2VWb2NvZGVyUHJvY2Vzc29yIGV4dGVuZHMgT0xBUHJvY2Vzc29yIHsKCSAgICBmZnRTaXplOwoJICAgIHRpbWVDdXJzb3I7CgkgICAgaGFubldpbmRvdzsKCSAgICBmZnQ7CgkgICAgZnJlcUNvbXBsZXhCdWZmZXI7CgkgICAgZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkOwoJICAgIHRpbWVDb21wbGV4QnVmZmVyOwoJICAgIG1hZ25pdHVkZXM7CgkgICAgcGVha0luZGV4ZXM7CgkgICAgbmJQZWFrczsKCSAgICBzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkgewoJICAgICAgICByZXR1cm4gWwoJICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgIG5hbWU6ICJwaXRjaEZhY3RvciIsCgkgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAsCgkgICAgICAgICAgICB9LAoJICAgICAgICBdOwoJICAgIH0KCSAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CgkgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKCSAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKCSAgICAgICAgfTsKCSAgICAgICAgc3VwZXIob3B0aW9ucyk7CgkgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwoJICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwoJICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCgkgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CgkgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwoJICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKCSAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwoJICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwoJICAgIH0KCSAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewoJICAgICAgICBjb25zdCBwaXRjaEZhY3RvciA9IHBhcmFtZXRlcnMucGl0Y2hGYWN0b3JbcGFyYW1ldGVycy5waXRjaEZhY3Rvci5sZW5ndGggLSAxXTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gaW5wdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHZhciBvdXRwdXQgPSBvdXRwdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KGlucHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmZmdC5yZWFsVHJhbnNmb3JtKHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIsIGlucHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmNvbXB1dGVNYWduaXR1ZGVzKCk7CgkgICAgICAgICAgICAgICAgdGhpcy5maW5kUGVha3MoKTsKCSAgICAgICAgICAgICAgICB0aGlzLnNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmNvbXBsZXRlU3BlY3RydW0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmludmVyc2VUcmFuc2Zvcm0odGhpcy50aW1lQ29tcGxleEJ1ZmZlciwgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmZyb21Db21wbGV4QXJyYXkodGhpcy50aW1lQ29tcGxleEJ1ZmZlciwgb3V0cHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmFwcGx5SGFubldpbmRvdyhvdXRwdXQpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHRoaXMudGltZUN1cnNvciArPSB0aGlzLmhvcFNpemU7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCSAgICBhcHBseUhhbm5XaW5kb3coaW5wdXQpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKSB7CgkgICAgICAgICAgICBpbnB1dFtpXSAqPSB0aGlzLmhhbm5XaW5kb3dbaV07CgkgICAgICAgIH0KCSAgICB9CgkgICAgY29tcHV0ZU1hZ25pdHVkZXMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IHRoaXMubWFnbml0dWRlcy5sZW5ndGg7IGkrKywgaiArPSAyKSB7CgkgICAgICAgICAgICBjb25zdCByZWFsID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltqXTsKCSAgICAgICAgICAgIGNvbnN0IGltYWcgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2ogKyAxXTsKCSAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpXSA9IHJlYWwgKiogMiArIGltYWcgKiogMjsKCSAgICAgICAgfQoJICAgIH0KCSAgICBmaW5kUGVha3MoKSB7CgkgICAgICAgIHRoaXMubmJQZWFrcyA9IDA7CgkgICAgICAgIGZvciAobGV0IGkgPSAyLCBlbmQgPSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoIC0gMjsgaSA8IGVuZDsgaSsrKSB7CgkgICAgICAgICAgICBjb25zdCBtYWcgPSB0aGlzLm1hZ25pdHVkZXNbaV07CgkgICAgICAgICAgICBpZiAodGhpcy5tYWduaXR1ZGVzW2kgLSAxXSA+PSBtYWcgfHwKCSAgICAgICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fAoJICAgICAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpICsgMV0gPj0gbWFnIHx8CgkgICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2kgKyAyXSA+PSBtYWcpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRoaXMucGVha0luZGV4ZXNbdGhpcy5uYlBlYWtzKytdID0gaTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBzaGlmdFBlYWtzKHBpdGNoRmFjdG9yKSB7CgkgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkLmZpbGwoMCk7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYlBlYWtzOyBpKyspIHsKCSAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleCA9IHRoaXMucGVha0luZGV4ZXNbaV07CgkgICAgICAgICAgICBjb25zdCBwZWFrSW5kZXhTaGlmdGVkID0gTWF0aC5yb3VuZChwZWFrSW5kZXggKiBwaXRjaEZhY3Rvcik7CgkgICAgICAgICAgICBpZiAocGVha0luZGV4U2hpZnRlZCA+IHRoaXMubWFnbml0dWRlcy5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvbnN0IHN0YXJ0SW5kZXggPSBpID4gMCA/IHBlYWtJbmRleCAtIE1hdGguZmxvb3IoKHBlYWtJbmRleCAtIHRoaXMucGVha0luZGV4ZXNbaSAtIDFdKSAvIDIpIDogMDsKCSAgICAgICAgICAgIGNvbnN0IGVuZEluZGV4ID0gaSA8IHRoaXMubmJQZWFrcyAtIDEgPyBwZWFrSW5kZXggKyBNYXRoLmNlaWwoKHRoaXMucGVha0luZGV4ZXNbaSArIDFdIC0gcGVha0luZGV4KSAvIDIpIDogdGhpcy5mZnRTaXplOwoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IHN0YXJ0SW5kZXggLSBwZWFrSW5kZXg7IGogPCBlbmRJbmRleCAtIHBlYWtJbmRleDsgaisrKSB7CgkgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXggPSBwZWFrSW5kZXggKyBqOwoJICAgICAgICAgICAgICAgIGNvbnN0IGJpbkluZGV4U2hpZnRlZCA9IHBlYWtJbmRleFNoaWZ0ZWQgKyBqOwoJICAgICAgICAgICAgICAgIGlmIChiaW5JbmRleFNoaWZ0ZWQgPj0gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY29uc3Qgb21lZ2FEZWx0YSA9ICgyICogTWF0aC5QSSAqIChiaW5JbmRleFNoaWZ0ZWQgLSBiaW5JbmRleCkpIC8gdGhpcy5mZnRTaXplOwoJICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CgkgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKCSAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CgkgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKCSAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CgkgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwoJICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwoJICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwoJICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwoJICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKCSAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwoJICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9Cgl9CgkvLyBAdHMtZXhwZWN0LWVycm9yCglyZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7Cgljb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCglleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCglyZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGhhc2Utdm9jb2Rlci1idW5kbGUuanMubWFwCg==",v="data:text/javascript;base64,dmFyIHN0ZXJlb1RvQmZvcm1hdCA9IChmdW5jdGlvbiAoZXhwb3J0cykgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIGNvbnN0IFNRUlQxXzIgPSBNYXRoLlNRUlQxXzI7CiAgICBmdW5jdGlvbiBlbmNvZGVTdGVyZW9Ub0JGb3JtYXQobGVmdCwgcmlnaHQsIHcsIHgsIHksIHopIHsKICAgICAgICBjb25zdCBmcmFtZUNvdW50ID0gTWF0aC5taW4obGVmdC5sZW5ndGgsIHJpZ2h0Lmxlbmd0aCwgdy5sZW5ndGgsIHgubGVuZ3RoLCB5Lmxlbmd0aCwgei5sZW5ndGgpOwogICAgICAgIGZvciAobGV0IGZyYW1lID0gMDsgZnJhbWUgPCBmcmFtZUNvdW50OyBmcmFtZSsrKSB7CiAgICAgICAgICAgIGNvbnN0IGwgPSBsZWZ0W2ZyYW1lXTsKICAgICAgICAgICAgY29uc3QgciA9IHJpZ2h0W2ZyYW1lXTsKICAgICAgICAgICAgd1tmcmFtZV0gPSAobCArIHIpICogU1FSVDFfMjsKICAgICAgICAgICAgeFtmcmFtZV0gPSAwOwogICAgICAgICAgICB5W2ZyYW1lXSA9IChsIC0gcikgKiBTUVJUMV8yOwogICAgICAgICAgICB6W2ZyYW1lXSA9IDA7CiAgICAgICAgfQogICAgfQoKICAgIGNsYXNzIFN0ZXJlb1RvQkZvcm1hdFByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgcHJvY2VzcyhpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgY29uc3QgaW5wdXQgPSBpbnB1dHNbMF07CiAgICAgICAgICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dHNbMF07CiAgICAgICAgICAgIGlmICghaW5wdXQgfHwgaW5wdXQubGVuZ3RoIDwgMiB8fCAhb3V0cHV0IHx8IG91dHB1dC5sZW5ndGggPCA0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbmNvZGVTdGVyZW9Ub0JGb3JtYXQoaW5wdXRbMF0sIGlucHV0WzFdLCBvdXRwdXRbMF0sIG91dHB1dFsxXSwgb3V0cHV0WzJdLCBvdXRwdXRbM10pOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICByZWdpc3RlclByb2Nlc3Nvcigic3RlcmVvLXRvLWJmb3JtYXQiLCBTdGVyZW9Ub0JGb3JtYXRQcm9jZXNzb3IpOwoKICAgIGV4cG9ydHMuU3RlcmVvVG9CRm9ybWF0UHJvY2Vzc29yID0gU3RlcmVvVG9CRm9ybWF0UHJvY2Vzc29yOwoKICAgIHJldHVybiBleHBvcnRzOwoKfSkoe30pOwovLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tdG8tYmZvcm1hdC1idW5kbGUuanMubWFwCg==";class b{listeners={};on(e,t){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:t,once:!1}),()=>this.off(e,t)}once(e,t){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:t,once:!0}),()=>this.off(e,t)}off(e,t){const s=this.listeners[e];s&&(this.listeners[e]=s.filter(g=>g.fn!==t))}emit(e,t){const s=this.listeners[e];s&&(s.forEach(g=>g.fn(t)),this.listeners[e]=s.filter(g=>!g.once))}emitAsync(e,t){const s=this.listeners[e];if(s){const g=s.map(o=>Promise.resolve().then(()=>o.fn(t)).catch(i=>console.error(`Error in listener for event ${e}:`,i)));return this.listeners[e]=s.filter(o=>!o.once),Promise.all(g).then(()=>{})}return Promise.resolve()}removeAllListeners(){this.listeners={}}}class w{constructor(e=[]){this.sounds=e}_position=[0,0,0];loopCount=0;playIndex=0;preplayRandom(){if(this.sounds.length===0)return;const t=this.randomSound().preplay();return t.length>0?t[0]:void 0}playRandom(){const e=this.preplayRandom();return e&&e.play(),e}preplayOrdered(e=!0){if(this.sounds.length===0||this.playIndex>=this.sounds.length)return;const s=this.sounds[this.playIndex].preplay();if(s.length!==0)return this.playIndex=(this.playIndex+1)%this.sounds.length,!e&&this.playIndex===0&&(this.playIndex=this.sounds.length),s[0]}playOrdered(e=!0){const t=this.preplayOrdered(e);return t&&t.play(),t}get duration(){return this.sounds.map(e=>e.duration).reduce((e,t)=>Math.max(e,t),0)}seek(e){this.sounds.forEach(t=>t.seek?.(e))}addSound(e){this.sounds.push(e)}randomSound(){if(this.sounds.length===0)throw new Error("Cannot get a random sound from an empty group");const e=Math.floor(Math.random()*this.sounds.length);return this.sounds[e]}preplay(){return this.sounds.map(t=>t.preplay()).flat()}play(){const e=[];return this.preplay().forEach(t=>{t.play(),e.push(t)}),e}get isPlaying(){return this.sounds.some(e=>e.isPlaying)}stop(){this.sounds.forEach(e=>e.stop())}pause(){this.sounds.forEach(e=>e.pause())}fadeTo(e,t,s){return Promise.all(this.sounds.map(g=>g.fadeTo(e,t,s))).then(()=>{})}fadeIn(e,t){return Promise.all(this.sounds.map(s=>s.fadeIn(e,t))).then(()=>{})}fadeOut(e,t){return Promise.all(this.sounds.map(s=>s.fadeOut(e,t))).then(()=>{})}stopWithFade(e,t){return Promise.all(this.sounds.map(s=>s.stopWithFade(e,t))).then(()=>{})}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.sounds.forEach(t=>t.loop(e)),this.loopCount)}addFilter(e){this.sounds.forEach(t=>t.addFilter(e))}removeFilter(e){this.sounds.forEach(t=>t.removeFilter(e))}set position(e){this._position=e,this.sounds.forEach(t=>t.position=this._position)}get position(){return this._position}get volume(){return this.sounds.length===0?1:this.sounds.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.sounds.length}set volume(e){this.sounds.forEach(t=>t.volume=e)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(e){this.sounds.forEach(t=>t.playbackRate=e)}}class y{_filters=[];addFilter(e){if(this._filters.includes(e))throw new Error("Cannot add the same filter instance twice");this._filters.push(e)}removeFilter(e){const t=this._filters.length;if(this._filters=this._filters.filter(s=>s!==e),this._filters.length===t)throw new Error("Cannot remove filter that was never added to this container")}applyFilters(e){return this._filters.reduce((t,s)=>(t.connect(s),s),e),this._filters.length>0?this._filters[this._filters.length-1]:e}get filters(){return this._filters}addFilters(e){e.forEach(t=>this.addFilter(t))}removeFilters(e){e.forEach(t=>this.removeFilter(t))}cleanup(){this._filters.forEach(e=>e.disconnect()),this._filters=[]}}class S extends y{context;source;gainNode;panner;constructor(e,t,s,g=0){super(),this.source=e,this.gainNode=t,this.context=s,this.panner=s.createPanner(),e.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}get isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(e){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=e}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!0)}addFilter(e){super.addFilter(e),this.refreshFilters()}removeFilter(e){super.removeFilter(e),this.refreshFilters()}set position(e){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[t,s,g]=e;this.panner.positionX.value=t,this.panner.positionY.value=s,this.panner.positionZ.value=g}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(e){}}class D extends y{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(e,t){super(),this.context=e,this.microphoneGainNode=this.context.createGain(),t&&(this.stream=t,this.streamSource=this.createStreamSource(t))}createStreamSource(e){if(!this.context.createMediaStreamSource)throw new Error("Media stream sources are not supported on this audio context (e.g. OfflineAudioContext).");return this.context.createMediaStreamSource(e)}play(){return this.stream?(this.streamPlayback||(this.streamSource=this.streamSource??this.createStreamSource(this.stream),this.streamPlayback=new S(this.streamSource,this.microphoneGainNode,this.context)),[this.streamPlayback]):(navigator.mediaDevices.getUserMedia({audio:!0}).then(e=>{this.stream=e,this.streamSource=this.createStreamSource(this.stream),this.streamPlayback=new S(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(e=>{console.error("Error initializing microphone stream:",e)}),[])}get duration(){return 0}seek(e){}get isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(e){this.streamPlayback&&this.streamPlayback.addFilter(e)}removeFilter(e){this.streamPlayback&&this.streamPlayback.removeFilter(e)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(e){this.streamPlayback&&(this.streamPlayback.volume=e)}get position(){return[0,0,0]}set position(e){}loop(e){return 0}get playbackRate(){return 1}set playbackRate(e){}}function J(c){class e extends c{playbacks=[];_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};_volume=1;play(){const s=this.preplay();return s.forEach(g=>g.play()),s}stop(){this.playbacks.forEach(s=>{s.stop(),s.cleanup()}),this.playbacks=[]}pause(){this.playbacks.forEach(s=>s.pause())}addFilter(s){super.addFilter(s)}removeFilter(s){super.removeFilter(s)}get isPlaying(){return this.playbacks.some(s=>s.isPlaying)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(s){this._threeDOptions.positionX=s[0],this._threeDOptions.positionY=s[1],this._threeDOptions.positionZ=s[2],this.playbacks.forEach(g=>g.position=s)}get threeDOptions(){return this._threeDOptions}set threeDOptions(s){this._threeDOptions={...this._threeDOptions,...s},this.playbacks.forEach(g=>g.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(s){this._stereoPan=s,this.playbacks.forEach(g=>g.stereoPan=s)}get volume(){return this._volume}set volume(s){this._volume=s,this.playbacks.forEach(g=>g.volume=s)}fadeTo(s,g,o){return this._volume=s,Promise.all(this.playbacks.map(i=>i.fadeTo(s,g,o))).then(()=>{})}fadeIn(s,g){return Promise.all(this.playbacks.map(o=>o.fadeIn(s,g))).then(()=>{})}fadeOut(s,g){return Promise.all(this.playbacks.map(o=>o.fadeOut(s,g))).then(()=>{})}stopWithFade(s,g){return this.fadeOut(s,g).then(()=>this.stop())}}return e}function W(c){class e extends c{panner;_panType="stereo";get panType(){return this._panType}setPanType(s,g){this._panType===s&&this.panner||(this.panner&&this.panner.disconnect(),this._panType=s,s==="stereo"?this.panner=g.createStereoPanner():this.panner=g.createPanner())}setPannerNode(s){this.panner=s}get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(s){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");if(s<-1||s>1)throw new RangeError("Stereo pan must be between -1 and 1.");this.panner.pan.setValueAtTime(s,this.panner.context.currentTime)}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const s=this.panner;return{coneInnerAngle:s.coneInnerAngle,coneOuterAngle:s.coneOuterAngle,coneOuterGain:s.coneOuterGain,distanceModel:s.distanceModel,maxDistance:s.maxDistance,channelCount:this.panner.channelCount,channelCountMode:s.channelCountMode,channelInterpretation:s.channelInterpretation,panningModel:s.panningModel,refDistance:s.refDistance,rolloffFactor:s.rolloffFactor,positionX:s.positionX.value,positionY:s.positionY.value,positionZ:s.positionZ.value,orientationX:s.orientationX.value,orientationY:s.orientationY.value,orientationZ:s.orientationZ.value}}set threeDOptions(s){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const g=this.panner;g.coneInnerAngle=s.coneInnerAngle!==void 0?s.coneInnerAngle:g.coneInnerAngle,g.coneOuterAngle=s.coneOuterAngle!==void 0?s.coneOuterAngle:g.coneOuterAngle,g.coneOuterGain=s.coneOuterGain!==void 0?s.coneOuterGain:g.coneOuterGain,g.distanceModel=s.distanceModel||g.distanceModel,g.maxDistance=s.maxDistance!==void 0?s.maxDistance:g.maxDistance,g.channelCount=s.channelCount!==void 0?s.channelCount:g.channelCount,g.channelCountMode=s.channelCountMode||g.channelCountMode,g.channelInterpretation=s.channelInterpretation||g.channelInterpretation,g.panningModel=s.panningModel||g.panningModel,g.refDistance=s.refDistance!==void 0?s.refDistance:g.refDistance,g.rolloffFactor=s.rolloffFactor!==void 0?s.rolloffFactor:g.rolloffFactor,g.positionX.value=s.positionX!==void 0?s.positionX:g.positionX.value,g.positionY.value=s.positionY!==void 0?s.positionY:g.positionY.value,g.positionZ.value=s.positionZ!==void 0?s.positionZ:g.positionZ.value,g.orientationX.value=s.orientationX!==void 0?s.orientationX:g.orientationX.value,g.orientationY.value=s.orientationY!==void 0?s.orientationY:g.orientationY.value,g.orientationZ.value=s.orientationZ!==void 0?s.orientationZ:g.orientationZ.value}set position(s){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[g,o,i]=s,a=this.panner;a.positionX.value=g,a.positionY.value=o,a.positionZ.value=i}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const s=this.panner;return[s.positionX.value,s.positionY.value,s.positionZ.value]}cleanup(){this.panner&&(this.panner.disconnect(),this.panner=void 0),super.cleanup()}}return e}function F(c){class e extends c{gainNode;_fadeTimeout;_isFading=!1;setGainNode(s){this.gainNode=s}cleanup(){this.cancelFade(),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),super.cleanup()}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(s){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.cancelFade(),this.gainNode.gain.value=s}get isFading(){return this._isFading}fadeTo(s,g,o="linear"){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");this.cancelFade();const i=this.gainNode.context.currentTime,a=i+g/1e3;return this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,i),o==="exponential"?this.gainNode.gain.exponentialRampToValueAtTime(s===0?1e-4:s,a):this.gainNode.gain.linearRampToValueAtTime(s,a),this._isFading=!0,new Promise(n=>{this._fadeTimeout=setTimeout(()=>{this._isFading=!1,s===0&&o==="exponential"&&this.gainNode&&(this.gainNode.gain.value=0),n()},g)})}cancelFade(){if(this._fadeTimeout&&(clearTimeout(this._fadeTimeout),this._fadeTimeout=void 0),this._isFading&&this.gainNode){const s=this.gainNode.context.currentTime;this.gainNode.gain.cancelScheduledValues(s),this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,s)}this._isFading=!1}fadeIn(s,g){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");const o=this.gainNode.gain.value;return this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(o,s,g)}fadeOut(s,g){return this.fadeTo(0,s,g)}}return e}class H extends W(F(y)){source;_playing=!1;origin;eventEmitter=new b;constructor(){super()}get isPlaying(){return this.source?this._playing:!1}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}fadeTo(e,t,s="linear"){return this.emit("fadeStart",{target:e,duration:t,type:s}),super.fadeTo(e,t,s).then(()=>{this.emit("fadeEnd",void 0)})}cancelFade(){const e=this._isFading;super.cancelFade(),e&&this.emit("fadeCancel",void 0)}cleanup(){this.eventEmitter.removeAllListeners(),super.cleanup()}}class Z extends H{constructor(e,t,s){super(),this.origin=e,this.context=e.context,this.loopCount=e.loopCount,this.setPanType(e.panType,e.context),this.source=t,"buffer"in t&&t.buffer&&(this.buffer=t.buffer),this.setupSourceNode(t),this.source.connect(this.panner),this.setGainNode(s),this.panner.connect(this.gainNode),this.refreshFilters()}context;loopCount=0;currentLoop=0;buffer;_offset=0;_startTime=0;_state=0;_playbackRate=1;_fadeInConfig;_fadeOutConfig;_loopEndCallback;setupSourceNode(e){if("mediaElement"in e&&e.mediaElement)e.mediaElement.onended=this.loopEnded;else if("onended"in e)e.onended=this.loopEnded;else throw new Error("Unsupported source type")}get isPlaying(){return this._state===1}get duration(){if(!this.source)throw new Error("Cannot get duration of a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.duration:this.buffer?this.buffer.duration||NaN:NaN}get playbackRate(){return this._playbackRate}get volume(){return super.volume}set volume(e){super.volume=e,this.emit("volumeChange",e)}set playbackRate(e){if(e<=0)throw new Error("Playback rate must be greater than 0");if(this._state===1){const t=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=t,this._startTime=this.context.currentTime}this._playbackRate=e,this.source&&("playbackRate"in this.source&&(this.source.playbackRate.value=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=e))}loopEnded=()=>{!this.source||this._state!==1||(this.currentLoop++,this.loopCount!=="infinite"&&this.currentLoop>this.loopCount?(this.emit("ended",void 0),this._fadeOutConfig?this.fadeOut(this._fadeOutConfig.duration,this._fadeOutConfig.type).then(()=>{this.stop(),this.removeFromOrigin()}):(this.stop(),this.removeFromOrigin())):(this._loopEndCallback?.(),this.seek(0),this._state!==1&&!("mediaElement"in this.source)&&this.play(),this._fadeInConfig?.perLoop&&this.gainNode&&(this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(this._fadeInConfig.targetVolume,this._fadeInConfig.duration,this._fadeInConfig.type))))};play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");if(this._state===1)return[this];const e=this._state===2;try{let t;if(this._state===2?"mediaElement"in this.source&&this.source.mediaElement?t=this.source.mediaElement.play():(this.recreateSource(),"start"in this.source&&this.source.start&&this.source.start(0,this._offset)):"mediaElement"in this.source&&this.source.mediaElement?(this.source.mediaElement.currentTime=this._offset,t=this.source.mediaElement.play()):"start"in this.source&&this.source.start&&(this.recreateSource(),this.source.start(0,this._offset)),t){const s=this._state;t.then(()=>{this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),e&&this.emit("resume",void 0),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()})},g=>{this._state=s,this.emitAsync("error",{error:g,errorType:"source",timestamp:Date.now(),recoverable:!0})})}else this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),e&&this.emit("resume",void 0),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()});return[this]}catch(t){throw this.emitAsync("error",{error:t,errorType:"source",timestamp:Date.now(),recoverable:!0}),t}}pause(){if(!this.source||this._state!==1)return;const e=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=e,"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.pause():"stop"in this.source&&this.source.stop(),this._state=2,this.emit("pause",void 0),this.origin.cacophony?.emit("globalPause",{source:this.origin,timestamp:Date.now()})}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this._state===3||this._state===0||(this.cancelFade(),"stop"in this.source&&this._state===1&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this._offset=0,this._startTime=0,this._state=3,this.emit("stop",void 0),this.origin.cacophony?.emit("globalStop",{source:this.origin,timestamp:Date.now()}))}fadeIn(e,t,s){return s?.perLoop&&(this._fadeInConfig={duration:e,type:t||"linear",perLoop:!0,targetVolume:this.gainNode.gain.value}),super.fadeIn(e,t)}configureFadeOut(e,t){this._fadeOutConfig={duration:e,type:t||"linear"}}stopWithFade(e,t){return this.fadeOut(e,t).then(()=>this.stop())}seek(e){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");if(!Number.isFinite(e)||e<0)throw new Error("Invalid time value for seek");const t=this._state===1;t&&this.pause(),this._offset=e,"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.currentTime=e),t&&this.play()}get currentTime(){if(this._state===1){const e=(this.context.currentTime-this._startTime)*this._playbackRate;return this._offset+e}else return this._offset}removeFromOrigin(){const e=this.origin.playbacks.indexOf(this);e!==-1&&this.origin.playbacks.splice(e,1)}recreateSource(){if(!this.buffer||!this.panner||!this.context||!this.gainNode)throw new Error("Cannot recreate source of a sound that has been cleaned up");try{this.source&&(!("mediaElement"in this.source)&&"onended"in this.source&&(this.source.onended=null),this.source.disconnect()),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.source.connect(this.panner),this.source.onended=this.loopEnded,this.playbackRate=this._playbackRate,this.refreshFilters()}catch(e){throw this.emitAsync("error",{error:e,errorType:"source",timestamp:Date.now(),recoverable:!1}),e}}set sourceLoop(e){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=e)}cleanup(){this.source&&("mediaElement"in this.source&&this.source.mediaElement?(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0,this.source.mediaElement.loop=!1,this.source.mediaElement.onended=null):"onended"in this.source&&(this.source.onended=null),this._offset=0,this._startTime=0,this._state=3,this.currentLoop=0,this.source.disconnect(),this.source=void 0,super.cleanup())}assertNotCleanedUp(){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot perform operation on a sound that has been cleaned up")}addFilter(e){this.assertNotCleanedUp(),super.addFilter(e),this.refreshFilters()}removeFilter(e){this.assertNotCleanedUp(),super.removeFilter(e),this.refreshFilters()}loop(e){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(e!==void 0&&(this.loopCount=e==="infinite"?"infinite":Math.max(0,e),this.currentLoop=0),"mediaElement"in this.source&&this.source.mediaElement){const t=this.source.mediaElement;t.loop=this.loopCount==="infinite"}else if("loop"in this.source)this.source.loop=this.loopCount==="infinite",this.source.buffer&&(this.source.loopEnd=this.source.buffer.duration,this.source.loopStart=0);else throw new Error("Unsupported source type");return this.loopCount}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get outputNode(){if(!this.gainNode)throw new Error("Cannot access output node of a playback that has been cleaned up");return this.gainNode}connect(e){return this.outputNode.connect(e)}disconnect(e){e?this.outputNode.disconnect(e):this.outputNode.disconnect()}clone(e={}){if(!this.source||!this.gainNode||!this.context)throw new Error("Cannot clone a sound that has been cleaned up");const t=e.panType||this.panType,s=this.context.createGain();let g;if("buffer"in this.source&&this.source.buffer)g=this.context.createBufferSource(),g.buffer=this.source.buffer;else if("mediaElement"in this.source&&this.source.mediaElement){if(!this.context.createMediaElementSource)throw new Error("Media element sources are not supported on this audio context.");g=this.context.createMediaElementSource(this.source.mediaElement)}else throw new Error("Unsupported source type");const o=e.loopCount!==void 0?e.loopCount:this.loopCount,i=new Z(this.origin,g,s);return i.loopCount=o,i.currentLoop=this.currentLoop,i.setPanType(t,this.context),i.volume=this.volume,i.playbackRate=this._playbackRate,i._offset=this._offset,i._state=this._state,this._filters.forEach(a=>{const n=this.context.createBiquadFilter();n.type=a.type,n.frequency.value=a.frequency.value,n.Q.value=a.Q.value,n.gain.value=a.gain.value,i.addFilter(n)}),this._state===1&&i.play(),i}}class m extends J(y){constructor(e,t,s,g,o=B.Buffer,i="HRTF",a){super(),this.url=e,this.globalGainNode=g,this.soundType=o,this.panType=i,this._cacophony=a,this.buffer=t,this.context=s,this._cacophony?.registerSoundForCleanup(this,this._holdings,this._unregisterToken)}buffer;context;loopCount=0;_playbackRate=1;eventEmitter=new b;_holdings={sources:[],gainNodes:[],mediaElements:[]};_unregisterToken={};get cacophony(){return this._cacophony}get volume(){return super.volume}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}clone(e={}){const t=e.panType||this.panType,s=e.stereoPan!==void 0?e.stereoPan:this.stereoPan,g=e.threeDOptions||this.threeDOptions,o=e.loopCount!==void 0?e.loopCount:this.loopCount,i=e.playbackRate||this.playbackRate,a=e.volume!==void 0?e.volume:this.volume,n=e.position!==void 0?e.position:this.position,I=e.filters?.length?e.filters:this._filters,r=new m(this.url,this.buffer,this.context,this.globalGainNode,this.soundType,t,this.cacophony);return r.loop(o),r.playbackRate=i,r.volume=a,t==="HRTF"?(r.threeDOptions=g,r.position=n):r.stereoPan=s,r.addFilters(I),r}preplay(){try{let e;if(this.buffer)e=this.context.createBufferSource(),e.buffer=this.buffer;else{if(!this.context.createMediaElementSource)throw new Error("Media element sources are not supported on this audio context (e.g. OfflineAudioContext). Use buffer-based sounds instead.");const g=new Audio;g.crossOrigin="anonymous",g.src=this.url,g.preload="auto",e=this.context.createMediaElementSource(g)}const t=this.context.createGain();t.connect(this.globalGainNode);const s=new Z(this,e,t);return this._holdings.sources.push(e),this._holdings.gainNodes.push(t),"mediaElement"in e&&e.mediaElement&&this._holdings.mediaElements.push(e.mediaElement),s.setGainNode(t),s.volume=this.volume,s.playbackRate=this.playbackRate,this._filters.forEach(g=>{const o=this.context.createBiquadFilter();o.type=g.type,o.frequency.value=g.frequency.value,o.Q.value=g.Q.value,o.gain.value=g.gain.value,s.addFilter(o)}),this.panType==="HRTF"?(s.threeDOptions=this.threeDOptions,s.position=this.position):this.panType==="stereo"&&(s.stereoPan=this.stereoPan),s.on("ended",()=>{this.emit("ended",void 0)}),s._loopEndCallback=()=>{this.emit("loopEnd",void 0)},s.on("error",g=>{this.emitAsync("soundError",{url:this.url,error:g.error,errorType:"playback",timestamp:g.timestamp,recoverable:g.recoverable})}),this.playbacks.push(s),[s]}catch(e){const t={url:this.url,error:e,errorType:"playback",timestamp:Date.now(),recoverable:!0};throw this.emitAsync("soundError",t),e}}play(e){const t=this.preplay();for(const s of t){const g=i=>{o(),this.emit("play",i)},o=()=>{s.off("play",g),s.off("error",o)};s.on("play",g),s.on("error",o);try{s.play()}catch(i){throw o(),i}}if(e)for(const s of t)e.fadeIn!==void 0&&s.fadeIn(e.fadeIn,e.fadeType,{perLoop:e.fadeInPerLoop}),e.fadeOut!==void 0&&s.configureFadeOut(e.fadeOut,e.fadeType);return t}stop(){this._holdings.sources.length=0,this._holdings.gainNodes.length=0,this._holdings.mediaElements.length=0,super.stop(),this.emit("stop",void 0)}pause(){super.pause(),this.emit("pause",void 0)}resume(){this.playbacks.forEach(e=>e.play()),this.emit("resume",void 0)}seek(e){this.playbacks.forEach(t=>t.seek(e))}get duration(){return this.playbacks.length>0?this.playbacks[0].duration:this.buffer?.duration||NaN}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.playbacks.forEach(t=>t.loop(e)),this.loopCount)}get playbackRate(){return this._playbackRate}set playbackRate(e){this._playbackRate=e,this.playbacks.forEach(t=>t.playbackRate=e),this.emit("rateChange",e)}set volume(e){super.volume=e,this.emit("volumeChange",e)}cleanup(){this._cacophony?.unregisterSoundCleanup(this._unregisterToken),this._holdings.sources.length=0,this._holdings.gainNodes.length=0,this._holdings.mediaElements.length=0,this.playbacks.forEach(e=>e.cleanup()),this.playbacks=[],this.eventEmitter.removeAllListeners()}}function T(c){class e extends H{_oscillatorOptions={};get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(s){this._oscillatorOptions=s,this.source&&(this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type))}play(){if(!this.source)throw new Error("No source node found");return this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type),this.source.start(),this._playing=!0,[this]}stop(){this.source?.stop&&(this.source.stop(),this._playing=!1)}pause(){this.stop()}get frequency(){return this.source.frequency.value}set frequency(s){this.source.frequency.value=s,this.oscillatorOptions.frequency=s}get detune(){return this.source.detune.value}set detune(s){this.source.detune.value=s,this.oscillatorOptions.detune=s}get type(){return this.source.type}set type(s){this.source.type=s,this.oscillatorOptions.type=s}}return e}class M extends T(W(F(y))){constructor(e,t,s){super(),this.origin=e,this.source=t,this.context=e.context,this.setPanType(e.panType,e.context),this.source.connect(this.panner),this.setGainNode(s),this.panner.connect(this.gainNode),this.refreshFilters(),this.oscillatorOptions={detune:t.detune.value,frequency:t.frequency.value,type:t.type}}context;_state=0;play(){if(!this.source||!this.panner)throw new Error("Cannot play a synth that has been cleaned up");return this._state===1?[this]:((this._state===2||this._state===3)&&this.recreateSource(),this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type),this.source.start(),this._playing=!0,this._state=1,[this])}pause(){!this.source||this._state!==1||(this.source.stop(),this._playing=!1,this._state=2)}stop(){!this.source||this._state===0||this._state===3||(this._state===1&&this.source.stop(),this._playing=!1,this._state=3)}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}cleanup(){this.panner&&this.gainNode&&(this.source.disconnect(this.panner),this.panner.disconnect(),this.gainNode.disconnect()),this.eventEmitter.removeAllListeners()}recreateSource(){if(!this.panner)throw new Error("Cannot recreate source of a synth that has been cleaned up");this.source.disconnect(),this.source=this.context.createOscillator(),this.source.connect(this.panner)}}class G extends J(y){constructor(e,t,s=B.Oscillator,g="HRTF",o={},i){super(),this.context=e,this.globalGainNode=t,this.soundType=s,this.panType=g,this.cacophony=i,this.context=e,this._oscillatorOptions=o}_oscillatorOptions;playbacks=[];eventEmitter=new b;on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}clone(e={}){const t=e.panType||this.panType,s=e.stereoPan!==void 0?e.stereoPan:this.stereoPan??0,g=e.threeDOptions||this.threeDOptions,o=e.volume!==void 0?e.volume:this.volume,i=e.position?.length?e.position:this.position,a=e.filters?.length?e.filters:this._filters,n=e.oscillatorOptions||this._oscillatorOptions,I=new G(this.context,this.globalGainNode,this.soundType,t,n,this.cacophony);return I._volume=o,I._position=i,I._stereoPan=s,I._threeDOptions=g,I.addFilters(a),I}preplay(){const e=this.context.createOscillator();return this.createPlayback(e)}createPlayback(e){this.oscillatorOptions.detune!==void 0&&(e.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(e.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(e.type=this.oscillatorOptions.type);const t=this.context.createGain();t.connect(this.globalGainNode);const s=new M(this,e,t);return s.volume=this.volume,this._filters.forEach(g=>{const o=this.context.createBiquadFilter();o.type=g.type,o.frequency.value=g.frequency.value,o.Q.value=g.Q.value,o.gain.value=g.gain.value,s.addFilter(o)}),this.panType==="HRTF"?(s.threeDOptions=this.threeDOptions,s.position=this.position):this.panType==="stereo"&&(s.stereoPan=this.stereoPan),this.playbacks.push(s),[s]}play(){const e=super.play();return this.emit("play",e[0]),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()}),e}stop(){super.stop(),this.emit("stop",void 0),this.cacophony?.emit("globalStop",{source:this,timestamp:Date.now()})}pause(){super.pause(),this.emit("pause",void 0),this.cacophony?.emit("globalPause",{source:this,timestamp:Date.now()})}resume(){this.playbacks.forEach(e=>e.play()),this.emit("resume",void 0),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()})}get volume(){return super.volume}set volume(e){super.volume=e,this.emit("volumeChange",e)}get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(e){this._oscillatorOptions=e,this.playbacks.forEach(t=>{t.source&&(this.oscillatorOptions.detune!==void 0&&(t.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(t.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(t.source.type=this.oscillatorOptions.type))})}get frequency(){return this.oscillatorOptions.frequency??440}set frequency(e){this._oscillatorOptions.frequency=e,this.playbacks.forEach(t=>t.frequency=e),this.emit("frequencyChange",e)}get detune(){return this.oscillatorOptions.detune}set detune(e){this._oscillatorOptions.detune=e,this.playbacks.forEach(t=>t.detune=e),this.emit("detuneChange",e)}get type(){return this.oscillatorOptions.type||"sine"}set type(e){this._oscillatorOptions.type=e,this.playbacks.forEach(t=>t.type=e),this.emit("typeChange",e)}}var B=(c=>(c.HTML="HTML",c.Streaming="Streaming",c.Buffer="Buffer",c.Oscillator="oscillator",c))(B||{});class X{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;eventEmitter=new b;cache;createAudioWorkletNode;constructor(e,t,s={}){this.context=e||new AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.cache=t||new C,this.createAudioWorkletNode=s.createAudioWorkletNode||((g,o,i)=>new AudioWorkletNode(g,o,i)),this.finalizationRegistry=new FinalizationRegistry(g=>{for(const o of g.sources)o.disconnect();for(const o of g.gainNodes)o.disconnect();for(const o of g.mediaElements)o.pause(),o.removeAttribute("src"),o.load()})}registerSoundForCleanup(e,t,s){this.finalizationRegistry.register(e,t,s)}unregisterSoundCleanup(e){this.finalizationRegistry.unregister(e)}static createOffline(e,t){const s=e.context||new OfflineAudioContext(e.numberOfChannels,e.length,e.sampleRate);return new X(s,t)}get isOffline(){return typeof this.context.startRendering=="function"}async startRendering(){if(typeof this.context.startRendering!="function")throw new Error("startRendering() is only available on offline audio contexts. Use Cacophony.createOffline() to create one.");return this.context.startRendering()}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}async loadWorklets(e){this.context.audioWorklet?(await this.createWorkletNode("phase-vocoder",Y,e),await this.loadStereoToBFormatWorklet(e)):console.warn("AudioWorklet not supported")}async loadStereoToBFormatWorklet(e){await this.createWorkletNode("stereo-to-bformat",v,e)}async createWorkletNode(e,t,s,g){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return this.createAudioWorkletNode(this.context,e,g)}catch(o){console.error(o),console.log("Loading worklet from url",t);try{await this.context.audioWorklet.addModule(t,{credentials:"same-origin",...s&&{signal:s}})}catch(i){throw console.error(i),i}return this.createAudioWorkletNode(this.context,e,g)}}async createStereoToBFormatNode(e){return this.createWorkletNode("stereo-to-bformat",v,e,{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[4],channelCount:2,channelCountMode:"explicit",channelInterpretation:"speakers"})}createAbortError(){return new DOMException("Operation was aborted","AbortError")}createMediaSound(e,t,s,g){return g?.aborted?Promise.reject(this.createAbortError()):new Promise((o,i)=>{const a=new Audio;let n=!1;const I=()=>{a.removeEventListener("loadedmetadata",A),a.removeEventListener("error",u),g?.removeEventListener("abort",p)},r=()=>{a.pause(),a.src="",a.load()},l=d=>{n||(n=!0,I(),d())},A=()=>{l(()=>{o(new m(e,void 0,this.context,this.globalGainNode,t,s,this))})},u=()=>{const d=new Error(`Failed to load audio from ${e}`);l(()=>{r(),i(d)})},p=()=>{const d=this.createAbortError();l(()=>{r(),i(d)})};a.crossOrigin="anonymous",a.preload="auto",a.addEventListener("loadedmetadata",A),a.addEventListener("error",u),g?.addEventListener("abort",p,{once:!0}),a.src=e,a.load()})}clearMemoryCache(){this.cache.clearMemoryCache()}createOscillator(e,t="HRTF"){return new G(this.context,this.globalGainNode,"oscillator",t,e,this)}async createSound(e,t="Buffer",s="HRTF",g){if(typeof e=="object")return Promise.resolve(new m("",e,this.context,this.globalGainNode,"Buffer",s,this));const o=e;return t==="HTML"?this.createMediaSound(o,"HTML",s,g):t==="Streaming"?this.createMediaSound(o,"Streaming",s,g):this.cache.getAudioBuffer(this.context,o,g,{onLoadingStart:i=>this.emitAsync("loadingStart",i),onLoadingProgress:i=>this.emitAsync("loadingProgress",i),onLoadingComplete:i=>this.emitAsync("loadingComplete",i),onLoadingError:i=>this.emitAsync("loadingError",i),onCacheHit:i=>this.emitAsync("cacheHit",i),onCacheMiss:i=>this.emitAsync("cacheMiss",i),onCacheError:i=>this.emitAsync("cacheError",i)}).then(i=>new m(o,i,this.context,this.globalGainNode,t,s,this))}async createGroup(e){const t=new w;return e.forEach(s=>t.addSound(s)),t}async createGroupFromUrls(e,t="Buffer",s="HRTF",g){const o=new w;return(await Promise.all(e.map(a=>this.createSound(a,t,s,g)))).forEach(a=>o.addSound(a)),o}async createStream(e,t){return this.createMediaSound(e,"Streaming","HRTF",t)}createBiquadFilter=({type:e,frequency:t,gain:s,Q:g})=>{t===void 0&&(t=350);const o=this.context.createBiquadFilter();return o.type=e||"lowpass",o.frequency.value=t,o.gain.value=s||0,o.Q.value=g||1,o};createSplitter(e=2){if(!this.context.createChannelSplitter)throw new Error("ChannelSplitterNode not supported");return this.context.createChannelSplitter(e)}createMerger(e=2){if(!this.context.createChannelMerger)throw new Error("ChannelMergerNode not supported");return this.context.createChannelMerger(e)}createPanner({coneInnerAngle:e,coneOuterAngle:t,coneOuterGain:s,distanceModel:g,maxDistance:o,channelCount:i,channelCountMode:a,channelInterpretation:n,panningModel:I,refDistance:r,rolloffFactor:l,positionX:A,positionY:u,positionZ:p,orientationX:d,orientationY:f,orientationZ:K}){const h=this.context.createPanner();return h.coneInnerAngle=e||360,h.coneOuterAngle=t||360,h.coneOuterGain=s||0,h.distanceModel=g||"inverse",h.maxDistance=o||1e4,h.channelCount=i||2,h.channelCountMode=a||"clamped-max",h.channelInterpretation=n||"speakers",h.panningModel=I||"HRTF",h.refDistance=r||1,h.rolloffFactor=l||1,h.positionX.value=A||0,h.positionY.value=u||0,h.positionZ.value=p||0,h.orientationX.value=d||0,h.orientationY.value=f||0,h.orientationZ.value=K||0,h}pause(){this.context.suspend&&(this.context.suspend(),this.emit("suspend",void 0))}resume(){this.context.resume&&(this.context.resume(),this.emit("resume",void 0))}setGlobalVolume(e){this.globalGainNode.gain.value!==e&&(this.globalGainNode.gain.value=e,this.emit("volumeChange",e))}get volume(){return this.globalGainNode.gain.value}set volume(e){if(this.muted){this.prevVolume=e;return}this.setGlobalVolume(e)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0),this.emit("mute",void 0))}unmute(){this.muted&&(this.setGlobalVolume(this.prevVolume),this.emit("unmute",void 0))}get muted(){return this.globalGainNode.gain.value===0}set muted(e){e!==this.muted&&(e?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((e,t)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(s=>{const g=new D(this.context,s);e(g)}).catch(s=>{t(s)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(e){const{forward:t,up:s}=e,[g,o,i]=t,[a,n,I]=s;this.listener.forwardX.value=g,this.listener.forwardY.value=o,this.listener.forwardZ.value=i,this.listener.upX.value=a,this.listener.upY.value=n,this.listener.upZ.value=I}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(e){const[t,s,g]=e;this.listener.upX.value=t,this.listener.upY.value=s,this.listener.upZ.value=g}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(e){const[t,s,g]=e;this.listener.forwardX.value=t,this.listener.forwardY.value=s,this.listener.forwardZ.value=g}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(e){const[t,s,g]=e,o=this.context.currentTime;this.listener.positionX.setValueAtTime(t,o),this.listener.positionY.setValueAtTime(s,o),this.listener.positionZ.setValueAtTime(g,o)}}class O{constructor(e=[]){this.synths=e}addSynth(e){this.synths.push(e)}removeSynth(e){const t=this.synths.indexOf(e);if(t!==-1)this.synths.splice(t,1);else throw new Error("Synth not found in group")}play(){return this.synths.flatMap(e=>e.play())}stop(){this.synths.forEach(e=>e.stop())}pause(){this.synths.forEach(e=>e.pause())}resume(){this.synths.forEach(e=>e.resume())}get isPlaying(){return this.synths.some(e=>e.isPlaying)}addFilter(e){this.synths.forEach(t=>t.addFilter(e))}removeFilter(e){this.synths.forEach(t=>t.removeFilter(e))}fadeTo(e,t,s){return Promise.all(this.synths.map(g=>g.fadeTo(e,t,s))).then(()=>{})}fadeIn(e,t){return Promise.all(this.synths.map(s=>s.fadeIn(e,t))).then(()=>{})}fadeOut(e,t){return Promise.all(this.synths.map(s=>s.fadeOut(e,t))).then(()=>{})}stopWithFade(e,t){return Promise.all(this.synths.map(s=>s.stopWithFade(e,t))).then(()=>{})}get volume(){return this.synths.length===0?1:this.synths.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.synths.length}set volume(e){this.synths.forEach(t=>t.volume=e)}get stereoPan(){return this.synths.length===0?null:this.synths[0].stereoPan}set stereoPan(e){this.synths.forEach(t=>t.stereoPan=e)}get position(){return this.synths.length===0?[0,0,0]:this.synths[0].position}set position(e){this.synths.forEach(t=>t.position=e)}get frequency(){return this.synths.length===0?440:this.synths[0].frequency}set frequency(e){this.synths.forEach(t=>t.frequency=e)}get detune(){return this.synths[0]?.detune}set detune(e){this.synths.forEach(t=>t.detune=e)}get type(){return this.synths.length===0?"sine":this.synths[0].type}set type(e){this.synths.forEach(t=>t.type=e)}}exports.AudioCache=C;exports.Cacophony=X;exports.Group=w;exports.MicrophonePlayback=S;exports.Playback=Z;exports.Sound=m;exports.SoundType=B;exports.Synth=G;exports.SynthGroup=O;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|