cacophony 0.16.1 → 0.18.3
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/README.md +4 -0
- package/dist/basePlayback.d.ts +16 -0
- package/dist/cacophony.d.ts +14 -0
- package/dist/container.d.ts +34 -3
- package/dist/events.d.ts +8 -0
- package/dist/filters.d.ts +10 -0
- package/dist/group.d.ts +12 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +895 -695
- package/dist/index.mjs.map +1 -1
- package/dist/oscillatorMixin.d.ts +7 -0
- package/dist/playback.d.ts +35 -1
- package/dist/sound.d.ts +6 -2
- package/dist/synth.d.ts +4 -3
- package/dist/synthPlayback.d.ts +7 -0
- package/dist/volumeMixin.d.ts +33 -0
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Cacophony.html +11 -11
- package/docs/classes/Group.html +17 -10
- package/docs/classes/MicrophonePlayback.html +3 -3
- package/docs/classes/Playback.html +60 -29
- package/docs/classes/Sound.html +40 -17
- package/docs/classes/Synth.html +39 -16
- package/docs/classes/SynthGroup.html +2 -2
- package/docs/enums/SoundType.html +2 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +1 -1
- package/docs/interfaces/AudioEventCallbacks.html +11 -0
- package/docs/interfaces/BaseAudioEvents.html +11 -0
- package/docs/interfaces/BaseSound.html +6 -2
- package/docs/interfaces/CacheErrorEvent.html +6 -0
- package/docs/interfaces/CacheHitEvent.html +5 -0
- package/docs/interfaces/CacheMissEvent.html +5 -0
- package/docs/interfaces/CacophonyEvents.html +17 -0
- package/docs/interfaces/FadeStartEvent.html +5 -0
- package/docs/interfaces/GlobalPlaybackEvent.html +4 -0
- package/docs/interfaces/LoadingCompleteEvent.html +6 -0
- package/docs/interfaces/LoadingErrorEvent.html +6 -0
- package/docs/interfaces/LoadingProgressEvent.html +8 -0
- package/docs/interfaces/LoadingStartEvent.html +4 -0
- package/docs/interfaces/PlayOptions.html +7 -0
- package/docs/interfaces/PlaybackErrorEvent.html +6 -0
- package/docs/interfaces/PlaybackEvents.html +13 -0
- package/docs/interfaces/SoundErrorEvent.html +7 -0
- package/docs/interfaces/SoundEvents.html +15 -0
- package/docs/interfaces/SynthEvents.html +15 -0
- package/docs/modules.html +23 -2
- package/docs/types/CacheEventCallback.html +2 -0
- package/docs/types/ErrorEventCallback.html +2 -0
- package/docs/types/FadeType.html +1 -1
- package/docs/types/LoadingEventCallback.html +2 -0
- 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/package.json +1 -1
package/README.md
CHANGED
|
@@ -213,6 +213,10 @@ synth.addFilter(lowpass);
|
|
|
213
213
|
|
|
214
214
|
// Remove filters
|
|
215
215
|
sound.removeFilter(lowpass);
|
|
216
|
+
|
|
217
|
+
// Note: Filters are cloned to each playback for independent processing
|
|
218
|
+
const playback = sound.play()[0];
|
|
219
|
+
playback.filters[0].frequency.value = 500; // Only affects this playback
|
|
216
220
|
```
|
|
217
221
|
|
|
218
222
|
See [TypeDoc](https://cacophony.js.org) for complete filter parameters and options.
|
package/dist/basePlayback.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FadeType } from './cacophony';
|
|
1
2
|
import { IPlaybackContainer } from './container';
|
|
2
3
|
import { AudioNode } from './context';
|
|
3
4
|
import { FilterManager } from './filters';
|
|
@@ -24,9 +25,16 @@ declare const BasePlayback_base: (abstract new (...args: any[]) => {
|
|
|
24
25
|
removeFilters(filters: BiquadFilterNode[]): void;
|
|
25
26
|
}) & (abstract new (...args: any[]) => {
|
|
26
27
|
gainNode?: import('./context').GainNode | undefined;
|
|
28
|
+
_fadeTimeout?: NodeJS.Timeout | undefined;
|
|
29
|
+
_isFading: boolean;
|
|
27
30
|
setGainNode(gainNode: import('./context').GainNode): void;
|
|
28
31
|
cleanup(): void;
|
|
29
32
|
volume: number;
|
|
33
|
+
readonly isFading: boolean;
|
|
34
|
+
fadeTo(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
35
|
+
cancelFade(): void;
|
|
36
|
+
fadeIn(duration: number, type?: FadeType | undefined): Promise<void>;
|
|
37
|
+
fadeOut(duration: number, type?: FadeType | undefined): Promise<void>;
|
|
30
38
|
_filters: BiquadFilterNode[];
|
|
31
39
|
addFilter(filter: BiquadFilterNode): void;
|
|
32
40
|
removeFilter(filter: BiquadFilterNode): void;
|
|
@@ -60,6 +68,14 @@ export declare abstract class BasePlayback extends BasePlayback_base {
|
|
|
60
68
|
off<K extends keyof PlaybackEvents>(event: K, listener: (data: PlaybackEvents[K]) => void): void;
|
|
61
69
|
emit<K extends keyof PlaybackEvents>(event: K, data: PlaybackEvents[K]): void;
|
|
62
70
|
emitAsync<K extends keyof PlaybackEvents>(event: K, data: PlaybackEvents[K]): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Fades the volume to a target value, emitting fadeStart and fadeEnd events.
|
|
73
|
+
*/
|
|
74
|
+
fadeTo(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Cancels any in-progress fade, emitting fadeCancel if a fade was active.
|
|
77
|
+
*/
|
|
78
|
+
cancelFade(): void;
|
|
63
79
|
cleanup(): void;
|
|
64
80
|
}
|
|
65
81
|
export {};
|
package/dist/cacophony.d.ts
CHANGED
|
@@ -43,6 +43,16 @@ export type FadeType = "linear" | "exponential";
|
|
|
43
43
|
* @typedef {'HRTF' | 'stereo'} PanType - The pan type, either 'HRTF' for 3D audio or 'stereo' for traditional stereo panning.
|
|
44
44
|
*/
|
|
45
45
|
export type PanType = "HRTF" | "stereo";
|
|
46
|
+
/**
|
|
47
|
+
* Options for configuring fade behavior when starting playback via Sound.play().
|
|
48
|
+
* @interface PlayOptions
|
|
49
|
+
*/
|
|
50
|
+
export interface PlayOptions {
|
|
51
|
+
fadeIn?: number;
|
|
52
|
+
fadeOut?: number;
|
|
53
|
+
fadeType?: FadeType;
|
|
54
|
+
fadeInPerLoop?: boolean;
|
|
55
|
+
}
|
|
46
56
|
/**
|
|
47
57
|
* The base interface for any sound-producing entity, including individual sounds, groups, and playbacks.
|
|
48
58
|
* @interface BaseSound
|
|
@@ -58,6 +68,10 @@ export interface BaseSound {
|
|
|
58
68
|
volume: number;
|
|
59
69
|
position?: Position;
|
|
60
70
|
threeDOptions?: any;
|
|
71
|
+
fadeTo?(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
72
|
+
fadeIn?(duration: number, type?: FadeType): Promise<void>;
|
|
73
|
+
fadeOut?(duration: number, type?: FadeType): Promise<void>;
|
|
74
|
+
stopWithFade?(duration: number, type?: FadeType): Promise<void>;
|
|
61
75
|
}
|
|
62
76
|
export declare class Cacophony {
|
|
63
77
|
context: AudioContext;
|
package/dist/container.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BasePlayback } from 'basePlayback';
|
|
2
|
-
import { Position } from './cacophony';
|
|
2
|
+
import { FadeType, Position } from './cacophony';
|
|
3
3
|
import { FilterManager } from './filters';
|
|
4
4
|
type Constructor<T = FilterManager> = abstract new (...args: any[]) => T;
|
|
5
5
|
export interface IPlaybackContainer {
|
|
@@ -38,14 +38,16 @@ export declare function PlaybackContainer<TBase extends Constructor>(Base: TBase
|
|
|
38
38
|
pause(): void;
|
|
39
39
|
/**
|
|
40
40
|
* Adds a BiquadFilterNode to the container's filter chain.
|
|
41
|
-
* Filters are
|
|
41
|
+
* Filters are cloned when creating new playbacks - existing playbacks are not affected.
|
|
42
|
+
* Each playback gets independent filter instances for isolated processing.
|
|
42
43
|
* @param { BiquadFilterNode } filter - The filter to add to the chain.
|
|
43
44
|
*/
|
|
44
45
|
addFilter(filter: BiquadFilterNode): void;
|
|
45
46
|
/**
|
|
46
47
|
* Removes a BiquadFilterNode from the container's filter chain.
|
|
47
|
-
*
|
|
48
|
+
* Only affects future playbacks - existing playbacks retain their cloned filters.
|
|
48
49
|
* @param { BiquadFilterNode } filter - The filter to remove from the chain.
|
|
50
|
+
* @throws {Error} If the filter was never added to this container.
|
|
49
51
|
*/
|
|
50
52
|
removeFilter(filter: BiquadFilterNode): void;
|
|
51
53
|
/**
|
|
@@ -71,6 +73,35 @@ export declare function PlaybackContainer<TBase extends Constructor>(Base: TBase
|
|
|
71
73
|
* @returns {number} The current volume of the sound.
|
|
72
74
|
*/
|
|
73
75
|
volume: number;
|
|
76
|
+
/**
|
|
77
|
+
* Fades the volume of all playbacks to a target value over a duration.
|
|
78
|
+
* @param {number} value - The target volume (0 to 1).
|
|
79
|
+
* @param {number} duration - The fade duration in milliseconds.
|
|
80
|
+
* @param {FadeType} type - The fade curve type. Defaults to "linear".
|
|
81
|
+
* @returns {Promise<void>} Resolves when all fades complete.
|
|
82
|
+
*/
|
|
83
|
+
fadeTo(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Fades in all playbacks from silence to their current volume.
|
|
86
|
+
* @param {number} duration - The fade duration in milliseconds.
|
|
87
|
+
* @param {FadeType} type - The fade curve type. Defaults to "linear".
|
|
88
|
+
* @returns {Promise<void>} Resolves when all fades complete.
|
|
89
|
+
*/
|
|
90
|
+
fadeIn(duration: number, type?: FadeType): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Fades out all playbacks from their current volume to silence.
|
|
93
|
+
* @param {number} duration - The fade duration in milliseconds.
|
|
94
|
+
* @param {FadeType} type - The fade curve type. Defaults to "linear".
|
|
95
|
+
* @returns {Promise<void>} Resolves when all fades complete.
|
|
96
|
+
*/
|
|
97
|
+
fadeOut(duration: number, type?: FadeType): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Fades out all playbacks then stops them.
|
|
100
|
+
* @param {number} duration - The fade-out duration in milliseconds.
|
|
101
|
+
* @param {FadeType} type - The fade curve type. Defaults to "linear".
|
|
102
|
+
* @returns {Promise<void>} Resolves when the fade completes and all playbacks are stopped.
|
|
103
|
+
*/
|
|
104
|
+
stopWithFade(duration: number, type?: FadeType): Promise<void>;
|
|
74
105
|
_filters: BiquadFilterNode[];
|
|
75
106
|
applyFilters(connection: any): any;
|
|
76
107
|
readonly filters: BiquadFilterNode[];
|
package/dist/events.d.ts
CHANGED
|
@@ -5,6 +5,11 @@ import { Synth } from './synth';
|
|
|
5
5
|
/**
|
|
6
6
|
* Base events for all audio objects.
|
|
7
7
|
*/
|
|
8
|
+
export interface FadeStartEvent {
|
|
9
|
+
target: number;
|
|
10
|
+
duration: number;
|
|
11
|
+
type: string;
|
|
12
|
+
}
|
|
8
13
|
export interface BaseAudioEvents {
|
|
9
14
|
play: BasePlayback;
|
|
10
15
|
stop: void;
|
|
@@ -13,6 +18,9 @@ export interface BaseAudioEvents {
|
|
|
13
18
|
ended: void;
|
|
14
19
|
volumeChange: number;
|
|
15
20
|
error: PlaybackErrorEvent;
|
|
21
|
+
fadeStart: FadeStartEvent;
|
|
22
|
+
fadeEnd: void;
|
|
23
|
+
fadeCancel: void;
|
|
16
24
|
}
|
|
17
25
|
/**
|
|
18
26
|
* Sound-specific events.
|
package/dist/filters.d.ts
CHANGED
|
@@ -3,7 +3,17 @@ export type FilterCloneOverrides = {
|
|
|
3
3
|
};
|
|
4
4
|
export declare abstract class FilterManager {
|
|
5
5
|
_filters: BiquadFilterNode[];
|
|
6
|
+
/**
|
|
7
|
+
* Adds a BiquadFilterNode to the filter chain.
|
|
8
|
+
* @param {BiquadFilterNode} filter - The filter to add.
|
|
9
|
+
* @throws {Error} If the same filter instance is added twice.
|
|
10
|
+
*/
|
|
6
11
|
addFilter(filter: BiquadFilterNode): void;
|
|
12
|
+
/**
|
|
13
|
+
* Removes a BiquadFilterNode from the filter chain by object identity.
|
|
14
|
+
* @param {BiquadFilterNode} filter - The filter to remove.
|
|
15
|
+
* @throws {Error} If the filter was never added to this container.
|
|
16
|
+
*/
|
|
7
17
|
removeFilter(filter: BiquadFilterNode): void;
|
|
8
18
|
applyFilters(connection: any): any;
|
|
9
19
|
get filters(): BiquadFilterNode[];
|
package/dist/group.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseSound, LoopCount } from './cacophony';
|
|
1
|
+
import { BaseSound, FadeType, LoopCount } from './cacophony';
|
|
2
2
|
import { Playback } from './playback';
|
|
3
3
|
import { Sound } from './sound';
|
|
4
4
|
export declare class Group implements BaseSound {
|
|
@@ -57,8 +57,19 @@ export declare class Group implements BaseSound {
|
|
|
57
57
|
*/
|
|
58
58
|
stop(): void;
|
|
59
59
|
pause(): void;
|
|
60
|
+
fadeTo(value: number, duration: number, type?: FadeType): Promise<void>;
|
|
61
|
+
fadeIn(duration: number, type?: FadeType): Promise<void>;
|
|
62
|
+
fadeOut(duration: number, type?: FadeType): Promise<void>;
|
|
63
|
+
stopWithFade(duration: number, type?: FadeType): Promise<void>;
|
|
60
64
|
loop(loopCount?: LoopCount): LoopCount;
|
|
65
|
+
/**
|
|
66
|
+
* Adds a filter to all sounds in the group.
|
|
67
|
+
* Filters are cloned to playbacks, not shared.
|
|
68
|
+
*/
|
|
61
69
|
addFilter(filter: BiquadFilterNode): void;
|
|
70
|
+
/**
|
|
71
|
+
* Removes a filter from all sounds in the group.
|
|
72
|
+
*/
|
|
62
73
|
removeFilter(filter: BiquadFilterNode): void;
|
|
63
74
|
set position(position: [number, number, number]);
|
|
64
75
|
get position(): [number, number, number];
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("standardized-audio-context"),Y="data:text/javascript;base64,dmFyIHBoYXNlVm9jb2RlciA9IChmdW5jdGlvbiAoZXhwb3J0cykgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIGNvbnN0IFdFQkFVRElPX0JMT0NLX1NJWkUgPSAxMjg7CiAgICBjb25zdCBERUZBVUxUX0JMT0NLX1NJWkUgPSAxMDI0OyAvLyBEZWZhdWx0IGJsb2NrIHNpemUgaWYgbm90IHByb3ZpZGVkIGluIG9wdGlvbnMKICAgIC8qKiBPdmVybGFwLUFkZCBOb2RlICovCiAgICBjbGFzcyBPTEFQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgewogICAgICAgIG5iSW5wdXRzOwogICAgICAgIG5iT3V0cHV0czsKICAgICAgICBibG9ja1NpemU7CiAgICAgICAgaG9wU2l6ZTsKICAgICAgICBuYk92ZXJsYXBzOwogICAgICAgIGlucHV0QnVmZmVycyA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc0hlYWQgPSBbXTsKICAgICAgICBpbnB1dEJ1ZmZlcnNUb1NlbmQgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzID0gW107CiAgICAgICAgb3V0cHV0QnVmZmVyc1RvUmV0cmlldmUgPSBbXTsKICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIHN1cGVyKG9wdGlvbnMpOwogICAgICAgICAgICB0aGlzLm5iSW5wdXRzID0gb3B0aW9ucy5udW1iZXJPZklucHV0cyB8fCAxOwogICAgICAgICAgICB0aGlzLm5iT3V0cHV0cyA9IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMuYmxvY2tTaXplID0gb3B0aW9ucy5wcm9jZXNzb3JPcHRpb25zLmJsb2NrU2l6ZSB8fCBERUZBVUxUX0JMT0NLX1NJWkU7CiAgICAgICAgICAgIHRoaXMuaG9wU2l6ZSA9IFdFQkFVRElPX0JMT0NLX1NJWkU7CiAgICAgICAgICAgIHRoaXMubmJPdmVybGFwcyA9IE1hdGguZmxvb3IodGhpcy5ibG9ja1NpemUgLyB0aGlzLmhvcFNpemUpOwogICAgICAgICAgICB0aGlzLmluaXRpYWxpemVCdWZmZXJzKCk7CiAgICAgICAgfQogICAgICAgIGluaXRpYWxpemVCdWZmZXJzKCkgewogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVycyA9IG5ldyBBcnJheSh0aGlzLm5iSW5wdXRzKTsKICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1RvU2VuZCA9IG5ldyBBcnJheSh0aGlzLm5iSW5wdXRzKTsKICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IG5ldyBBcnJheSh0aGlzLm5iT3V0cHV0cyk7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZUlucHV0Q2hhbm5lbHMoaW5wdXRJbmRleCwgbmJDaGFubmVscykgewogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XSA9IG5ldyBBcnJheShuYkNoYW5uZWxzKTsKICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1RvU2VuZFtpbnB1dEluZGV4XSA9IG5ldyBBcnJheShuYkNoYW5uZWxzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYkNoYW5uZWxzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdW2ldID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJsb2NrU2l6ZSArIFdFQkFVRElPX0JMT0NLX1NJWkUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uZmlsbCgwKTsKICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzSGVhZFtpbnB1dEluZGV4XVtpXSA9IHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdW2ldLnN1YmFycmF5KDAsIHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdW2ldID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYWxsb2NhdGVPdXRwdXRDaGFubmVscyhvdXRwdXRJbmRleCwgbmJDaGFubmVscykgewogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW291dHB1dEluZGV4XSA9IG5ldyBBcnJheShuYkNoYW5uZWxzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYkNoYW5uZWxzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF1baV0uZmlsbCgwKTsKICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdW2ldID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVhbGxvY2F0ZUNoYW5uZWxzSWZOZWVkZWQoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBsZXQgbmJDaGFubmVscyA9IGlucHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZUlucHV0Q2hhbm5lbHMoaSwgbmJDaGFubmVscyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBsZXQgbmJDaGFubmVscyA9IG91dHB1dHNbaV0ubGVuZ3RoOwogICAgICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlT3V0cHV0Q2hhbm5lbHMoaSwgbmJDaGFubmVscyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVhZElucHV0cyhpbnB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBsZXQgd2ViQXVkaW9CbG9jayA9IGlucHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpXVtqXS5zZXQod2ViQXVkaW9CbG9jaywgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHdyaXRlT3V0cHV0cyhvdXRwdXRzKSB7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBsZXQgd2ViQXVkaW9CbG9jayA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgd2ViQXVkaW9CbG9jay5zZXQodGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLnN1YmFycmF5KDAsIFdFQkFVRElPX0JMT0NLX1NJWkUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzaGlmdElucHV0QnVmZmVycygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpXVtqXS5jb3B5V2l0aGluKDAsIFdFQkFVRElPX0JMT0NLX1NJWkUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0T3V0cHV0QnVmZmVycygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXS5jb3B5V2l0aGluKDAsIFdFQkFVRElPX0JMT0NLX1NJWkUpOwogICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXS5maWxsKDAsIHRoaXMuYmxvY2tTaXplIC0gV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1RvU2VuZFtpXVtqXS5zZXQodGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2ldW2pdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBoYW5kbGVPdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSgpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgdGhpcy5ibG9ja1NpemU7IGsrKykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal1ba10gKz0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbaV1bal1ba10gLyB0aGlzLm5iT3ZlcmxhcHM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICAgICAgICAgIHRoaXMucmVhbGxvY2F0ZUNoYW5uZWxzSWZOZWVkZWQoaW5wdXRzLCBvdXRwdXRzKTsKICAgICAgICAgICAgdGhpcy5yZWFkSW5wdXRzKGlucHV0cyk7CiAgICAgICAgICAgIHRoaXMuc2hpZnRJbnB1dEJ1ZmZlcnMoKTsKICAgICAgICAgICAgdGhpcy5wcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCk7CiAgICAgICAgICAgIHRoaXMucHJvY2Vzc09MQSh0aGlzLmlucHV0QnVmZmVyc1RvU2VuZCwgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSwgcGFyYW1ldGVycyk7CiAgICAgICAgICAgIHRoaXMuaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKTsKICAgICAgICAgICAgdGhpcy53cml0ZU91dHB1dHMob3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMuc2hpZnRPdXRwdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBnZXREZWZhdWx0RXhwb3J0RnJvbUNqcyAoeCkgewogICAgCXJldHVybiB4ICYmIHguX19lc01vZHVsZSAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ2RlZmF1bHQnKSA/IHhbJ2RlZmF1bHQnXSA6IHg7CiAgICB9CgogICAgZnVuY3Rpb24gRkZUKHNpemUpIHsKICAgICAgdGhpcy5zaXplID0gc2l6ZSB8IDA7CiAgICAgIGlmICh0aGlzLnNpemUgPD0gMSB8fCAodGhpcy5zaXplICYgKHRoaXMuc2l6ZSAtIDEpKSAhPT0gMCkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZGVCBzaXplIG11c3QgYmUgYSBwb3dlciBvZiB0d28gYW5kIGJpZ2dlciB0aGFuIDEnKTsKCiAgICAgIHRoaXMuX2NzaXplID0gc2l6ZSA8PCAxOwoKICAgICAgLy8gTk9URTogVXNlIG9mIGB2YXJgIGlzIGludGVudGlvbmFsIGZvciBvbGQgVjggdmVyc2lvbnMKICAgICAgdmFyIHRhYmxlID0gbmV3IEFycmF5KHRoaXMuc2l6ZSAqIDIpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRhYmxlLmxlbmd0aDsgaSArPSAyKSB7CiAgICAgICAgY29uc3QgYW5nbGUgPSBNYXRoLlBJICogaSAvIHRoaXMuc2l6ZTsKICAgICAgICB0YWJsZVtpXSA9IE1hdGguY29zKGFuZ2xlKTsKICAgICAgICB0YWJsZVtpICsgMV0gPSAtTWF0aC5zaW4oYW5nbGUpOwogICAgICB9CiAgICAgIHRoaXMudGFibGUgPSB0YWJsZTsKCiAgICAgIC8vIEZpbmQgc2l6ZSdzIHBvd2VyIG9mIHR3bwogICAgICB2YXIgcG93ZXIgPSAwOwogICAgICBmb3IgKHZhciB0ID0gMTsgdGhpcy5zaXplID4gdDsgdCA8PD0gMSkKICAgICAgICBwb3dlcisrOwoKICAgICAgLy8gQ2FsY3VsYXRlIGluaXRpYWwgc3RlcCdzIHdpZHRoOgogICAgICAvLyAgICogSWYgd2UgYXJlIGZ1bGwgcmFkaXgtNCAtIGl0IGlzIDJ4IHNtYWxsZXIgdG8gZ2l2ZSBpbml0YWwgbGVuPTgKICAgICAgLy8gICAqIE90aGVyd2lzZSBpdCBpcyB0aGUgc2FtZSBhcyBgcG93ZXJgIHRvIGdpdmUgbGVuPTQKICAgICAgdGhpcy5fd2lkdGggPSBwb3dlciAlIDIgPT09IDAgPyBwb3dlciAtIDEgOiBwb3dlcjsKCiAgICAgIC8vIFByZS1jb21wdXRlIGJpdC1yZXZlcnNhbCBwYXR0ZXJucwogICAgICB0aGlzLl9iaXRyZXYgPSBuZXcgQXJyYXkoMSA8PCB0aGlzLl93aWR0aCk7CiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5fYml0cmV2Lmxlbmd0aDsgaisrKSB7CiAgICAgICAgdGhpcy5fYml0cmV2W2pdID0gMDsKICAgICAgICBmb3IgKHZhciBzaGlmdCA9IDA7IHNoaWZ0IDwgdGhpcy5fd2lkdGg7IHNoaWZ0ICs9IDIpIHsKICAgICAgICAgIHZhciByZXZTaGlmdCA9IHRoaXMuX3dpZHRoIC0gc2hpZnQgLSAyOwogICAgICAgICAgdGhpcy5fYml0cmV2W2pdIHw9ICgoaiA+Pj4gc2hpZnQpICYgMykgPDwgcmV2U2hpZnQ7CiAgICAgICAgfQogICAgICB9CgogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgICAgdGhpcy5faW52ID0gMDsKICAgIH0KICAgIHZhciBmZnQgPSBGRlQ7CgogICAgRkZULnByb3RvdHlwZS5mcm9tQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gZnJvbUNvbXBsZXhBcnJheShjb21wbGV4LCBzdG9yYWdlKSB7CiAgICAgIHZhciByZXMgPSBzdG9yYWdlIHx8IG5ldyBBcnJheShjb21wbGV4Lmxlbmd0aCA+Pj4gMSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29tcGxleC5sZW5ndGg7IGkgKz0gMikKICAgICAgICByZXNbaSA+Pj4gMV0gPSBjb21wbGV4W2ldOwogICAgICByZXR1cm4gcmVzOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLmNyZWF0ZUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGNyZWF0ZUNvbXBsZXhBcnJheSgpIHsKICAgICAgY29uc3QgcmVzID0gbmV3IEFycmF5KHRoaXMuX2NzaXplKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpKyspCiAgICAgICAgcmVzW2ldID0gMDsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS50b0NvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIHRvQ29tcGxleEFycmF5KGlucHV0LCBzdG9yYWdlKSB7CiAgICAgIHZhciByZXMgPSBzdG9yYWdlIHx8IHRoaXMuY3JlYXRlQ29tcGxleEFycmF5KCk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSArPSAyKSB7CiAgICAgICAgcmVzW2ldID0gaW5wdXRbaSA+Pj4gMV07CiAgICAgICAgcmVzW2kgKyAxXSA9IDA7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jb21wbGV0ZVNwZWN0cnVtID0gZnVuY3Rpb24gY29tcGxldGVTcGVjdHJ1bShzcGVjdHJ1bSkgewogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwogICAgICB2YXIgaGFsZiA9IHNpemUgPj4+IDE7CiAgICAgIGZvciAodmFyIGkgPSAyOyBpIDwgaGFsZjsgaSArPSAyKSB7CiAgICAgICAgc3BlY3RydW1bc2l6ZSAtIGldID0gc3BlY3RydW1baV07CiAgICAgICAgc3BlY3RydW1bc2l6ZSAtIGkgKyAxXSA9IC1zcGVjdHJ1bVtpICsgMV07CiAgICAgIH0KICAgIH07CgogICAgRkZULnByb3RvdHlwZS50cmFuc2Zvcm0gPSBmdW5jdGlvbiB0cmFuc2Zvcm0ob3V0LCBkYXRhKSB7CiAgICAgIGlmIChvdXQgPT09IGRhdGEpCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgbXVzdCBiZSBkaWZmZXJlbnQnKTsKCiAgICAgIHRoaXMuX291dCA9IG91dDsKICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICAgIHRoaXMuX3RyYW5zZm9ybTQoKTsKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUucmVhbFRyYW5zZm9ybSA9IGZ1bmN0aW9uIHJlYWxUcmFuc2Zvcm0ob3V0LCBkYXRhKSB7CiAgICAgIGlmIChvdXQgPT09IGRhdGEpCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgbXVzdCBiZSBkaWZmZXJlbnQnKTsKCiAgICAgIHRoaXMuX291dCA9IG91dDsKICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICAgIHRoaXMuX3JlYWxUcmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLmludmVyc2VUcmFuc2Zvcm0gPSBmdW5jdGlvbiBpbnZlcnNlVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAxOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3V0Lmxlbmd0aDsgaSsrKQogICAgICAgIG91dFtpXSAvPSB0aGlzLnNpemU7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICAvLyByYWRpeC00IGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogVXNlcyBvZiBgdmFyYCBhcmUgaW50ZW50aW9uYWwgZm9yIG9sZGVyIFY4IHZlcnNpb24gdGhhdCBkbyBub3QKICAgIC8vIHN1cHBvcnQgYm90aCBgbGV0IGNvbXBvdW5kIGFzc2lnbm1lbnRzYCBhbmQgYGNvbnN0IHBoaWAKICAgIEZGVC5wcm90b3R5cGUuX3RyYW5zZm9ybTQgPSBmdW5jdGlvbiBfdHJhbnNmb3JtNCgpIHsKICAgICAgdmFyIG91dCA9IHRoaXMuX291dDsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKCiAgICAgIC8vIEluaXRpYWwgc3RlcCAocGVybXV0ZSBhbmQgdHJhbnNmb3JtKQogICAgICB2YXIgd2lkdGggPSB0aGlzLl93aWR0aDsKICAgICAgdmFyIHN0ZXAgPSAxIDw8IHdpZHRoOwogICAgICB2YXIgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwoKICAgICAgdmFyIG91dE9mZjsKICAgICAgdmFyIHQ7CiAgICAgIHZhciBiaXRyZXYgPSB0aGlzLl9iaXRyZXY7CiAgICAgIGlmIChsZW4gPT09IDQpIHsKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsIHN0ZXApOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVRyYW5zZm9ybTQob3V0T2ZmLCBvZmYsIHN0ZXApOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gTG9vcCB0aHJvdWdoIHN0ZXBzIGluIGRlY3JlYXNpbmcgb3JkZXIKICAgICAgdmFyIGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgdmFyIHRhYmxlID0gdGhpcy50YWJsZTsKICAgICAgZm9yIChzdGVwID4+PSAyOyBzdGVwID49IDI7IHN0ZXAgPj49IDIpIHsKICAgICAgICBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CiAgICAgICAgdmFyIHF1YXJ0ZXJMZW4gPSBsZW4gPj4+IDI7CgogICAgICAgIC8vIExvb3AgdGhyb3VnaCBvZmZzZXRzIGluIHRoZSBkYXRhCiAgICAgICAgZm9yIChvdXRPZmYgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuKSB7CiAgICAgICAgICAvLyBGdWxsIGNhc2UKICAgICAgICAgIHZhciBsaW1pdCA9IG91dE9mZiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICBmb3IgKHZhciBpID0gb3V0T2ZmLCBrID0gMDsgaSA8IGxpbWl0OyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICBjb25zdCBBID0gaTsKICAgICAgICAgICAgY29uc3QgQiA9IEEgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIGNvbnN0IEQgPSBDICsgcXVhcnRlckxlbjsKCiAgICAgICAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICAgICAgICBjb25zdCBBciA9IG91dFtBXTsKICAgICAgICAgICAgY29uc3QgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICBjb25zdCBCciA9IG91dFtCXTsKICAgICAgICAgICAgY29uc3QgQmkgPSBvdXRbQiArIDFdOwogICAgICAgICAgICBjb25zdCBDciA9IG91dFtDXTsKICAgICAgICAgICAgY29uc3QgQ2kgPSBvdXRbQyArIDFdOwogICAgICAgICAgICBjb25zdCBEciA9IG91dFtEXTsKICAgICAgICAgICAgY29uc3QgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICBjb25zdCBNQXIgPSBBcjsKICAgICAgICAgICAgY29uc3QgTUFpID0gQWk7CgogICAgICAgICAgICBjb25zdCB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQmkgPSBpbnYgKiB0YWJsZVtrICsgMV07CiAgICAgICAgICAgIGNvbnN0IE1CciA9IEJyICogdGFibGVCciAtIEJpICogdGFibGVCaTsKICAgICAgICAgICAgY29uc3QgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgY29uc3QgdGFibGVDciA9IHRhYmxlWzIgKiBrXTsKICAgICAgICAgICAgY29uc3QgdGFibGVDaSA9IGludiAqIHRhYmxlWzIgKiBrICsgMV07CiAgICAgICAgICAgIGNvbnN0IE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgY29uc3QgTUNpID0gQ3IgKiB0YWJsZUNpICsgQ2kgKiB0YWJsZUNyOwoKICAgICAgICAgICAgY29uc3QgdGFibGVEciA9IHRhYmxlWzMgKiBrXTsKICAgICAgICAgICAgY29uc3QgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIGNvbnN0IE1EciA9IERyICogdGFibGVEciAtIERpICogdGFibGVEaTsKICAgICAgICAgICAgY29uc3QgTURpID0gRHIgKiB0YWJsZURpICsgRGkgKiB0YWJsZURyOwoKICAgICAgICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwogICAgICAgICAgICBjb25zdCBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIGNvbnN0IFQwaSA9IE1BaSArIE1DaTsKICAgICAgICAgICAgY29uc3QgVDFyID0gTUFyIC0gTUNyOwogICAgICAgICAgICBjb25zdCBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQyciA9IE1CciArIE1EcjsKICAgICAgICAgICAgY29uc3QgVDJpID0gTUJpICsgTURpOwogICAgICAgICAgICBjb25zdCBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgY29uc3QgVDNpID0gaW52ICogKE1CaSAtIE1EaSk7CgogICAgICAgICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICAgICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CiAgICAgICAgICAgIGNvbnN0IEZDaSA9IFQwaSAtIFQyaTsKCiAgICAgICAgICAgIGNvbnN0IEZCciA9IFQxciArIFQzaTsKICAgICAgICAgICAgY29uc3QgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICAgICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICAgICAgICBvdXRbQV0gPSBGQXI7CiAgICAgICAgICAgIG91dFtBICsgMV0gPSBGQWk7CiAgICAgICAgICAgIG91dFtCXSA9IEZCcjsKICAgICAgICAgICAgb3V0W0IgKyAxXSA9IEZCaTsKICAgICAgICAgICAgb3V0W0NdID0gRkNyOwogICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICBvdXRbRF0gPSBGRHI7CiAgICAgICAgICAgIG91dFtEICsgMV0gPSBGRGk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9OwoKICAgIC8vIHJhZGl4LTIgaW1wbGVtZW50YXRpb24KICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTQKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtMihvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CgogICAgICBjb25zdCBldmVuUiA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgZXZlbkkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBvZGRSID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3Qgb2RkSSA9IGRhdGFbb2ZmICsgc3RlcCArIDFdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IGxlZnRJID0gZXZlbkkgKyBvZGRJOwogICAgICBjb25zdCByaWdodFIgPSBldmVuUiAtIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0SSA9IGV2ZW5JIC0gb2RkSTsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IGxlZnRJOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSByaWdodFI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IHJpZ2h0STsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlVHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKICAgICAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwogICAgICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKICAgICAgY29uc3QgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwogICAgICBjb25zdCBzdGVwMiA9IHN0ZXAgKiAyOwogICAgICBjb25zdCBzdGVwMyA9IHN0ZXAgKiAzOwoKICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCiAgICAgIGNvbnN0IEFyID0gZGF0YVtvZmZdOwogICAgICBjb25zdCBBaSA9IGRhdGFbb2ZmICsgMV07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQmkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgQ2kgPSBkYXRhW29mZiArIHN0ZXAyICsgMV07CiAgICAgIGNvbnN0IERyID0gZGF0YVtvZmYgKyBzdGVwM107CiAgICAgIGNvbnN0IERpID0gZGF0YVtvZmYgKyBzdGVwMyArIDFdOwoKICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwogICAgICBjb25zdCBUMHIgPSBBciArIENyOwogICAgICBjb25zdCBUMGkgPSBBaSArIENpOwogICAgICBjb25zdCBUMXIgPSBBciAtIENyOwogICAgICBjb25zdCBUMWkgPSBBaSAtIENpOwogICAgICBjb25zdCBUMnIgPSBCciArIERyOwogICAgICBjb25zdCBUMmkgPSBCaSArIERpOwogICAgICBjb25zdCBUM3IgPSBpbnYgKiAoQnIgLSBEcik7CiAgICAgIGNvbnN0IFQzaSA9IGludiAqIChCaSAtIERpKTsKCiAgICAgIC8vIEZpbmFsIHZhbHVlcwogICAgICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CiAgICAgIGNvbnN0IEZBaSA9IFQwaSArIFQyaTsKCiAgICAgIGNvbnN0IEZCciA9IFQxciArIFQzaTsKICAgICAgY29uc3QgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICBjb25zdCBGRHIgPSBUMXIgLSBUM2k7CiAgICAgIGNvbnN0IEZEaSA9IFQxaSArIFQzcjsKCiAgICAgIG91dFtvdXRPZmZdID0gRkFyOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBGQWk7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IEZDaTsKICAgICAgb3V0W291dE9mZiArIDZdID0gRkRyOwogICAgICBvdXRbb3V0T2ZmICsgN10gPSBGRGk7CiAgICB9OwoKICAgIC8vIFJlYWwgaW5wdXQgcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgRkZULnByb3RvdHlwZS5fcmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfcmVhbFRyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVSZWFsVHJhbnNmb3JtMihvdXRPZmYsIG9mZiA+Pj4gMSwgc3RlcCA+Pj4gMSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIGxlbiA9PT0gOAogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gTG9vcCB0aHJvdWdoIHN0ZXBzIGluIGRlY3JlYXNpbmcgb3JkZXIKICAgICAgdmFyIGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgdmFyIHRhYmxlID0gdGhpcy50YWJsZTsKICAgICAgZm9yIChzdGVwID4+PSAyOyBzdGVwID49IDI7IHN0ZXAgPj49IDIpIHsKICAgICAgICBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CiAgICAgICAgdmFyIGhhbGZMZW4gPSBsZW4gPj4+IDE7CiAgICAgICAgdmFyIHF1YXJ0ZXJMZW4gPSBoYWxmTGVuID4+PiAxOwogICAgICAgIHZhciBocXVhcnRlckxlbiA9IHF1YXJ0ZXJMZW4gPj4+IDE7CgogICAgICAgIC8vIExvb3AgdGhyb3VnaCBvZmZzZXRzIGluIHRoZSBkYXRhCiAgICAgICAgZm9yIChvdXRPZmYgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuKSB7CiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPD0gaHF1YXJ0ZXJMZW47IGkgKz0gMiwgayArPSBzdGVwKSB7CiAgICAgICAgICAgIHZhciBBID0gb3V0T2ZmICsgaTsKICAgICAgICAgICAgdmFyIEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgdmFyIEMgPSBCICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgdmFyIEQgPSBDICsgcXVhcnRlckxlbjsKCiAgICAgICAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICAgICAgICB2YXIgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIHZhciBBaSA9IG91dFtBICsgMV07CiAgICAgICAgICAgIHZhciBCciA9IG91dFtCXTsKICAgICAgICAgICAgdmFyIEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgdmFyIENyID0gb3V0W0NdOwogICAgICAgICAgICB2YXIgQ2kgPSBvdXRbQyArIDFdOwogICAgICAgICAgICB2YXIgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIHZhciBEaSA9IG91dFtEICsgMV07CgogICAgICAgICAgICAvLyBNaWRkbGUgdmFsdWVzCiAgICAgICAgICAgIHZhciBNQXIgPSBBcjsKICAgICAgICAgICAgdmFyIE1BaSA9IEFpOwoKICAgICAgICAgICAgdmFyIHRhYmxlQnIgPSB0YWJsZVtrXTsKICAgICAgICAgICAgdmFyIHRhYmxlQmkgPSBpbnYgKiB0YWJsZVtrICsgMV07CiAgICAgICAgICAgIHZhciBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIHZhciBNQmkgPSBCciAqIHRhYmxlQmkgKyBCaSAqIHRhYmxlQnI7CgogICAgICAgICAgICB2YXIgdGFibGVDciA9IHRhYmxlWzIgKiBrXTsKICAgICAgICAgICAgdmFyIHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICB2YXIgTUNyID0gQ3IgKiB0YWJsZUNyIC0gQ2kgKiB0YWJsZUNpOwogICAgICAgICAgICB2YXIgTUNpID0gQ3IgKiB0YWJsZUNpICsgQ2kgKiB0YWJsZUNyOwoKICAgICAgICAgICAgdmFyIHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIHZhciB0YWJsZURpID0gaW52ICogdGFibGVbMyAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1EciA9IERyICogdGFibGVEciAtIERpICogdGFibGVEaTsKICAgICAgICAgICAgdmFyIE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIFQwciA9IE1BciArIE1DcjsKICAgICAgICAgICAgdmFyIFQwaSA9IE1BaSArIE1DaTsKICAgICAgICAgICAgdmFyIFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgdmFyIFQxaSA9IE1BaSAtIE1DaTsKICAgICAgICAgICAgdmFyIFQyciA9IE1CciArIE1EcjsKICAgICAgICAgICAgdmFyIFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgdmFyIFQzciA9IGludiAqIChNQnIgLSBNRHIpOwogICAgICAgICAgICB2YXIgVDNpID0gaW52ICogKE1CaSAtIE1EaSk7CgogICAgICAgICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgdmFyIEZBaSA9IFQwaSArIFQyaTsKCiAgICAgICAgICAgIHZhciBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIHZhciBGQmkgPSBUMWkgLSBUM3I7CgogICAgICAgICAgICBvdXRbQV0gPSBGQXI7CiAgICAgICAgICAgIG91dFtBICsgMV0gPSBGQWk7CiAgICAgICAgICAgIG91dFtCXSA9IEZCcjsKICAgICAgICAgICAgb3V0W0IgKyAxXSA9IEZCaTsKCiAgICAgICAgICAgIC8vIE91dHB1dCBmaW5hbCBtaWRkbGUgcG9pbnQKICAgICAgICAgICAgaWYgKGkgPT09IDApIHsKICAgICAgICAgICAgICB2YXIgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICAgIHZhciBGQ2kgPSBUMGkgLSBUMmk7CiAgICAgICAgICAgICAgb3V0W0NdID0gRkNyOwogICAgICAgICAgICAgIG91dFtDICsgMV0gPSBGQ2k7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIERvIG5vdCBvdmVyd3JpdGUgb3Vyc2VsdmVzCiAgICAgICAgICAgIGlmIChpID09PSBocXVhcnRlckxlbikKICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIC8vIEluIHRoZSBmbGlwcGVkIGNhc2U6CiAgICAgICAgICAgIC8vIE1BaSA9IC1NQWkKICAgICAgICAgICAgLy8gTUJyPS1NQmksIE1CaT0tTUJyCiAgICAgICAgICAgIC8vIE1Dcj0tTUNyCiAgICAgICAgICAgIC8vIE1Ecj1NRGksIE1EaT1NRHIKICAgICAgICAgICAgdmFyIFNUMHIgPSBUMXI7CiAgICAgICAgICAgIHZhciBTVDBpID0gLVQxaTsKICAgICAgICAgICAgdmFyIFNUMXIgPSBUMHI7CiAgICAgICAgICAgIHZhciBTVDFpID0gLVQwaTsKICAgICAgICAgICAgdmFyIFNUMnIgPSAtaW52ICogVDNpOwogICAgICAgICAgICB2YXIgU1QyaSA9IC1pbnYgKiBUM3I7CiAgICAgICAgICAgIHZhciBTVDNyID0gLWludiAqIFQyaTsKICAgICAgICAgICAgdmFyIFNUM2kgPSAtaW52ICogVDJyOwoKICAgICAgICAgICAgdmFyIFNGQXIgPSBTVDByICsgU1QycjsKICAgICAgICAgICAgdmFyIFNGQWkgPSBTVDBpICsgU1QyaTsKCiAgICAgICAgICAgIHZhciBTRkJyID0gU1QxciArIFNUM2k7CiAgICAgICAgICAgIHZhciBTRkJpID0gU1QxaSAtIFNUM3I7CgogICAgICAgICAgICB2YXIgU0EgPSBvdXRPZmYgKyBxdWFydGVyTGVuIC0gaTsKICAgICAgICAgICAgdmFyIFNCID0gb3V0T2ZmICsgaGFsZkxlbiAtIGk7CgogICAgICAgICAgICBvdXRbU0FdID0gU0ZBcjsKICAgICAgICAgICAgb3V0W1NBICsgMV0gPSBTRkFpOwogICAgICAgICAgICBvdXRbU0JdID0gU0ZCcjsKICAgICAgICAgICAgb3V0W1NCICsgMV0gPSBTRkJpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVSZWFsVHJhbnNmb3JtMiA9IGZ1bmN0aW9uIF9zaW5nbGVSZWFsVHJhbnNmb3JtMihvdXRPZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CgogICAgICBjb25zdCBldmVuUiA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CgogICAgICBjb25zdCBsZWZ0UiA9IGV2ZW5SICsgb2RkUjsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwoKICAgICAgb3V0W291dE9mZl0gPSBsZWZ0UjsKICAgICAgb3V0W291dE9mZiArIDFdID0gMDsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSAwOwogICAgfTsKCiAgICAvLyByYWRpeC00CiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj04CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVSZWFsVHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF9zaW5nbGVSZWFsVHJhbnNmb3JtNChvdXRPZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQnIgPSBkYXRhW29mZiArIHN0ZXBdOwogICAgICBjb25zdCBDciA9IGRhdGFbb2ZmICsgc3RlcDJdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwoKICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwogICAgICBjb25zdCBUMHIgPSBBciArIENyOwogICAgICBjb25zdCBUMXIgPSBBciAtIENyOwogICAgICBjb25zdCBUMnIgPSBCciArIERyOwogICAgICBjb25zdCBUM3IgPSBpbnYgKiAoQnIgLSBEcik7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwoKICAgICAgY29uc3QgRkJyID0gVDFyOwogICAgICBjb25zdCBGQmkgPSAtVDNyOwoKICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwoKICAgICAgY29uc3QgRkRyID0gVDFyOwogICAgICBjb25zdCBGRGkgPSBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gMDsKICAgICAgb3V0W291dE9mZiArIDJdID0gRkJyOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSBGQmk7CiAgICAgIG91dFtvdXRPZmYgKyA0XSA9IEZDcjsKICAgICAgb3V0W291dE9mZiArIDVdID0gMDsKICAgICAgb3V0W291dE9mZiArIDZdID0gRkRyOwogICAgICBvdXRbb3V0T2ZmICsgN10gPSBGRGk7CiAgICB9OwoKICAgIHZhciBGRlQkMSA9IC8qQF9fUFVSRV9fKi9nZXREZWZhdWx0RXhwb3J0RnJvbUNqcyhmZnQpOwoKICAgIGNvbnN0IEJVRkZFUkVEX0JMT0NLX1NJWkUgPSAyMDQ4OwogICAgZnVuY3Rpb24gZ2VuSGFubldpbmRvdyhsZW5ndGgpIHsKICAgICAgICBsZXQgd2luID0gbmV3IEZsb2F0MzJBcnJheShsZW5ndGgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgd2luW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcygoMiAqIE1hdGguUEkgKiBpKSAvIGxlbmd0aCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gd2luOwogICAgfQogICAgY2xhc3MgUGhhc2VWb2NvZGVyUHJvY2Vzc29yIGV4dGVuZHMgT0xBUHJvY2Vzc29yIHsKICAgICAgICBmZnRTaXplOwogICAgICAgIHRpbWVDdXJzb3I7CiAgICAgICAgaGFubldpbmRvdzsKICAgICAgICBmZnQ7CiAgICAgICAgZnJlcUNvbXBsZXhCdWZmZXI7CiAgICAgICAgZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkOwogICAgICAgIHRpbWVDb21wbGV4QnVmZmVyOwogICAgICAgIG1hZ25pdHVkZXM7CiAgICAgICAgcGVha0luZGV4ZXM7CiAgICAgICAgbmJQZWFrczsKICAgICAgICBzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkgewogICAgICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICJwaXRjaEZhY3RvciIsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICBdOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPQogICAgICAgICAgICAgICAgdGhpcy5mZnQuY3JlYXRlQ29tcGxleEFycmF5KCk7CiAgICAgICAgICAgIHRoaXMudGltZUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmZmdFNpemUgLyAyICsgMSk7CiAgICAgICAgICAgIHRoaXMucGVha0luZGV4ZXMgPSBuZXcgSW50MzJBcnJheSh0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKTsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICB9CiAgICAgICAgcHJvY2Vzc09MQShpbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpIHsKICAgICAgICAgICAgY29uc3QgcGl0Y2hGYWN0b3IgPSBwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yW3BhcmFtZXRlcnMucGl0Y2hGYWN0b3IubGVuZ3RoIC0gMV07CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGlucHV0c1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGlucHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB2YXIgb3V0cHV0ID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGx5SGFubldpbmRvdyhpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQucmVhbFRyYW5zZm9ybSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyLCBpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wdXRlTWFnbml0dWRlcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmluZFBlYWtzKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zaGlmdFBlYWtzKHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZmdC5jb21wbGV0ZVNwZWN0cnVtKHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZmdC5pbnZlcnNlVHJhbnNmb3JtKHRoaXMudGltZUNvbXBsZXhCdWZmZXIsIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZmdC5mcm9tQ29tcGxleEFycmF5KHRoaXMudGltZUNvbXBsZXhCdWZmZXIsIG91dHB1dCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3cob3V0cHV0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgKz0gdGhpcy5ob3BTaXplOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgYXBwbHlIYW5uV2luZG93KGlucHV0KSB7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKykgewogICAgICAgICAgICAgICAgaW5wdXRbaV0gKj0gdGhpcy5oYW5uV2luZG93W2ldOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbXB1dGVNYWduaXR1ZGVzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgaiA9IDA7IGkgPCB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoOyBpKyssIGogKz0gMikgewogICAgICAgICAgICAgICAgY29uc3QgcmVhbCA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbal07CiAgICAgICAgICAgICAgICBjb25zdCBpbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltqICsgMV07CiAgICAgICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXNbaV0gPSByZWFsICoqIDIgKyBpbWFnICoqIDI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZmluZFBlYWtzKCkgewogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMiwgZW5kID0gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCAtIDI7IGkgPCBlbmQ7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgbWFnID0gdGhpcy5tYWduaXR1ZGVzW2ldOwogICAgICAgICAgICAgICAgaWYgKHRoaXMubWFnbml0dWRlc1tpIC0gMV0gPj0gbWFnIHx8CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2kgLSAyXSA+PSBtYWcgfHwKICAgICAgICAgICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fAogICAgICAgICAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpICsgMl0gPj0gbWFnKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLnBlYWtJbmRleGVzW3RoaXMubmJQZWFrcysrXSA9IGk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRQZWFrcyhwaXRjaEZhY3RvcikgewogICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZC5maWxsKDApOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJQZWFrczsgaSsrKSB7CiAgICAgICAgICAgICAgICBjb25zdCBwZWFrSW5kZXggPSB0aGlzLnBlYWtJbmRleGVzW2ldOwogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4U2hpZnRlZCA9IE1hdGgucm91bmQocGVha0luZGV4ICogcGl0Y2hGYWN0b3IpOwogICAgICAgICAgICAgICAgaWYgKHBlYWtJbmRleFNoaWZ0ZWQgPiB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsZXQgc3RhcnRJbmRleCA9IGkgPiAwCiAgICAgICAgICAgICAgICAgICAgPyBwZWFrSW5kZXggLSBNYXRoLmZsb29yKChwZWFrSW5kZXggLSB0aGlzLnBlYWtJbmRleGVzW2kgLSAxXSkgLyAyKQogICAgICAgICAgICAgICAgICAgIDogMDsKICAgICAgICAgICAgICAgIGxldCBlbmRJbmRleCA9IGkgPCB0aGlzLm5iUGVha3MgLSAxCiAgICAgICAgICAgICAgICAgICAgPyBwZWFrSW5kZXggKyBNYXRoLmNlaWwoKHRoaXMucGVha0luZGV4ZXNbaSArIDFdIC0gcGVha0luZGV4KSAvIDIpCiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gKDIgKiBNYXRoLlBJICogKGJpbkluZGV4U2hpZnRlZCAtIGJpbkluZGV4KSkgLyB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdFJlYWwgPSBNYXRoLmNvcyhvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBwaGFzZVNoaWZ0SW1hZyA9IE1hdGguc2luKG9tZWdhRGVsdGEgKiB0aGlzLnRpbWVDdXJzb3IpOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4UmVhbCA9IGJpbkluZGV4ICogMjsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleEltYWcgPSBpbmRleFJlYWwgKyAxOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlUmVhbCA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaW5kZXhSZWFsXTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZUltYWcgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4SW1hZ107CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVTaGlmdGVkUmVhbCA9IHZhbHVlUmVhbCAqIHBoYXNlU2hpZnRSZWFsIC0gdmFsdWVJbWFnICogcGhhc2VTaGlmdEltYWc7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVTaGlmdGVkSW1hZyA9IHZhbHVlUmVhbCAqIHBoYXNlU2hpZnRJbWFnICsgdmFsdWVJbWFnICogcGhhc2VTaGlmdFJlYWw7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhTaGlmdGVkUmVhbCA9IGJpbkluZGV4U2hpZnRlZCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhTaGlmdGVkSW1hZyA9IGluZGV4U2hpZnRlZFJlYWwgKyAxOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZFJlYWxdICs9IHZhbHVlU2hpZnRlZFJlYWw7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWRbaW5kZXhTaGlmdGVkSW1hZ10gKz0gdmFsdWVTaGlmdGVkSW1hZzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8vIEB0cy1pZ25vcmUKICAgIHJlZ2lzdGVyUHJvY2Vzc29yKCJwaGFzZS12b2NvZGVyIiwgUGhhc2VWb2NvZGVyUHJvY2Vzc29yKTsKICAgIGNvbnNvbGUubG9nKCJQaGFzZVZvY29kZXJQcm9jZXNzb3IgcmVnaXN0ZXJlZCIpOwoKICAgIGV4cG9ydHMuUGhhc2VWb2NvZGVyUHJvY2Vzc29yID0gUGhhc2VWb2NvZGVyUHJvY2Vzc29yOwoKICAgIHJldHVybiBleHBvcnRzOwoKfSkoe30pOwovLyMgc291cmNlTWFwcGluZ1VSTD1waGFzZS12b2NvZGVyLWJ1bmRsZS5qcy5tYXAK";class w{maxSize;cache;constructor(g){this.maxSize=g,this.cache=new Map}get(g){if(!this.cache.has(g))return;const e=this.cache.get(g);return this.cache.delete(g),this.cache.set(g,e),e}set(g,e){if(this.cache.has(g))this.cache.delete(g);else if(this.cache.size>=this.maxSize){const t=this.cache.keys().next().value;t!==void 0&&this.cache.delete(t)}this.cache.set(g,e)}has(g){return this.cache.has(g)}}const R=100;function E(a){if(!a)return null;const g=a.match(/max-age\s*=\s*"?(\d+)"?/i);return g?parseInt(g[1],10):null}function D(a){return a?/(?:^|,)\s*(no-cache|no-store|must-revalidate)\s*(?:,|$)/i.test(a):!1}class r{static pendingRequests=new Map;static pendingCallbacks=new Map;static decodedBuffers=new w(R);static cacheExpirationTime=1440*60*1e3;static setCacheExpirationTime(g){this.cacheExpirationTime=g}static async openCache(){try{return await caches.open("audio-cache")}catch(g){throw console.error("Failed to open cache:",g),g}}static callAllCallbacks(g,e,t){const I=this.pendingCallbacks.get(g);I&&I.forEach(s=>{const C=s[e];if(C)try{C(t)}catch(i){console.error(`Error in ${e} callback:`,i)}})}static async getOrCreatePendingRequest(g,e,t,I){if(t?.aborted)throw new DOMException("Operation was aborted","AbortError");if(I){const C=this.pendingCallbacks.get(g)||[];C.push(I),this.pendingCallbacks.set(g,C)}let s=this.pendingRequests.get(g);if(!s){const C=(async()=>{try{const i=await e();if(i===void 0)throw new Error("Failed to create audio buffer.");return i}finally{this.pendingRequests.delete(g),this.pendingCallbacks.delete(g)}})();return t?.addEventListener("abort",()=>{t.aborted&&(this.pendingRequests.delete(g),this.pendingCallbacks.delete(g))},{once:!0}),this.pendingRequests.set(g,C),C}return s}static async updateMetadata(g,e,t){const I={url:e,timestamp:Date.now(),...t};await g.put(`${e}:meta`,new Response(JSON.stringify(I),{headers:{"Content-Type":"application/json"}}))}static async getBufferFromCache(g,e){try{const t=await e.match(g);return t&&t.ok?await t.arrayBuffer():null}catch(t){return console.error("Failed to get data from cache:",t),null}}static async fetchAndCacheBuffer(g,e,t,I,s,C){const i=new Headers;t&&i.append("If-None-Match",t),I&&i.append("If-Modified-Since",I),console.debug(`[AudioCache] Fetching ${g}`,{headers:Object.fromEntries(i.entries()),hasEtag:!!t,hasLastModified:!!I});const A=await fetch(g,{headers:i,signal:s});if(console.debug(`[AudioCache] Response ${g}`,{status:A.status,statusText:A.statusText,etag:A.headers?.get("ETag"),lastModified:A.headers?.get("Last-Modified"),cacheControl:A.headers?.get("Cache-Control")}),A.status===304){const o=await e.match(g);if(o){C?.onCacheHit&&C.onCacheHit({url:g,cacheType:"browser",timestamp:Date.now()});const n=Date.now(),c=A.headers?.get("Cache-Control");return await this.updateMetadata(e,g,{timestamp:n,etag:t,lastModified:I,...c?{cacheControl:c}:{}}),await o.arrayBuffer()}else{console.warn(`Cache inconsistency detected for ${g}: 304 response but no cached body. Re-fetching.`);const n=await fetch(g,{signal:s});if(n.status===200){const c=n.clone(),h=n.headers.get("ETag"),d=n.headers.get("Last-Modified"),m=n.headers.get("Cache-Control");try{await Promise.all([e.put(g,c),this.updateMetadata(e,g,{timestamp:Date.now(),etag:h||void 0,lastModified:d||void 0,cacheControl:m||void 0})])}catch(b){throw await e.delete(g),await e.delete(`${g}:meta`),b}if(n.body){const{stream:b,total:V}=this.createProgressTrackingStream(n,g);return await this.collectStreamToArrayBuffer(b,V||void 0)}else return await n.arrayBuffer()}else throw new Error(`Failed to fetch resource after cache inconsistency: ${n.status} ${n.statusText}`)}}if(A.status===200){const o=A.clone(),n=A.headers.get("ETag"),c=A.headers.get("Last-Modified"),h=A.headers.get("Cache-Control");try{await Promise.all([e.put(g,o),this.updateMetadata(e,g,{timestamp:Date.now(),etag:n||void 0,lastModified:c||void 0,cacheControl:h||void 0})])}catch(d){throw await e.delete(g),await e.delete(`${g}:meta`),d}}if(s?.aborted)throw new DOMException("Operation was aborted","AbortError");if(A.body){const{stream:o,total:n}=this.createProgressTrackingStream(A,g);return await this.collectStreamToArrayBuffer(o,n||void 0)}else return await A.arrayBuffer()}static createProgressTrackingStream(g,e){const t=g.headers.get("content-length"),I=t?parseInt(t,10):null;let s=0;if(!g.body)throw new Error("Response body is null");const C=g.body.getReader();return{stream:new ReadableStream({start(A){function o(){return C.read().then(({done:n,value:c})=>{if(n){r.callAllCallbacks(e,"onLoadingProgress",{url:e,loaded:s,total:I,progress:I?1:-1,timestamp:Date.now()}),A.close();return}if(c){s+=c.byteLength;const h=I?s/I:-1;r.callAllCallbacks(e,"onLoadingProgress",{url:e,loaded:s,total:I,progress:h,timestamp:Date.now()}),A.enqueue(c)}return o()}).catch(n=>{A.error(n)})}return o()},cancel(A){return C.cancel(A)}}),total:I}}static async collectStreamToArrayBuffer(g,e){const t=g.getReader();try{if(e!==void 0&&e>0){const I=new ArrayBuffer(e),s=new Uint8Array(I);let C=0;for(;;){const{done:i,value:A}=await t.read();if(i)break;A&&(s.set(A,C),C+=A.byteLength)}return I}else{let I=new Uint8Array(8192),s=0;for(;;){const{done:C,value:i}=await t.read();if(C)break;if(i){if(s+i.byteLength>I.length){const A=Math.max(I.length*2,s+i.byteLength),o=new Uint8Array(A);o.set(I.subarray(0,s)),I=o}I.set(i,s),s+=i.byteLength}}return I.slice(0,s).buffer}}finally{t.releaseLock()}}static async decodeAudioData(g,e){try{return await g.decodeAudioData(e)}catch(t){throw console.error("Failed to decode audio data:",t),t}}static async getMetadataFromCache(g,e){try{const t=await e.match(g+":meta");return t&&t.ok?await t.json():null}catch(t){return console.error("Failed to get metadata from cache:",t),null}}async getAudioBuffer(g,e,t,I){if(I?.onLoadingStart&&I.onLoadingStart({url:e,timestamp:Date.now()}),r.decodedBuffers.has(e))return I?.onCacheHit&&I.onCacheHit({url:e,cacheType:"memory",timestamp:Date.now()}),r.decodedBuffers.get(e);if(e.startsWith("data:")){const A=e.split(",")[1],o=Uint8Array.from(atob(A),c=>c.charCodeAt(0)).buffer,n=await r.decodeAudioData(g,o);return r.decodedBuffers.set(e,n),n}const s=await r.openCache(),C=await r.getMetadataFromCache(e,s),i=(()=>{if(!C||D(C.cacheControl))return!0;const A=E(C.cacheControl);if(A!==null){const o=(Date.now()-C.timestamp)/1e3;if(A>0&&o<A)return!1}return C.etag||C.lastModified?!0:Date.now()-C.timestamp>r.cacheExpirationTime})();return r.getOrCreatePendingRequest(e,async()=>{if(i){I?.onCacheMiss&&I.onCacheMiss({url:e,reason:C?"expired":"not-found",timestamp:Date.now()});try{const A=await r.fetchAndCacheBuffer(e,s,C?.etag,C?.lastModified,t,{onCacheHit:I?.onCacheHit});I?.onLoadingComplete&&I.onLoadingComplete({url:e,duration:0,size:A.byteLength,timestamp:Date.now()});const o=await r.decodeAudioData(g,A);return r.decodedBuffers.set(e,o),o}catch(A){throw I?.onCacheError&&I.onCacheError({url:e,error:A,operation:"get",timestamp:Date.now()}),A}}else{const A=await r.getBufferFromCache(e,s);if(A){I?.onCacheHit&&I.onCacheHit({url:e,cacheType:"browser",timestamp:Date.now()});const o=await r.decodeAudioData(g,A);return r.decodedBuffers.set(e,o),o}else{I?.onCacheError&&I.onCacheError({url:e,error:new Error("Cache inconsistency: metadata exists but body is missing"),operation:"get",timestamp:Date.now()});const o=await r.fetchAndCacheBuffer(e,s,C?.etag,C?.lastModified,t,{onCacheHit:I?.onCacheHit}),n=await r.decodeAudioData(g,o);return r.decodedBuffers.set(e,n),n}}},t,{onLoadingProgress:I?.onLoadingProgress})}clearMemoryCache(){r.decodedBuffers=new w(R),r.pendingRequests.clear()}}class y{listeners={};on(g,e){return this.listeners[g]=this.listeners[g]??[],this.listeners[g].push({fn:e,once:!1}),()=>this.off(g,e)}once(g,e){return this.listeners[g]=this.listeners[g]??[],this.listeners[g].push({fn:e,once:!0}),()=>this.off(g,e)}off(g,e){const t=this.listeners[g];t&&(this.listeners[g]=t.filter(I=>I.fn!==e))}emit(g,e){const t=this.listeners[g];t&&(t.forEach(I=>I.fn(e)),this.listeners[g]=t.filter(I=>!I.once))}emitAsync(g,e){const t=this.listeners[g];if(t){const I=t.map(s=>Promise.resolve().then(()=>s.fn(e)).catch(C=>console.error(`Error in listener for event ${g}:`,C)));return this.listeners[g]=t.filter(s=>!s.once),Promise.all(I).then(()=>{})}return Promise.resolve()}removeAllListeners(){this.listeners={}}}class X{constructor(g=[]){this.sounds=g}_position=[0,0,0];loopCount=0;playIndex=0;preplayRandom(){if(this.sounds.length===0)return;const e=this.randomSound().preplay();return e.length>0?e[0]:void 0}playRandom(){const g=this.preplayRandom();return g&&g.play(),g}preplayOrdered(g=!0){if(this.sounds.length===0)return;const t=this.sounds[this.playIndex].preplay();if(t.length!==0)return this.playIndex=(this.playIndex+1)%this.sounds.length,!g&&this.playIndex===0&&(this.playIndex=this.sounds.length),t[0]}playOrdered(g=!0){const e=this.preplayOrdered(g);return e&&e.play(),e}get duration(){return this.sounds.map(g=>g.duration).reduce((g,e)=>Math.max(g,e),0)}seek(g){this.sounds.forEach(e=>e.seek&&e.seek(g))}addSound(g){this.sounds.push(g)}randomSound(){if(this.sounds.length===0)throw new Error("Cannot get a random sound from an empty group");const g=Math.floor(Math.random()*this.sounds.length);return this.sounds[g]}preplay(){return this.sounds.map(e=>e.preplay()).flat()}play(){const g=[];return this.preplay().forEach(e=>{e.play(),g.push(e)}),g}get isPlaying(){return this.sounds.some(g=>g.isPlaying)}stop(){this.sounds.forEach(g=>g.stop())}pause(){this.sounds.forEach(g=>g.pause())}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.sounds.forEach(e=>e.loop(g)),this.loopCount)}addFilter(g){this.sounds.forEach(e=>e.addFilter(g))}removeFilter(g){this.sounds.forEach(e=>e.removeFilter(g))}set position(g){this._position=g,this.sounds.forEach(e=>e.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(g=>g.volume).reduce((g,e)=>g+e,0)/this.sounds.length}set volume(g){this.sounds.forEach(e=>e.volume=g)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(g){this.sounds.forEach(e=>e.playbackRate=g)}}class p{_filters=[];addFilter(g){this._filters.push(g)}removeFilter(g){this._filters=this._filters.filter(e=>e!==g)}applyFilters(g){return this._filters.reduce((e,t)=>(e.connect(t),t),g),this._filters.length>0?this._filters[this._filters.length-1]:g}get filters(){return this._filters}addFilters(g){g.forEach(e=>this.addFilter(e))}removeFilters(g){g.forEach(e=>this.removeFilter(e))}cleanup(){this._filters.forEach(g=>g.disconnect()),this._filters=[]}}class v extends p{context;source;gainNode;panner;constructor(g,e,t,I=0){super(),this.source=g,this.gainNode=e,this.context=t,this.panner=t.createPanner(),g.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(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=g}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(g=>g.enabled=!0)}addFilter(g){super.addFilter(g),this.refreshFilters()}removeFilter(g){super.removeFilter(g),this.refreshFilters()}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[e,t,I]=g;this.panner.positionX.value=e,this.panner.positionY.value=t,this.panner.positionZ.value=I}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.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.source;this.source.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(g){}}class N extends p{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(g){super(),this.context=g,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{this.stream=g,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new v(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(g=>{console.error("Error initializing microphone stream:",g)}),this.streamPlayback?[this.streamPlayback]:[]}get duration(){return 0}seek(g){}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(g){this.streamPlayback&&this.streamPlayback.addFilter(g)}removeFilter(g){this.streamPlayback&&this.streamPlayback.removeFilter(g)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(g){this.streamPlayback&&(this.streamPlayback.volume=g)}get position(){return[0,0,0]}set position(g){}loop(g){return 0}get playbackRate(){return 1}set playbackRate(g){}}function H(a){class g extends a{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 t=this.preplay();return t.forEach(I=>I.play()),t}stop(){this.playbacks.forEach(t=>t.stop()),this.playbacks=[]}pause(){this.playbacks.forEach(t=>t.pause())}addFilter(t){super.addFilter(t),this.playbacks.forEach(I=>I.addFilter(t))}removeFilter(t){super.removeFilter(t),this.playbacks.forEach(I=>I.removeFilter(t))}get isPlaying(){return this.playbacks.some(t=>t.isPlaying)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(t){this._threeDOptions.positionX=t[0],this._threeDOptions.positionY=t[1],this._threeDOptions.positionZ=t[2],this.playbacks.forEach(I=>I.position=t)}get threeDOptions(){return this._threeDOptions}set threeDOptions(t){this._threeDOptions={...this._threeDOptions,...t},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(t){this._stereoPan=t,this.playbacks.forEach(I=>I.stereoPan=t)}get volume(){return this._volume}set volume(t){this._volume=t,this.playbacks.forEach(I=>I.volume=t)}}return g}function K(a){class g extends a{panner;_panType="stereo";get panType(){return this._panType}setPanType(t,I){this._panType===t&&this.panner||(this.panner&&this.panner.disconnect(),this._panType=t,t==="stereo"?this.panner=I.createStereoPanner():this.panner=I.createPanner())}setPannerNode(t){this.panner=t}get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(t){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");t=S(t,-1,1),this.panner.pan.setValueAtTime(S(t,-1,1),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 t=this.panner;return{coneInnerAngle:t.coneInnerAngle,coneOuterAngle:t.coneOuterAngle,coneOuterGain:t.coneOuterGain,distanceModel:t.distanceModel,maxDistance:t.maxDistance,channelCount:this.panner.channelCount,channelCountMode:t.channelCountMode,channelInterpretation:t.channelInterpretation,panningModel:t.panningModel,refDistance:t.refDistance,rolloffFactor:t.rolloffFactor,positionX:t.positionX.value,positionY:t.positionY.value,positionZ:t.positionZ.value,orientationX:t.orientationX.value,orientationY:t.orientationY.value,orientationZ:t.orientationZ.value}}set threeDOptions(t){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 I=this.panner;I.coneInnerAngle=t.coneInnerAngle!==void 0?t.coneInnerAngle:I.coneInnerAngle,I.coneOuterAngle=t.coneOuterAngle!==void 0?t.coneOuterAngle:I.coneOuterAngle,I.coneOuterGain=t.coneOuterGain!==void 0?t.coneOuterGain:I.coneOuterGain,I.distanceModel=t.distanceModel||I.distanceModel,I.maxDistance=t.maxDistance!==void 0?t.maxDistance:I.maxDistance,I.channelCount=t.channelCount!==void 0?t.channelCount:I.channelCount,I.channelCountMode=t.channelCountMode||I.channelCountMode,I.channelInterpretation=t.channelInterpretation||I.channelInterpretation,I.panningModel=t.panningModel||I.panningModel,I.refDistance=t.refDistance!==void 0?t.refDistance:I.refDistance,I.rolloffFactor=t.rolloffFactor!==void 0?t.rolloffFactor:I.rolloffFactor,I.positionX.value=t.positionX!==void 0?t.positionX:I.positionX.value,I.positionY.value=t.positionY!==void 0?t.positionY:I.positionY.value,I.positionZ.value=t.positionZ!==void 0?t.positionZ:I.positionZ.value,I.orientationX.value=t.orientationX!==void 0?t.orientationX:I.orientationX.value,I.orientationY.value=t.orientationY!==void 0?t.orientationY:I.orientationY.value,I.orientationZ.value=t.orientationZ!==void 0?t.orientationZ:I.orientationZ.value}set position(t){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[I,s,C]=t,i=this.panner;i.positionX.value=I,i.positionY.value=s,i.positionZ.value=C}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 t=this.panner;return[t.positionX.value,t.positionY.value,t.positionZ.value]}cleanup(){this.panner&&(this.panner.disconnect(),this.panner=void 0),super.cleanup()}}return g}function S(a,g,e){return Math.min(Math.max(a,g),e)}function W(a){class g extends a{gainNode;setGainNode(t){this.gainNode=t}cleanup(){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(t){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=t}}return g}class F extends K(W(p)){source;_playing=!1;origin;eventEmitter=new y;constructor(){super()}get isPlaying(){return this.source?this._playing:!1}on(g,e){this.eventEmitter.on(g,e)}off(g,e){this.eventEmitter.off(g,e)}emit(g,e){this.eventEmitter.emit(g,e)}async emitAsync(g,e){return this.eventEmitter.emitAsync(g,e)}cleanup(){this.eventEmitter.removeAllListeners(),super.cleanup()}}class Z extends F{constructor(g,e,t){super(),this.origin=g,this.context=g.context,this.loopCount=g.loopCount,this.setPanType(g.panType,g.context),this.source=e,"buffer"in e&&e.buffer&&(this.buffer=e.buffer),this.setupSourceNode(e),this.source.connect(this.panner),this.setGainNode(t),this.panner.connect(this.gainNode),this.refreshFilters()}context;loopCount=0;currentLoop=0;buffer;_offset=0;_startTime=0;_state=0;_playbackRate=1;setupSourceNode(g){if("mediaElement"in g&&g.mediaElement)g.mediaElement.onended=this.loopEnded;else if("onended"in g)g.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}set playbackRate(g){if(g<=0)throw new Error("Playback rate must be greater than 0");if(this._state===1){const e=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=e,this._startTime=this.context.currentTime}this._playbackRate=g,this.source&&("playbackRate"in this.source&&(this.source.playbackRate.value=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=g))}loopEnded=()=>{!this.source||this._state!==1||(this.currentLoop++,this.loopCount!=="infinite"&&this.currentLoop>this.loopCount?this.stop():(this.seek(0),"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():this.play()))};play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");if(this._state===1)return[this];try{return this._state===2?"mediaElement"in this.source&&this.source.mediaElement?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,this.source.mediaElement.play()):"start"in this.source&&this.source.start&&(this.recreateSource(),this.source.start(0,this._offset)),this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()}),[this]}catch(g){throw this.emitAsync("error",{error:g,errorType:"source",timestamp:Date.now(),recoverable:!0}),g}}pause(){if(!this.source||this._state!==1)return;const g=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=g,"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||("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()}))}seek(g){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");if(!isFinite(g)||g<0)throw new Error("Invalid time value for seek");const e=this._state===1;e&&this.pause(),this._offset=g,"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.currentTime=g),e&&this.play()}get currentTime(){if(this._state===1){const g=(this.context.currentTime-this._startTime)*this._playbackRate;return this._offset+g}else return this._offset}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(g){throw this.emitAsync("error",{error:g,errorType:"source",timestamp:Date.now(),recoverable:!1}),g}}set sourceLoop(g){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=g),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=g)}cleanup(){this.source&&(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(g){this.assertNotCleanedUp(),super.addFilter(g),this.refreshFilters()}removeFilter(g){this.assertNotCleanedUp(),super.removeFilter(g),this.refreshFilters()}loop(g){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(g!==void 0&&(this.loopCount=g==="infinite"?"infinite":Math.max(0,g),this.currentLoop=0),"mediaElement"in this.source&&this.source.mediaElement){const e=this.source.mediaElement;e.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 g=this.panner;g.disconnect(),g=this.applyFilters(g),g.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(g){return this.outputNode.connect(g)}disconnect(g){g?this.outputNode.disconnect(g):this.outputNode.disconnect()}clone(g={}){if(!this.source||!this.gainNode||!this.context)throw new Error("Cannot clone a sound that has been cleaned up");const e=g.panType||this.panType,t=this.context.createGain();let I;if("buffer"in this.source&&this.source.buffer)I=this.context.createBufferSource(),I.buffer=this.source.buffer;else if("mediaElement"in this.source&&this.source.mediaElement)I=this.context.createMediaElementSource(this.source.mediaElement);else throw new Error("Unsupported source type");const s=g.loopCount!==void 0?g.loopCount:this.loopCount,C=new Z(this.origin,I,t);return C.loopCount=s,C.currentLoop=this.currentLoop,C.setPanType(e,this.context),C.volume=this.volume,C.playbackRate=this._playbackRate,C._offset=this._offset,C._state=this._state,this._filters.forEach(i=>{const A=this.context.createBiquadFilter();A.type=i.type,A.frequency.value=i.frequency.value,A.Q.value=i.Q.value,A.gain.value=i.gain.value,C.addFilter(A)}),this._state===1&&C.play(),C}}class u extends H(p){constructor(g,e,t,I,s=B.Buffer,C="HRTF",i){super(),this.url=g,this.globalGainNode=I,this.soundType=s,this.panType=C,this._cacophony=i,this.buffer=e,this.context=t}buffer;context;loopCount=0;_playbackRate=1;eventEmitter=new y;get cacophony(){return this._cacophony}get volume(){return super.volume}on(g,e){this.eventEmitter.on(g,e)}off(g,e){this.eventEmitter.off(g,e)}emit(g,e){this.eventEmitter.emit(g,e)}async emitAsync(g,e){return this.eventEmitter.emitAsync(g,e)}clone(g={}){const e=g.panType||this.panType,t=g.stereoPan!==void 0?g.stereoPan:this.stereoPan,I=g.threeDOptions||this.threeDOptions,s=g.loopCount!==void 0?g.loopCount:this.loopCount,C=g.playbackRate||this.playbackRate,i=g.volume!==void 0?g.volume:this.volume,A=g.position!==void 0?g.position:this.position,o=g.filters&&g.filters.length?g.filters:this._filters,n=new u(this.url,this.buffer,this.context,this.globalGainNode,this.soundType,e,this.cacophony);return n.loop(s),n.playbackRate=C,n.volume=i,e==="HRTF"?(n.threeDOptions=I,n.position=A):n.stereoPan=t,n.addFilters(o),n}preplay(){try{let g;if(this.buffer)g=this.context.createBufferSource(),g.buffer=this.buffer;else{const I=new Audio;I.crossOrigin="anonymous",I.src=this.url,I.preload="auto",g=this.context.createMediaElementSource(I)}const e=this.context.createGain();e.connect(this.globalGainNode);const t=new Z(this,g,e);return t.setGainNode(e),t.volume=this.volume,t.playbackRate=this.playbackRate,this._filters.forEach(I=>t.addFilter(I)),this.panType==="HRTF"?(t.threeDOptions=this.threeDOptions,t.position=this.position):this.panType==="stereo"&&(t.stereoPan=this.stereoPan),t.on("error",I=>{this.emitAsync("soundError",{url:this.url,error:I.error,errorType:"playback",timestamp:I.timestamp,recoverable:I.recoverable})}),this.playbacks.push(t),[t]}catch(g){const e={url:this.url,error:g,errorType:"playback",timestamp:Date.now(),recoverable:!0};throw this.emitAsync("soundError",e),g}}play(){const g=super.play();return this.emit("play",g[0]),g}stop(){super.stop(),this.emit("stop",void 0)}pause(){super.pause(),this.emit("pause",void 0)}seek(g){this.playbacks.forEach(e=>e.seek(g))}get duration(){return this.playbacks.length>0?this.playbacks[0].duration:this.buffer?.duration||NaN}loop(g){return g===void 0?this.loopCount:(this.loopCount=g,this.playbacks.forEach(e=>e.loop(g)),this.loopCount)}get playbackRate(){return this._playbackRate}set playbackRate(g){this._playbackRate=g,this.playbacks.forEach(e=>e.playbackRate=g),this.emit("rateChange",g)}set volume(g){super.volume=g,this.emit("volumeChange",g)}cleanup(){this.playbacks.forEach(g=>g.cleanup()),this.playbacks=[],this.eventEmitter.removeAllListeners()}}const P=(a,g)=>{var e=new Uint8Array(a.byteLength+g.byteLength);return e.set(new Uint8Array(a),0),e.set(new Uint8Array(g),a.byteLength),e.buffer};function M(a,g,e){const t=[];let I=0,s;if(e?.aborted){console.error("Stream error:",new DOMException("Operation was aborted","AbortError"));return}fetch(a,e?{signal:e}:void 0).then(function(i){if(!i.ok)throw new Error("HTTP error, status = "+i.status);if(!i.body)throw new Error("Missing body");s=i.body.getReader();let A=new ArrayBuffer(0);const o=()=>{t.length=0,s&&s.cancel("Stream aborted").catch(()=>{})};e?.addEventListener("abort",o);function n(){return e?.aborted?(o(),Promise.resolve()):s.read().then(({value:c,done:h})=>{if(e?.aborted){o();return}let d=null;if(c){if(A.byteLength?d=P(A,c.buffer):(A=c.buffer.slice(0,44),d=c.buffer),g.decodeAudioData(d,function(m){e?.aborted||(t.push(m),t.length&&C())},function(m){console.log("err(decodeAudioData): "+m)}),h){console.log("done"),e?.removeEventListener("abort",o);return}n()}}).catch(c=>{e?.aborted||c.name==="AbortError"||console.error("Stream read error:",c)})}n()}).catch(function(i){console.error("Stream error:",i)});function C(){for(;t.length;){let i=t.shift();const A=g.createBufferSource();if(!i)return;A.buffer=i,A.connect(g.destination),I==0&&(I=g.currentTime+.02),A.start(I),I+=A.buffer.duration}}}function z(a){class g extends F{_oscillatorOptions={};get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(t){this._oscillatorOptions=t,this.source&&this.source instanceof OscillatorNode&&(this.oscillatorOptions.detune&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency&&(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&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency&&(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&&this.source.stop&&(this.source.stop(),this._playing=!1)}pause(){this.stop()}get frequency(){return this.source.frequency.value}set frequency(t){this.source.frequency.value=t,this.oscillatorOptions.frequency=t}get detune(){return this.source.detune.value}set detune(t){this.source.detune.value=t,this.oscillatorOptions.detune=t}get type(){return this.source.type}set type(t){this.source.type=t,this.oscillatorOptions.type=t}}return g}class T extends z(K(W(p))){constructor(g,e,t){super(),this.origin=g,this.source=e,this.context=g.context,this.setPanType(g.panType,g.context),this.source.connect(this.panner),this.setGainNode(t),this.panner.connect(this.gainNode),this.refreshFilters()}context;refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let g=this.panner;g.disconnect(),g=this.applyFilters(g),g.connect(this.gainNode)}cleanup(){this.panner&&this.gainNode&&(this.source.disconnect(this.panner),this.panner.disconnect(),this.gainNode.disconnect()),this.eventEmitter.removeAllListeners()}}class G extends H(p){constructor(g,e,t=B.Oscillator,I="HRTF",s={},C){super(),this.context=g,this.globalGainNode=e,this.soundType=t,this.panType=I,this.cacophony=C,this.context=g,this._oscillatorOptions=s}_oscillatorOptions;playbacks=[];eventEmitter=new y;on(g,e){this.eventEmitter.on(g,e)}off(g,e){this.eventEmitter.off(g,e)}emit(g,e){this.eventEmitter.emit(g,e)}async emitAsync(g,e){return this.eventEmitter.emitAsync(g,e)}clone(g={}){const e=g.panType||this.panType,t=g.stereoPan!==void 0?g.stereoPan:this.stereoPan??0,I=g.threeDOptions||this.threeDOptions,s=g.volume!==void 0?g.volume:this.volume,C=g.position&&g.position.length?g.position:this.position,i=g.filters&&g.filters.length?g.filters:this._filters,A=g.oscillatorOptions||this._oscillatorOptions,o=new G(this.context,this.globalGainNode,this.soundType,e,A,this.cacophony);return o._volume=s,o._position=C,o._stereoPan=t,o._threeDOptions=I,o.addFilters(i),o}preplay(){const g=this.context.createOscillator();return this.createPlayback(g)}createPlayback(g){this.oscillatorOptions.detune&&(g.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency&&(g.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(g.type=this.oscillatorOptions.type);const e=this.context.createGain();e.connect(this.globalGainNode);const t=new T(this,g,e);return t.volume=this.volume,this._filters.forEach(I=>t.addFilter(I)),this.panType==="HRTF"?(t.threeDOptions=this.threeDOptions,t.position=this.position):this.panType==="stereo"&&(t.stereoPan=this.stereoPan),this.playbacks.push(t),[t]}play(){const g=super.play();return this.emit("play",g[0]),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()}),g}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()})}get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(g){this._oscillatorOptions=g,this.playbacks.forEach(e=>{e.source instanceof OscillatorNode&&(this.oscillatorOptions.detune&&(e.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency&&(e.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(e.source.type=this.oscillatorOptions.type))})}get frequency(){return this.oscillatorOptions.frequency||440}set frequency(g){this._oscillatorOptions.frequency=g,this.playbacks.forEach(e=>e.frequency=g),this.emit("frequencyChange",g)}get detune(){return this.oscillatorOptions.detune}set detune(g){this._oscillatorOptions.detune=g,this.playbacks.forEach(e=>e.detune=g),this.emit("detuneChange",g)}get type(){return this.oscillatorOptions.type||"sine"}set type(g){this._oscillatorOptions.type=g,this.playbacks.forEach(e=>e.type=g),this.emit("typeChange",g)}}var B=(a=>(a.HTML="HTML",a.Streaming="Streaming",a.Buffer="Buffer",a.Oscillator="oscillator",a))(B||{});class Q{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;eventEmitter=new y;cache;constructor(g,e){this.context=g||new f.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.cache=e||new r,this.finalizationRegistry=new FinalizationRegistry(t=>{t.cleanup()})}on(g,e){this.eventEmitter.on(g,e)}off(g,e){this.eventEmitter.off(g,e)}emit(g,e){this.eventEmitter.emit(g,e)}async emitAsync(g,e){return this.eventEmitter.emitAsync(g,e)}async loadWorklets(g){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",Y,g):console.warn("AudioWorklet not supported")}async createWorkletNode(g,e,t){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new f.AudioWorkletNode(this.context,g)}catch(I){console.error(I),console.log("Loading worklet from url",e);try{await this.context.audioWorklet.addModule(e,{credentials:"same-origin",...t&&{signal:t}})}catch(s){throw console.error(s),s}return new f.AudioWorkletNode(this.context,g)}}clearMemoryCache(){this.cache.clearMemoryCache()}createOscillator(g,e="HRTF"){return new G(this.context,this.globalGainNode,"oscillator",e,g,this)}async createSound(g,e="Buffer",t="HRTF",I){if(typeof g=="object")return Promise.resolve(new u("",g,this.context,this.globalGainNode,"Buffer",t,this));const s=g;if(e==="HTML"){const C=new Audio;return C.src=s,C.crossOrigin="anonymous",Promise.resolve(new u(s,void 0,this.context,this.globalGainNode,"HTML",t,this))}return e==="Streaming"?Promise.resolve(new u(s,void 0,this.context,this.globalGainNode,"Streaming",t,this)):this.cache.getAudioBuffer(this.context,s,I,{onLoadingStart:C=>this.emitAsync("loadingStart",C),onLoadingProgress:C=>this.emitAsync("loadingProgress",C),onLoadingComplete:C=>this.emitAsync("loadingComplete",C),onLoadingError:C=>this.emitAsync("loadingError",C),onCacheHit:C=>this.emitAsync("cacheHit",C),onCacheMiss:C=>this.emitAsync("cacheMiss",C),onCacheError:C=>this.emitAsync("cacheError",C)}).then(C=>new u(s,C,this.context,this.globalGainNode,e,t,this))}async createGroup(g){const e=new X;return g.forEach(t=>e.addSound(t)),e}async createGroupFromUrls(g,e="Buffer",t="HRTF",I){const s=new X;return(await Promise.all(g.map(i=>this.createSound(i,e,t,I)))).forEach(i=>s.addSound(i)),s}async createStream(g,e){return M(g,this.context,e),new u(g,void 0,this.context,this.globalGainNode,"Streaming","HRTF",this)}createBiquadFilter=({type:g,frequency:e,gain:t,Q:I})=>{e===void 0&&(e=350);const s=this.context.createBiquadFilter();return s.type=g||"lowpass",s.frequency.value=e,s.gain.value=t||0,s.Q.value=I||1,s};createPanner({coneInnerAngle:g,coneOuterAngle:e,coneOuterGain:t,distanceModel:I,maxDistance:s,channelCount:C,channelCountMode:i,channelInterpretation:A,panningModel:o,refDistance:n,rolloffFactor:c,positionX:h,positionY:d,positionZ:m,orientationX:b,orientationY:V,orientationZ:k}){const l=this.context.createPanner();return l.coneInnerAngle=g||360,l.coneOuterAngle=e||360,l.coneOuterGain=t||0,l.distanceModel=I||"inverse",l.maxDistance=s||1e4,l.channelCount=C||2,l.channelCountMode=i||"clamped-max",l.channelInterpretation=A||"speakers",l.panningModel=o||"HRTF",l.refDistance=n||1,l.rolloffFactor=c||1,l.positionX.value=h||0,l.positionY.value=d||0,l.positionZ.value=m||0,l.orientationX.value=b||0,l.orientationY.value=V||0,l.orientationZ.value=k||0,l}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(g){this.globalGainNode.gain.value=g}get volume(){return this.globalGainNode.gain.value}set volume(g){if(this.muted){this.prevVolume=g;return}this.setGlobalVolume(g)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(g){g!==this.muted&&(g?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((g,e)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(t=>{const I=new N(this.context);I.play(),g(I)}).catch(t=>{e(t)})})}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(g){const{forward:e,up:t}=g,[I,s,C]=e,[i,A,o]=t;this.listener.forwardX.value=I,this.listener.forwardY.value=s,this.listener.forwardZ.value=C,this.listener.upX.value=i,this.listener.upY.value=A,this.listener.upZ.value=o}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(g){const[e,t,I]=g;this.listener.upX.value=e,this.listener.upY.value=t,this.listener.upZ.value=I}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(g){const[e,t,I]=g;this.listener.forwardX.value=e,this.listener.forwardY.value=t,this.listener.forwardZ.value=I}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(g){const[e,t,I]=g,s=this.context.currentTime;this.listener.positionX.setValueAtTime(e,s),this.listener.positionY.setValueAtTime(t,s),this.listener.positionZ.setValueAtTime(I,s)}}class J{constructor(g=[]){this.synths=g}addSynth(g){this.synths.push(g)}removeSynth(g){const e=this.synths.indexOf(g);if(e!==-1)this.synths.splice(e,1);else throw new Error("Synth not found in group")}play(){this.synths.forEach(g=>g.play())}stop(){this.synths.forEach(g=>g.stop())}setVolume(g){this.synths.forEach(e=>e.volume=g)}set stereoPan(g){this.synths.forEach(e=>e.stereoPan=g)}set position(g){this.synths.forEach(e=>e.position=g)}}exports.Cacophony=Q;exports.Group=X;exports.MicrophonePlayback=v;exports.Playback=Z;exports.Sound=u;exports.SoundType=B;exports.Synth=G;exports.SynthGroup=J;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const V=require("standardized-audio-context"),E="data:text/javascript;base64,dmFyIHBoYXNlVm9jb2RlciA9IChmdW5jdGlvbiAoZXhwb3J0cykgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIGNvbnN0IFdFQkFVRElPX0JMT0NLX1NJWkUgPSAxMjg7CiAgICBjb25zdCBERUZBVUxUX0JMT0NLX1NJWkUgPSAxMDI0OyAvLyBEZWZhdWx0IGJsb2NrIHNpemUgaWYgbm90IHByb3ZpZGVkIGluIG9wdGlvbnMKICAgIC8qKiBPdmVybGFwLUFkZCBOb2RlICovCiAgICBjbGFzcyBPTEFQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgewogICAgICAgIG5iSW5wdXRzOwogICAgICAgIG5iT3V0cHV0czsKICAgICAgICBibG9ja1NpemU7CiAgICAgICAgaG9wU2l6ZTsKICAgICAgICBuYk92ZXJsYXBzOwogICAgICAgIGlucHV0QnVmZmVycyA9IFtdOwogICAgICAgIGlucHV0QnVmZmVyc0hlYWQgPSBbXTsKICAgICAgICBpbnB1dEJ1ZmZlcnNUb1NlbmQgPSBbXTsKICAgICAgICBvdXRwdXRCdWZmZXJzID0gW107CiAgICAgICAgb3V0cHV0QnVmZmVyc1RvUmV0cmlldmUgPSBbXTsKICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIHN1cGVyKG9wdGlvbnMpOwogICAgICAgICAgICB0aGlzLm5iSW5wdXRzID0gb3B0aW9ucy5udW1iZXJPZklucHV0cyB8fCAxOwogICAgICAgICAgICB0aGlzLm5iT3V0cHV0cyA9IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzIHx8IDE7CiAgICAgICAgICAgIHRoaXMuYmxvY2tTaXplID0gb3B0aW9ucy5wcm9jZXNzb3JPcHRpb25zLmJsb2NrU2l6ZSB8fCBERUZBVUxUX0JMT0NLX1NJWkU7CiAgICAgICAgICAgIHRoaXMuaG9wU2l6ZSA9IFdFQkFVRElPX0JMT0NLX1NJWkU7CiAgICAgICAgICAgIHRoaXMubmJPdmVybGFwcyA9IE1hdGguZmxvb3IodGhpcy5ibG9ja1NpemUgLyB0aGlzLmhvcFNpemUpOwogICAgICAgICAgICB0aGlzLmluaXRpYWxpemVCdWZmZXJzKCk7CiAgICAgICAgfQogICAgICAgIGluaXRpYWxpemVCdWZmZXJzKCkgewogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVycyA9IG5ldyBBcnJheSh0aGlzLm5iSW5wdXRzKTsKICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1RvU2VuZCA9IG5ldyBBcnJheSh0aGlzLm5iSW5wdXRzKTsKICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IG5ldyBBcnJheSh0aGlzLm5iT3V0cHV0cyk7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlSW5wdXRDaGFubmVscyhpLCAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJPdXRwdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVPdXRwdXRDaGFubmVscyhpLCAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhbGxvY2F0ZUlucHV0Q2hhbm5lbHMoaW5wdXRJbmRleCwgbmJDaGFubmVscykgewogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XSA9IG5ldyBBcnJheShuYkNoYW5uZWxzKTsKICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1RvU2VuZFtpbnB1dEluZGV4XSA9IG5ldyBBcnJheShuYkNoYW5uZWxzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYkNoYW5uZWxzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdW2ldID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJsb2NrU2l6ZSArIFdFQkFVRElPX0JMT0NLX1NJWkUpOwogICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uZmlsbCgwKTsKICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzSGVhZFtpbnB1dEluZGV4XVtpXSA9IHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdW2ldLnN1YmFycmF5KDAsIHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdW2ldID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYWxsb2NhdGVPdXRwdXRDaGFubmVscyhvdXRwdXRJbmRleCwgbmJDaGFubmVscykgewogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwogICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlW291dHB1dEluZGV4XSA9IG5ldyBBcnJheShuYkNoYW5uZWxzKTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYkNoYW5uZWxzOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF1baV0uZmlsbCgwKTsKICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdW2ldID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmJsb2NrU2l6ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVhbGxvY2F0ZUNoYW5uZWxzSWZOZWVkZWQoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBsZXQgbmJDaGFubmVscyA9IGlucHV0c1tpXS5sZW5ndGg7CiAgICAgICAgICAgICAgICBpZiAobmJDaGFubmVscyAhPT0gdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZUlucHV0Q2hhbm5lbHMoaSwgbmJDaGFubmVscyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBsZXQgbmJDaGFubmVscyA9IG91dHB1dHNbaV0ubGVuZ3RoOwogICAgICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlT3V0cHV0Q2hhbm5lbHMoaSwgbmJDaGFubmVscyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVhZElucHV0cyhpbnB1dHMpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBsZXQgd2ViQXVkaW9CbG9jayA9IGlucHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpXVtqXS5zZXQod2ViQXVkaW9CbG9jaywgdGhpcy5ibG9ja1NpemUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHdyaXRlT3V0cHV0cyhvdXRwdXRzKSB7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewogICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBsZXQgd2ViQXVkaW9CbG9jayA9IG91dHB1dHNbaV1bal07CiAgICAgICAgICAgICAgICAgICAgd2ViQXVkaW9CbG9jay5zZXQodGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdLnN1YmFycmF5KDAsIFdFQkFVRElPX0JMT0NLX1NJWkUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzaGlmdElucHV0QnVmZmVycygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpXVtqXS5jb3B5V2l0aGluKDAsIFdFQkFVRElPX0JMT0NLX1NJWkUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHNoaWZ0T3V0cHV0QnVmZmVycygpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXS5jb3B5V2l0aGluKDAsIFdFQkFVRElPX0JMT0NLX1NJWkUpOwogICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXS5maWxsKDAsIHRoaXMuYmxvY2tTaXplIC0gV0VCQVVESU9fQkxPQ0tfU0laRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJlcGFyZUlucHV0QnVmZmVyc1RvU2VuZCgpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1RvU2VuZFtpXVtqXS5zZXQodGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2ldW2pdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBoYW5kbGVPdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSgpIHsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgdGhpcy5ibG9ja1NpemU7IGsrKykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal1ba10gKz0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbaV1bal1ba10gLyB0aGlzLm5iT3ZlcmxhcHM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CiAgICAgICAgICAgIHRoaXMucmVhbGxvY2F0ZUNoYW5uZWxzSWZOZWVkZWQoaW5wdXRzLCBvdXRwdXRzKTsKICAgICAgICAgICAgdGhpcy5yZWFkSW5wdXRzKGlucHV0cyk7CiAgICAgICAgICAgIHRoaXMuc2hpZnRJbnB1dEJ1ZmZlcnMoKTsKICAgICAgICAgICAgdGhpcy5wcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCk7CiAgICAgICAgICAgIHRoaXMucHJvY2Vzc09MQSh0aGlzLmlucHV0QnVmZmVyc1RvU2VuZCwgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSwgcGFyYW1ldGVycyk7CiAgICAgICAgICAgIHRoaXMuaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKTsKICAgICAgICAgICAgdGhpcy53cml0ZU91dHB1dHMob3V0cHV0cyk7CiAgICAgICAgICAgIHRoaXMuc2hpZnRPdXRwdXRCdWZmZXJzKCk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBnZXREZWZhdWx0RXhwb3J0RnJvbUNqcyAoeCkgewogICAgCXJldHVybiB4ICYmIHguX19lc01vZHVsZSAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ2RlZmF1bHQnKSA/IHhbJ2RlZmF1bHQnXSA6IHg7CiAgICB9CgogICAgZnVuY3Rpb24gRkZUKHNpemUpIHsKICAgICAgdGhpcy5zaXplID0gc2l6ZSB8IDA7CiAgICAgIGlmICh0aGlzLnNpemUgPD0gMSB8fCAodGhpcy5zaXplICYgKHRoaXMuc2l6ZSAtIDEpKSAhPT0gMCkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZGVCBzaXplIG11c3QgYmUgYSBwb3dlciBvZiB0d28gYW5kIGJpZ2dlciB0aGFuIDEnKTsKCiAgICAgIHRoaXMuX2NzaXplID0gc2l6ZSA8PCAxOwoKICAgICAgLy8gTk9URTogVXNlIG9mIGB2YXJgIGlzIGludGVudGlvbmFsIGZvciBvbGQgVjggdmVyc2lvbnMKICAgICAgdmFyIHRhYmxlID0gbmV3IEFycmF5KHRoaXMuc2l6ZSAqIDIpOwogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRhYmxlLmxlbmd0aDsgaSArPSAyKSB7CiAgICAgICAgY29uc3QgYW5nbGUgPSBNYXRoLlBJICogaSAvIHRoaXMuc2l6ZTsKICAgICAgICB0YWJsZVtpXSA9IE1hdGguY29zKGFuZ2xlKTsKICAgICAgICB0YWJsZVtpICsgMV0gPSAtTWF0aC5zaW4oYW5nbGUpOwogICAgICB9CiAgICAgIHRoaXMudGFibGUgPSB0YWJsZTsKCiAgICAgIC8vIEZpbmQgc2l6ZSdzIHBvd2VyIG9mIHR3bwogICAgICB2YXIgcG93ZXIgPSAwOwogICAgICBmb3IgKHZhciB0ID0gMTsgdGhpcy5zaXplID4gdDsgdCA8PD0gMSkKICAgICAgICBwb3dlcisrOwoKICAgICAgLy8gQ2FsY3VsYXRlIGluaXRpYWwgc3RlcCdzIHdpZHRoOgogICAgICAvLyAgICogSWYgd2UgYXJlIGZ1bGwgcmFkaXgtNCAtIGl0IGlzIDJ4IHNtYWxsZXIgdG8gZ2l2ZSBpbml0YWwgbGVuPTgKICAgICAgLy8gICAqIE90aGVyd2lzZSBpdCBpcyB0aGUgc2FtZSBhcyBgcG93ZXJgIHRvIGdpdmUgbGVuPTQKICAgICAgdGhpcy5fd2lkdGggPSBwb3dlciAlIDIgPT09IDAgPyBwb3dlciAtIDEgOiBwb3dlcjsKCiAgICAgIC8vIFByZS1jb21wdXRlIGJpdC1yZXZlcnNhbCBwYXR0ZXJucwogICAgICB0aGlzLl9iaXRyZXYgPSBuZXcgQXJyYXkoMSA8PCB0aGlzLl93aWR0aCk7CiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5fYml0cmV2Lmxlbmd0aDsgaisrKSB7CiAgICAgICAgdGhpcy5fYml0cmV2W2pdID0gMDsKICAgICAgICBmb3IgKHZhciBzaGlmdCA9IDA7IHNoaWZ0IDwgdGhpcy5fd2lkdGg7IHNoaWZ0ICs9IDIpIHsKICAgICAgICAgIHZhciByZXZTaGlmdCA9IHRoaXMuX3dpZHRoIC0gc2hpZnQgLSAyOwogICAgICAgICAgdGhpcy5fYml0cmV2W2pdIHw9ICgoaiA+Pj4gc2hpZnQpICYgMykgPDwgcmV2U2hpZnQ7CiAgICAgICAgfQogICAgICB9CgogICAgICB0aGlzLl9vdXQgPSBudWxsOwogICAgICB0aGlzLl9kYXRhID0gbnVsbDsKICAgICAgdGhpcy5faW52ID0gMDsKICAgIH0KICAgIHZhciBmZnQgPSBGRlQ7CgogICAgRkZULnByb3RvdHlwZS5mcm9tQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gZnJvbUNvbXBsZXhBcnJheShjb21wbGV4LCBzdG9yYWdlKSB7CiAgICAgIHZhciByZXMgPSBzdG9yYWdlIHx8IG5ldyBBcnJheShjb21wbGV4Lmxlbmd0aCA+Pj4gMSk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29tcGxleC5sZW5ndGg7IGkgKz0gMikKICAgICAgICByZXNbaSA+Pj4gMV0gPSBjb21wbGV4W2ldOwogICAgICByZXR1cm4gcmVzOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLmNyZWF0ZUNvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIGNyZWF0ZUNvbXBsZXhBcnJheSgpIHsKICAgICAgY29uc3QgcmVzID0gbmV3IEFycmF5KHRoaXMuX2NzaXplKTsKICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpKyspCiAgICAgICAgcmVzW2ldID0gMDsKICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS50b0NvbXBsZXhBcnJheSA9IGZ1bmN0aW9uIHRvQ29tcGxleEFycmF5KGlucHV0LCBzdG9yYWdlKSB7CiAgICAgIHZhciByZXMgPSBzdG9yYWdlIHx8IHRoaXMuY3JlYXRlQ29tcGxleEFycmF5KCk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSArPSAyKSB7CiAgICAgICAgcmVzW2ldID0gaW5wdXRbaSA+Pj4gMV07CiAgICAgICAgcmVzW2kgKyAxXSA9IDA7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlczsKICAgIH07CgogICAgRkZULnByb3RvdHlwZS5jb21wbGV0ZVNwZWN0cnVtID0gZnVuY3Rpb24gY29tcGxldGVTcGVjdHJ1bShzcGVjdHJ1bSkgewogICAgICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwogICAgICB2YXIgaGFsZiA9IHNpemUgPj4+IDE7CiAgICAgIGZvciAodmFyIGkgPSAyOyBpIDwgaGFsZjsgaSArPSAyKSB7CiAgICAgICAgc3BlY3RydW1bc2l6ZSAtIGldID0gc3BlY3RydW1baV07CiAgICAgICAgc3BlY3RydW1bc2l6ZSAtIGkgKyAxXSA9IC1zcGVjdHJ1bVtpICsgMV07CiAgICAgIH0KICAgIH07CgogICAgRkZULnByb3RvdHlwZS50cmFuc2Zvcm0gPSBmdW5jdGlvbiB0cmFuc2Zvcm0ob3V0LCBkYXRhKSB7CiAgICAgIGlmIChvdXQgPT09IGRhdGEpCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgbXVzdCBiZSBkaWZmZXJlbnQnKTsKCiAgICAgIHRoaXMuX291dCA9IG91dDsKICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICAgIHRoaXMuX3RyYW5zZm9ybTQoKTsKICAgICAgdGhpcy5fb3V0ID0gbnVsbDsKICAgICAgdGhpcy5fZGF0YSA9IG51bGw7CiAgICB9OwoKICAgIEZGVC5wcm90b3R5cGUucmVhbFRyYW5zZm9ybSA9IGZ1bmN0aW9uIHJlYWxUcmFuc2Zvcm0ob3V0LCBkYXRhKSB7CiAgICAgIGlmIChvdXQgPT09IGRhdGEpCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgbXVzdCBiZSBkaWZmZXJlbnQnKTsKCiAgICAgIHRoaXMuX291dCA9IG91dDsKICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7CiAgICAgIHRoaXMuX2ludiA9IDA7CiAgICAgIHRoaXMuX3JlYWxUcmFuc2Zvcm00KCk7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICBGRlQucHJvdG90eXBlLmludmVyc2VUcmFuc2Zvcm0gPSBmdW5jdGlvbiBpbnZlcnNlVHJhbnNmb3JtKG91dCwgZGF0YSkgewogICAgICBpZiAob3V0ID09PSBkYXRhKQogICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgYW5kIG91dHB1dCBidWZmZXJzIG11c3QgYmUgZGlmZmVyZW50Jyk7CgogICAgICB0aGlzLl9vdXQgPSBvdXQ7CiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhOwogICAgICB0aGlzLl9pbnYgPSAxOwogICAgICB0aGlzLl90cmFuc2Zvcm00KCk7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3V0Lmxlbmd0aDsgaSsrKQogICAgICAgIG91dFtpXSAvPSB0aGlzLnNpemU7CiAgICAgIHRoaXMuX291dCA9IG51bGw7CiAgICAgIHRoaXMuX2RhdGEgPSBudWxsOwogICAgfTsKCiAgICAvLyByYWRpeC00IGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogVXNlcyBvZiBgdmFyYCBhcmUgaW50ZW50aW9uYWwgZm9yIG9sZGVyIFY4IHZlcnNpb24gdGhhdCBkbyBub3QKICAgIC8vIHN1cHBvcnQgYm90aCBgbGV0IGNvbXBvdW5kIGFzc2lnbm1lbnRzYCBhbmQgYGNvbnN0IHBoaWAKICAgIEZGVC5wcm90b3R5cGUuX3RyYW5zZm9ybTQgPSBmdW5jdGlvbiBfdHJhbnNmb3JtNCgpIHsKICAgICAgdmFyIG91dCA9IHRoaXMuX291dDsKICAgICAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKCiAgICAgIC8vIEluaXRpYWwgc3RlcCAocGVybXV0ZSBhbmQgdHJhbnNmb3JtKQogICAgICB2YXIgd2lkdGggPSB0aGlzLl93aWR0aDsKICAgICAgdmFyIHN0ZXAgPSAxIDw8IHdpZHRoOwogICAgICB2YXIgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwoKICAgICAgdmFyIG91dE9mZjsKICAgICAgdmFyIHQ7CiAgICAgIHZhciBiaXRyZXYgPSB0aGlzLl9iaXRyZXY7CiAgICAgIGlmIChsZW4gPT09IDQpIHsKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVRyYW5zZm9ybTIob3V0T2ZmLCBvZmYsIHN0ZXApOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBsZW4gPT09IDgKICAgICAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKICAgICAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKICAgICAgICAgIHRoaXMuX3NpbmdsZVRyYW5zZm9ybTQob3V0T2ZmLCBvZmYsIHN0ZXApOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gTG9vcCB0aHJvdWdoIHN0ZXBzIGluIGRlY3JlYXNpbmcgb3JkZXIKICAgICAgdmFyIGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgdmFyIHRhYmxlID0gdGhpcy50YWJsZTsKICAgICAgZm9yIChzdGVwID4+PSAyOyBzdGVwID49IDI7IHN0ZXAgPj49IDIpIHsKICAgICAgICBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CiAgICAgICAgdmFyIHF1YXJ0ZXJMZW4gPSBsZW4gPj4+IDI7CgogICAgICAgIC8vIExvb3AgdGhyb3VnaCBvZmZzZXRzIGluIHRoZSBkYXRhCiAgICAgICAgZm9yIChvdXRPZmYgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuKSB7CiAgICAgICAgICAvLyBGdWxsIGNhc2UKICAgICAgICAgIHZhciBsaW1pdCA9IG91dE9mZiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICBmb3IgKHZhciBpID0gb3V0T2ZmLCBrID0gMDsgaSA8IGxpbWl0OyBpICs9IDIsIGsgKz0gc3RlcCkgewogICAgICAgICAgICBjb25zdCBBID0gaTsKICAgICAgICAgICAgY29uc3QgQiA9IEEgKyBxdWFydGVyTGVuOwogICAgICAgICAgICBjb25zdCBDID0gQiArIHF1YXJ0ZXJMZW47CiAgICAgICAgICAgIGNvbnN0IEQgPSBDICsgcXVhcnRlckxlbjsKCiAgICAgICAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICAgICAgICBjb25zdCBBciA9IG91dFtBXTsKICAgICAgICAgICAgY29uc3QgQWkgPSBvdXRbQSArIDFdOwogICAgICAgICAgICBjb25zdCBCciA9IG91dFtCXTsKICAgICAgICAgICAgY29uc3QgQmkgPSBvdXRbQiArIDFdOwogICAgICAgICAgICBjb25zdCBDciA9IG91dFtDXTsKICAgICAgICAgICAgY29uc3QgQ2kgPSBvdXRbQyArIDFdOwogICAgICAgICAgICBjb25zdCBEciA9IG91dFtEXTsKICAgICAgICAgICAgY29uc3QgRGkgPSBvdXRbRCArIDFdOwoKICAgICAgICAgICAgLy8gTWlkZGxlIHZhbHVlcwogICAgICAgICAgICBjb25zdCBNQXIgPSBBcjsKICAgICAgICAgICAgY29uc3QgTUFpID0gQWk7CgogICAgICAgICAgICBjb25zdCB0YWJsZUJyID0gdGFibGVba107CiAgICAgICAgICAgIGNvbnN0IHRhYmxlQmkgPSBpbnYgKiB0YWJsZVtrICsgMV07CiAgICAgICAgICAgIGNvbnN0IE1CciA9IEJyICogdGFibGVCciAtIEJpICogdGFibGVCaTsKICAgICAgICAgICAgY29uc3QgTUJpID0gQnIgKiB0YWJsZUJpICsgQmkgKiB0YWJsZUJyOwoKICAgICAgICAgICAgY29uc3QgdGFibGVDciA9IHRhYmxlWzIgKiBrXTsKICAgICAgICAgICAgY29uc3QgdGFibGVDaSA9IGludiAqIHRhYmxlWzIgKiBrICsgMV07CiAgICAgICAgICAgIGNvbnN0IE1DciA9IENyICogdGFibGVDciAtIENpICogdGFibGVDaTsKICAgICAgICAgICAgY29uc3QgTUNpID0gQ3IgKiB0YWJsZUNpICsgQ2kgKiB0YWJsZUNyOwoKICAgICAgICAgICAgY29uc3QgdGFibGVEciA9IHRhYmxlWzMgKiBrXTsKICAgICAgICAgICAgY29uc3QgdGFibGVEaSA9IGludiAqIHRhYmxlWzMgKiBrICsgMV07CiAgICAgICAgICAgIGNvbnN0IE1EciA9IERyICogdGFibGVEciAtIERpICogdGFibGVEaTsKICAgICAgICAgICAgY29uc3QgTURpID0gRHIgKiB0YWJsZURpICsgRGkgKiB0YWJsZURyOwoKICAgICAgICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwogICAgICAgICAgICBjb25zdCBUMHIgPSBNQXIgKyBNQ3I7CiAgICAgICAgICAgIGNvbnN0IFQwaSA9IE1BaSArIE1DaTsKICAgICAgICAgICAgY29uc3QgVDFyID0gTUFyIC0gTUNyOwogICAgICAgICAgICBjb25zdCBUMWkgPSBNQWkgLSBNQ2k7CiAgICAgICAgICAgIGNvbnN0IFQyciA9IE1CciArIE1EcjsKICAgICAgICAgICAgY29uc3QgVDJpID0gTUJpICsgTURpOwogICAgICAgICAgICBjb25zdCBUM3IgPSBpbnYgKiAoTUJyIC0gTURyKTsKICAgICAgICAgICAgY29uc3QgVDNpID0gaW52ICogKE1CaSAtIE1EaSk7CgogICAgICAgICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwogICAgICAgICAgICBjb25zdCBGQWkgPSBUMGkgKyBUMmk7CgogICAgICAgICAgICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CiAgICAgICAgICAgIGNvbnN0IEZDaSA9IFQwaSAtIFQyaTsKCiAgICAgICAgICAgIGNvbnN0IEZCciA9IFQxciArIFQzaTsKICAgICAgICAgICAgY29uc3QgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgICAgICAgY29uc3QgRkRyID0gVDFyIC0gVDNpOwogICAgICAgICAgICBjb25zdCBGRGkgPSBUMWkgKyBUM3I7CgogICAgICAgICAgICBvdXRbQV0gPSBGQXI7CiAgICAgICAgICAgIG91dFtBICsgMV0gPSBGQWk7CiAgICAgICAgICAgIG91dFtCXSA9IEZCcjsKICAgICAgICAgICAgb3V0W0IgKyAxXSA9IEZCaTsKICAgICAgICAgICAgb3V0W0NdID0gRkNyOwogICAgICAgICAgICBvdXRbQyArIDFdID0gRkNpOwogICAgICAgICAgICBvdXRbRF0gPSBGRHI7CiAgICAgICAgICAgIG91dFtEICsgMV0gPSBGRGk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9OwoKICAgIC8vIHJhZGl4LTIgaW1wbGVtZW50YXRpb24KICAgIC8vCiAgICAvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTQKICAgIEZGVC5wcm90b3R5cGUuX3NpbmdsZVRyYW5zZm9ybTIgPSBmdW5jdGlvbiBfc2luZ2xlVHJhbnNmb3JtMihvdXRPZmYsIG9mZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CgogICAgICBjb25zdCBldmVuUiA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgZXZlbkkgPSBkYXRhW29mZiArIDFdOwogICAgICBjb25zdCBvZGRSID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3Qgb2RkSSA9IGRhdGFbb2ZmICsgc3RlcCArIDFdOwoKICAgICAgY29uc3QgbGVmdFIgPSBldmVuUiArIG9kZFI7CiAgICAgIGNvbnN0IGxlZnRJID0gZXZlbkkgKyBvZGRJOwogICAgICBjb25zdCByaWdodFIgPSBldmVuUiAtIG9kZFI7CiAgICAgIGNvbnN0IHJpZ2h0SSA9IGV2ZW5JIC0gb2RkSTsKCiAgICAgIG91dFtvdXRPZmZdID0gbGVmdFI7CiAgICAgIG91dFtvdXRPZmYgKyAxXSA9IGxlZnRJOwogICAgICBvdXRbb3V0T2ZmICsgMl0gPSByaWdodFI7CiAgICAgIG91dFtvdXRPZmYgKyAzXSA9IHJpZ2h0STsKICAgIH07CgogICAgLy8gcmFkaXgtNAogICAgLy8KICAgIC8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49OAogICAgRkZULnByb3RvdHlwZS5fc2luZ2xlVHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF9zaW5nbGVUcmFuc2Zvcm00KG91dE9mZiwgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKICAgICAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwogICAgICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKICAgICAgY29uc3QgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwogICAgICBjb25zdCBzdGVwMiA9IHN0ZXAgKiAyOwogICAgICBjb25zdCBzdGVwMyA9IHN0ZXAgKiAzOwoKICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCiAgICAgIGNvbnN0IEFyID0gZGF0YVtvZmZdOwogICAgICBjb25zdCBBaSA9IGRhdGFbb2ZmICsgMV07CiAgICAgIGNvbnN0IEJyID0gZGF0YVtvZmYgKyBzdGVwXTsKICAgICAgY29uc3QgQmkgPSBkYXRhW29mZiArIHN0ZXAgKyAxXTsKICAgICAgY29uc3QgQ3IgPSBkYXRhW29mZiArIHN0ZXAyXTsKICAgICAgY29uc3QgQ2kgPSBkYXRhW29mZiArIHN0ZXAyICsgMV07CiAgICAgIGNvbnN0IERyID0gZGF0YVtvZmYgKyBzdGVwM107CiAgICAgIGNvbnN0IERpID0gZGF0YVtvZmYgKyBzdGVwMyArIDFdOwoKICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwogICAgICBjb25zdCBUMHIgPSBBciArIENyOwogICAgICBjb25zdCBUMGkgPSBBaSArIENpOwogICAgICBjb25zdCBUMXIgPSBBciAtIENyOwogICAgICBjb25zdCBUMWkgPSBBaSAtIENpOwogICAgICBjb25zdCBUMnIgPSBCciArIERyOwogICAgICBjb25zdCBUMmkgPSBCaSArIERpOwogICAgICBjb25zdCBUM3IgPSBpbnYgKiAoQnIgLSBEcik7CiAgICAgIGNvbnN0IFQzaSA9IGludiAqIChCaSAtIERpKTsKCiAgICAgIC8vIEZpbmFsIHZhbHVlcwogICAgICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CiAgICAgIGNvbnN0IEZBaSA9IFQwaSArIFQyaTsKCiAgICAgIGNvbnN0IEZCciA9IFQxciArIFQzaTsKICAgICAgY29uc3QgRkJpID0gVDFpIC0gVDNyOwoKICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwogICAgICBjb25zdCBGQ2kgPSBUMGkgLSBUMmk7CgogICAgICBjb25zdCBGRHIgPSBUMXIgLSBUM2k7CiAgICAgIGNvbnN0IEZEaSA9IFQxaSArIFQzcjsKCiAgICAgIG91dFtvdXRPZmZdID0gRkFyOwogICAgICBvdXRbb3V0T2ZmICsgMV0gPSBGQWk7CiAgICAgIG91dFtvdXRPZmYgKyAyXSA9IEZCcjsKICAgICAgb3V0W291dE9mZiArIDNdID0gRkJpOwogICAgICBvdXRbb3V0T2ZmICsgNF0gPSBGQ3I7CiAgICAgIG91dFtvdXRPZmYgKyA1XSA9IEZDaTsKICAgICAgb3V0W291dE9mZiArIDZdID0gRkRyOwogICAgICBvdXRbb3V0T2ZmICsgN10gPSBGRGk7CiAgICB9OwoKICAgIC8vIFJlYWwgaW5wdXQgcmFkaXgtNCBpbXBsZW1lbnRhdGlvbgogICAgRkZULnByb3RvdHlwZS5fcmVhbFRyYW5zZm9ybTQgPSBmdW5jdGlvbiBfcmVhbFRyYW5zZm9ybTQoKSB7CiAgICAgIHZhciBvdXQgPSB0aGlzLl9vdXQ7CiAgICAgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgogICAgICAvLyBJbml0aWFsIHN0ZXAgKHBlcm11dGUgYW5kIHRyYW5zZm9ybSkKICAgICAgdmFyIHdpZHRoID0gdGhpcy5fd2lkdGg7CiAgICAgIHZhciBzdGVwID0gMSA8PCB3aWR0aDsKICAgICAgdmFyIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCiAgICAgIHZhciBvdXRPZmY7CiAgICAgIHZhciB0OwogICAgICB2YXIgYml0cmV2ID0gdGhpcy5fYml0cmV2OwogICAgICBpZiAobGVuID09PSA0KSB7CiAgICAgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CiAgICAgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CiAgICAgICAgICB0aGlzLl9zaW5nbGVSZWFsVHJhbnNmb3JtMihvdXRPZmYsIG9mZiA+Pj4gMSwgc3RlcCA+Pj4gMSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIGxlbiA9PT0gOAogICAgICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewogICAgICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwogICAgICAgICAgdGhpcy5fc2luZ2xlUmVhbFRyYW5zZm9ybTQob3V0T2ZmLCBvZmYgPj4+IDEsIHN0ZXAgPj4+IDEpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gTG9vcCB0aHJvdWdoIHN0ZXBzIGluIGRlY3JlYXNpbmcgb3JkZXIKICAgICAgdmFyIGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgdmFyIHRhYmxlID0gdGhpcy50YWJsZTsKICAgICAgZm9yIChzdGVwID4+PSAyOyBzdGVwID49IDI7IHN0ZXAgPj49IDIpIHsKICAgICAgICBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CiAgICAgICAgdmFyIGhhbGZMZW4gPSBsZW4gPj4+IDE7CiAgICAgICAgdmFyIHF1YXJ0ZXJMZW4gPSBoYWxmTGVuID4+PiAxOwogICAgICAgIHZhciBocXVhcnRlckxlbiA9IHF1YXJ0ZXJMZW4gPj4+IDE7CgogICAgICAgIC8vIExvb3AgdGhyb3VnaCBvZmZzZXRzIGluIHRoZSBkYXRhCiAgICAgICAgZm9yIChvdXRPZmYgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuKSB7CiAgICAgICAgICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPD0gaHF1YXJ0ZXJMZW47IGkgKz0gMiwgayArPSBzdGVwKSB7CiAgICAgICAgICAgIHZhciBBID0gb3V0T2ZmICsgaTsKICAgICAgICAgICAgdmFyIEIgPSBBICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgdmFyIEMgPSBCICsgcXVhcnRlckxlbjsKICAgICAgICAgICAgdmFyIEQgPSBDICsgcXVhcnRlckxlbjsKCiAgICAgICAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICAgICAgICB2YXIgQXIgPSBvdXRbQV07CiAgICAgICAgICAgIHZhciBBaSA9IG91dFtBICsgMV07CiAgICAgICAgICAgIHZhciBCciA9IG91dFtCXTsKICAgICAgICAgICAgdmFyIEJpID0gb3V0W0IgKyAxXTsKICAgICAgICAgICAgdmFyIENyID0gb3V0W0NdOwogICAgICAgICAgICB2YXIgQ2kgPSBvdXRbQyArIDFdOwogICAgICAgICAgICB2YXIgRHIgPSBvdXRbRF07CiAgICAgICAgICAgIHZhciBEaSA9IG91dFtEICsgMV07CgogICAgICAgICAgICAvLyBNaWRkbGUgdmFsdWVzCiAgICAgICAgICAgIHZhciBNQXIgPSBBcjsKICAgICAgICAgICAgdmFyIE1BaSA9IEFpOwoKICAgICAgICAgICAgdmFyIHRhYmxlQnIgPSB0YWJsZVtrXTsKICAgICAgICAgICAgdmFyIHRhYmxlQmkgPSBpbnYgKiB0YWJsZVtrICsgMV07CiAgICAgICAgICAgIHZhciBNQnIgPSBCciAqIHRhYmxlQnIgLSBCaSAqIHRhYmxlQmk7CiAgICAgICAgICAgIHZhciBNQmkgPSBCciAqIHRhYmxlQmkgKyBCaSAqIHRhYmxlQnI7CgogICAgICAgICAgICB2YXIgdGFibGVDciA9IHRhYmxlWzIgKiBrXTsKICAgICAgICAgICAgdmFyIHRhYmxlQ2kgPSBpbnYgKiB0YWJsZVsyICogayArIDFdOwogICAgICAgICAgICB2YXIgTUNyID0gQ3IgKiB0YWJsZUNyIC0gQ2kgKiB0YWJsZUNpOwogICAgICAgICAgICB2YXIgTUNpID0gQ3IgKiB0YWJsZUNpICsgQ2kgKiB0YWJsZUNyOwoKICAgICAgICAgICAgdmFyIHRhYmxlRHIgPSB0YWJsZVszICoga107CiAgICAgICAgICAgIHZhciB0YWJsZURpID0gaW52ICogdGFibGVbMyAqIGsgKyAxXTsKICAgICAgICAgICAgdmFyIE1EciA9IERyICogdGFibGVEciAtIERpICogdGFibGVEaTsKICAgICAgICAgICAgdmFyIE1EaSA9IERyICogdGFibGVEaSArIERpICogdGFibGVEcjsKCiAgICAgICAgICAgIC8vIFByZS1GaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIFQwciA9IE1BciArIE1DcjsKICAgICAgICAgICAgdmFyIFQwaSA9IE1BaSArIE1DaTsKICAgICAgICAgICAgdmFyIFQxciA9IE1BciAtIE1DcjsKICAgICAgICAgICAgdmFyIFQxaSA9IE1BaSAtIE1DaTsKICAgICAgICAgICAgdmFyIFQyciA9IE1CciArIE1EcjsKICAgICAgICAgICAgdmFyIFQyaSA9IE1CaSArIE1EaTsKICAgICAgICAgICAgdmFyIFQzciA9IGludiAqIChNQnIgLSBNRHIpOwogICAgICAgICAgICB2YXIgVDNpID0gaW52ICogKE1CaSAtIE1EaSk7CgogICAgICAgICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgICAgICAgdmFyIEZBciA9IFQwciArIFQycjsKICAgICAgICAgICAgdmFyIEZBaSA9IFQwaSArIFQyaTsKCiAgICAgICAgICAgIHZhciBGQnIgPSBUMXIgKyBUM2k7CiAgICAgICAgICAgIHZhciBGQmkgPSBUMWkgLSBUM3I7CgogICAgICAgICAgICBvdXRbQV0gPSBGQXI7CiAgICAgICAgICAgIG91dFtBICsgMV0gPSBGQWk7CiAgICAgICAgICAgIG91dFtCXSA9IEZCcjsKICAgICAgICAgICAgb3V0W0IgKyAxXSA9IEZCaTsKCiAgICAgICAgICAgIC8vIE91dHB1dCBmaW5hbCBtaWRkbGUgcG9pbnQKICAgICAgICAgICAgaWYgKGkgPT09IDApIHsKICAgICAgICAgICAgICB2YXIgRkNyID0gVDByIC0gVDJyOwogICAgICAgICAgICAgIHZhciBGQ2kgPSBUMGkgLSBUMmk7CiAgICAgICAgICAgICAgb3V0W0NdID0gRkNyOwogICAgICAgICAgICAgIG91dFtDICsgMV0gPSBGQ2k7CiAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIERvIG5vdCBvdmVyd3JpdGUgb3Vyc2VsdmVzCiAgICAgICAgICAgIGlmIChpID09PSBocXVhcnRlckxlbikKICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIC8vIEluIHRoZSBmbGlwcGVkIGNhc2U6CiAgICAgICAgICAgIC8vIE1BaSA9IC1NQWkKICAgICAgICAgICAgLy8gTUJyPS1NQmksIE1CaT0tTUJyCiAgICAgICAgICAgIC8vIE1Dcj0tTUNyCiAgICAgICAgICAgIC8vIE1Ecj1NRGksIE1EaT1NRHIKICAgICAgICAgICAgdmFyIFNUMHIgPSBUMXI7CiAgICAgICAgICAgIHZhciBTVDBpID0gLVQxaTsKICAgICAgICAgICAgdmFyIFNUMXIgPSBUMHI7CiAgICAgICAgICAgIHZhciBTVDFpID0gLVQwaTsKICAgICAgICAgICAgdmFyIFNUMnIgPSAtaW52ICogVDNpOwogICAgICAgICAgICB2YXIgU1QyaSA9IC1pbnYgKiBUM3I7CiAgICAgICAgICAgIHZhciBTVDNyID0gLWludiAqIFQyaTsKICAgICAgICAgICAgdmFyIFNUM2kgPSAtaW52ICogVDJyOwoKICAgICAgICAgICAgdmFyIFNGQXIgPSBTVDByICsgU1QycjsKICAgICAgICAgICAgdmFyIFNGQWkgPSBTVDBpICsgU1QyaTsKCiAgICAgICAgICAgIHZhciBTRkJyID0gU1QxciArIFNUM2k7CiAgICAgICAgICAgIHZhciBTRkJpID0gU1QxaSAtIFNUM3I7CgogICAgICAgICAgICB2YXIgU0EgPSBvdXRPZmYgKyBxdWFydGVyTGVuIC0gaTsKICAgICAgICAgICAgdmFyIFNCID0gb3V0T2ZmICsgaGFsZkxlbiAtIGk7CgogICAgICAgICAgICBvdXRbU0FdID0gU0ZBcjsKICAgICAgICAgICAgb3V0W1NBICsgMV0gPSBTRkFpOwogICAgICAgICAgICBvdXRbU0JdID0gU0ZCcjsKICAgICAgICAgICAgb3V0W1NCICsgMV0gPSBTRkJpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfTsKCiAgICAvLyByYWRpeC0yIGltcGxlbWVudGF0aW9uCiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj00CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVSZWFsVHJhbnNmb3JtMiA9IGZ1bmN0aW9uIF9zaW5nbGVSZWFsVHJhbnNmb3JtMihvdXRPZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CgogICAgICBjb25zdCBldmVuUiA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3Qgb2RkUiA9IGRhdGFbb2ZmICsgc3RlcF07CgogICAgICBjb25zdCBsZWZ0UiA9IGV2ZW5SICsgb2RkUjsKICAgICAgY29uc3QgcmlnaHRSID0gZXZlblIgLSBvZGRSOwoKICAgICAgb3V0W291dE9mZl0gPSBsZWZ0UjsKICAgICAgb3V0W291dE9mZiArIDFdID0gMDsKICAgICAgb3V0W291dE9mZiArIDJdID0gcmlnaHRSOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSAwOwogICAgfTsKCiAgICAvLyByYWRpeC00CiAgICAvLwogICAgLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj04CiAgICBGRlQucHJvdG90eXBlLl9zaW5nbGVSZWFsVHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF9zaW5nbGVSZWFsVHJhbnNmb3JtNChvdXRPZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKSB7CiAgICAgIGNvbnN0IG91dCA9IHRoaXMuX291dDsKICAgICAgY29uc3QgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgIGNvbnN0IGludiA9IHRoaXMuX2ludiA/IC0xIDogMTsKICAgICAgY29uc3Qgc3RlcDIgPSBzdGVwICogMjsKICAgICAgY29uc3Qgc3RlcDMgPSBzdGVwICogMzsKCiAgICAgIC8vIE9yaWdpbmFsIHZhbHVlcwogICAgICBjb25zdCBBciA9IGRhdGFbb2ZmXTsKICAgICAgY29uc3QgQnIgPSBkYXRhW29mZiArIHN0ZXBdOwogICAgICBjb25zdCBDciA9IGRhdGFbb2ZmICsgc3RlcDJdOwogICAgICBjb25zdCBEciA9IGRhdGFbb2ZmICsgc3RlcDNdOwoKICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwogICAgICBjb25zdCBUMHIgPSBBciArIENyOwogICAgICBjb25zdCBUMXIgPSBBciAtIENyOwogICAgICBjb25zdCBUMnIgPSBCciArIERyOwogICAgICBjb25zdCBUM3IgPSBpbnYgKiAoQnIgLSBEcik7CgogICAgICAvLyBGaW5hbCB2YWx1ZXMKICAgICAgY29uc3QgRkFyID0gVDByICsgVDJyOwoKICAgICAgY29uc3QgRkJyID0gVDFyOwogICAgICBjb25zdCBGQmkgPSAtVDNyOwoKICAgICAgY29uc3QgRkNyID0gVDByIC0gVDJyOwoKICAgICAgY29uc3QgRkRyID0gVDFyOwogICAgICBjb25zdCBGRGkgPSBUM3I7CgogICAgICBvdXRbb3V0T2ZmXSA9IEZBcjsKICAgICAgb3V0W291dE9mZiArIDFdID0gMDsKICAgICAgb3V0W291dE9mZiArIDJdID0gRkJyOwogICAgICBvdXRbb3V0T2ZmICsgM10gPSBGQmk7CiAgICAgIG91dFtvdXRPZmYgKyA0XSA9IEZDcjsKICAgICAgb3V0W291dE9mZiArIDVdID0gMDsKICAgICAgb3V0W291dE9mZiArIDZdID0gRkRyOwogICAgICBvdXRbb3V0T2ZmICsgN10gPSBGRGk7CiAgICB9OwoKICAgIHZhciBGRlQkMSA9IC8qQF9fUFVSRV9fKi9nZXREZWZhdWx0RXhwb3J0RnJvbUNqcyhmZnQpOwoKICAgIGNvbnN0IEJVRkZFUkVEX0JMT0NLX1NJWkUgPSAyMDQ4OwogICAgZnVuY3Rpb24gZ2VuSGFubldpbmRvdyhsZW5ndGgpIHsKICAgICAgICBsZXQgd2luID0gbmV3IEZsb2F0MzJBcnJheShsZW5ndGgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgd2luW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcygoMiAqIE1hdGguUEkgKiBpKSAvIGxlbmd0aCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gd2luOwogICAgfQogICAgY2xhc3MgUGhhc2VWb2NvZGVyUHJvY2Vzc29yIGV4dGVuZHMgT0xBUHJvY2Vzc29yIHsKICAgICAgICBmZnRTaXplOwogICAgICAgIHRpbWVDdXJzb3I7CiAgICAgICAgaGFubldpbmRvdzsKICAgICAgICBmZnQ7CiAgICAgICAgZnJlcUNvbXBsZXhCdWZmZXI7CiAgICAgICAgZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkOwogICAgICAgIHRpbWVDb21wbGV4QnVmZmVyOwogICAgICAgIG1hZ25pdHVkZXM7CiAgICAgICAgcGVha0luZGV4ZXM7CiAgICAgICAgbmJQZWFrczsKICAgICAgICBzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkgewogICAgICAgICAgICByZXR1cm4gWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5hbWU6ICJwaXRjaEZhY3RvciIsCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICBdOwogICAgICAgIH0KICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3VwZXIob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwogICAgICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKICAgICAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCiAgICAgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CiAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPQogICAgICAgICAgICAgICAgdGhpcy5mZnQuY3JlYXRlQ29tcGxleEFycmF5KCk7CiAgICAgICAgICAgIHRoaXMudGltZUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmZmdFNpemUgLyAyICsgMSk7CiAgICAgICAgICAgIHRoaXMucGVha0luZGV4ZXMgPSBuZXcgSW50MzJBcnJheSh0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKTsKICAgICAgICAgICAgdGhpcy5uYlBlYWtzID0gMDsKICAgICAgICB9CiAgICAgICAgcHJvY2Vzc09MQShpbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpIHsKICAgICAgICAgICAgY29uc3QgcGl0Y2hGYWN0b3IgPSBwYXJhbWV0ZXJzLnBpdGNoRmFjdG9yW3BhcmFtZXRlcnMucGl0Y2hGYWN0b3IubGVuZ3RoIC0gMV07CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGlucHV0c1tpXS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIHZhciBpbnB1dCA9IGlucHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB2YXIgb3V0cHV0ID0gb3V0cHV0c1tpXVtqXTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGx5SGFubldpbmRvdyhpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mZnQucmVhbFRyYW5zZm9ybSh0aGlzLmZyZXFDb21wbGV4QnVmZmVyLCBpbnB1dCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wdXRlTWFnbml0dWRlcygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZmluZFBlYWtzKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zaGlmdFBlYWtzKHBpdGNoRmFjdG9yKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZmdC5jb21wbGV0ZVNwZWN0cnVtKHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZmdC5pbnZlcnNlVHJhbnNmb3JtKHRoaXMudGltZUNvbXBsZXhCdWZmZXIsIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZmdC5mcm9tQ29tcGxleEFycmF5KHRoaXMudGltZUNvbXBsZXhCdWZmZXIsIG91dHB1dCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseUhhbm5XaW5kb3cob3V0cHV0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLnRpbWVDdXJzb3IgKz0gdGhpcy5ob3BTaXplOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgYXBwbHlIYW5uV2luZG93KGlucHV0KSB7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ibG9ja1NpemU7IGkrKykgewogICAgICAgICAgICAgICAgaW5wdXRbaV0gKj0gdGhpcy5oYW5uV2luZG93W2ldOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbXB1dGVNYWduaXR1ZGVzKCkgewogICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgaiA9IDA7IGkgPCB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoOyBpKyssIGogKz0gMikgewogICAgICAgICAgICAgICAgY29uc3QgcmVhbCA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbal07CiAgICAgICAgICAgICAgICBjb25zdCBpbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltqICsgMV07CiAgICAgICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXNbaV0gPSByZWFsICoqIDIgKyBpbWFnICoqIDI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZmluZFBlYWtzKCkgewogICAgICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMiwgZW5kID0gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCAtIDI7IGkgPCBlbmQ7IGkrKykgewogICAgICAgICAgICAgICAgY29uc3QgbWFnID0gdGhpcy5tYWduaXR1ZGVzW2ldOwogICAgICAgICAgICAgICAgaWYgKHRoaXMubWFnbml0dWRlc1tpIC0gMV0gPj0gbWFnIHx8CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2kgLSAyXSA+PSBtYWcgfHwKICAgICAgICAgICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXNbaSArIDFdID49IG1hZyB8fAogICAgICAgICAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpICsgMl0gPj0gbWFnKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLnBlYWtJbmRleGVzW3RoaXMubmJQZWFrcysrXSA9IGk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2hpZnRQZWFrcyhwaXRjaEZhY3RvcikgewogICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZC5maWxsKDApOwogICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmJQZWFrczsgaSsrKSB7CiAgICAgICAgICAgICAgICBjb25zdCBwZWFrSW5kZXggPSB0aGlzLnBlYWtJbmRleGVzW2ldOwogICAgICAgICAgICAgICAgY29uc3QgcGVha0luZGV4U2hpZnRlZCA9IE1hdGgucm91bmQocGVha0luZGV4ICogcGl0Y2hGYWN0b3IpOwogICAgICAgICAgICAgICAgaWYgKHBlYWtJbmRleFNoaWZ0ZWQgPiB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsZXQgc3RhcnRJbmRleCA9IGkgPiAwCiAgICAgICAgICAgICAgICAgICAgPyBwZWFrSW5kZXggLSBNYXRoLmZsb29yKChwZWFrSW5kZXggLSB0aGlzLnBlYWtJbmRleGVzW2kgLSAxXSkgLyAyKQogICAgICAgICAgICAgICAgICAgIDogMDsKICAgICAgICAgICAgICAgIGxldCBlbmRJbmRleCA9IGkgPCB0aGlzLm5iUGVha3MgLSAxCiAgICAgICAgICAgICAgICAgICAgPyBwZWFrSW5kZXggKyBNYXRoLmNlaWwoKHRoaXMucGVha0luZGV4ZXNbaSArIDFdIC0gcGVha0luZGV4KSAvIDIpCiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleCAtIHBlYWtJbmRleDsgaiA8IGVuZEluZGV4IC0gcGVha0luZGV4OyBqKyspIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBiaW5JbmRleCA9IHBlYWtJbmRleCArIGo7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXhTaGlmdGVkID0gcGVha0luZGV4U2hpZnRlZCArIGo7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJpbkluZGV4U2hpZnRlZCA+PSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYURlbHRhID0gKDIgKiBNYXRoLlBJICogKGJpbkluZGV4U2hpZnRlZCAtIGJpbkluZGV4KSkgLyB0aGlzLmZmdFNpemU7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdFJlYWwgPSBNYXRoLmNvcyhvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBwaGFzZVNoaWZ0SW1hZyA9IE1hdGguc2luKG9tZWdhRGVsdGEgKiB0aGlzLnRpbWVDdXJzb3IpOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4UmVhbCA9IGJpbkluZGV4ICogMjsKICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleEltYWcgPSBpbmRleFJlYWwgKyAxOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlUmVhbCA9IHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJbaW5kZXhSZWFsXTsKICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZUltYWcgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4SW1hZ107CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVTaGlmdGVkUmVhbCA9IHZhbHVlUmVhbCAqIHBoYXNlU2hpZnRSZWFsIC0gdmFsdWVJbWFnICogcGhhc2VTaGlmdEltYWc7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVTaGlmdGVkSW1hZyA9IHZhbHVlUmVhbCAqIHBoYXNlU2hpZnRJbWFnICsgdmFsdWVJbWFnICogcGhhc2VTaGlmdFJlYWw7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhTaGlmdGVkUmVhbCA9IGJpbkluZGV4U2hpZnRlZCAqIDI7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhTaGlmdGVkSW1hZyA9IGluZGV4U2hpZnRlZFJlYWwgKyAxOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZFJlYWxdICs9IHZhbHVlU2hpZnRlZFJlYWw7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWRbaW5kZXhTaGlmdGVkSW1hZ10gKz0gdmFsdWVTaGlmdGVkSW1hZzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8vIEB0cy1pZ25vcmUKICAgIHJlZ2lzdGVyUHJvY2Vzc29yKCJwaGFzZS12b2NvZGVyIiwgUGhhc2VWb2NvZGVyUHJvY2Vzc29yKTsKICAgIGNvbnNvbGUubG9nKCJQaGFzZVZvY29kZXJQcm9jZXNzb3IgcmVnaXN0ZXJlZCIpOwoKICAgIGV4cG9ydHMuUGhhc2VWb2NvZGVyUHJvY2Vzc29yID0gUGhhc2VWb2NvZGVyUHJvY2Vzc29yOwoKICAgIHJldHVybiBleHBvcnRzOwoKfSkoe30pOwovLyMgc291cmNlTWFwcGluZ1VSTD1waGFzZS12b2NvZGVyLWJ1bmRsZS5qcy5tYXAK";class w{maxSize;cache;constructor(e){this.maxSize=e,this.cache=new Map}get(e){if(!this.cache.has(e))return;const g=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,g),g}set(e,g){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const t=this.cache.keys().next().value;t!==void 0&&this.cache.delete(t)}this.cache.set(e,g)}has(e){return this.cache.has(e)}}const R=100;function Y(a){if(!a)return null;const e=a.match(/max-age\s*=\s*"?(\d+)"?/i);return e?parseInt(e[1],10):null}function D(a){return a?/(?:^|,)\s*(no-cache|no-store|must-revalidate)\s*(?:,|$)/i.test(a):!1}class r{static pendingRequests=new Map;static pendingCallbacks=new Map;static decodedBuffers=new w(R);static cacheExpirationTime=1440*60*1e3;static setCacheExpirationTime(e){this.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,g,t){const I=this.pendingCallbacks.get(e);I&&I.forEach(C=>{const i=C[g];if(i)try{i(t)}catch(o){console.error(`Error in ${g} callback:`,o)}})}static async getOrCreatePendingRequest(e,g,t,I){if(t?.aborted)throw new DOMException("Operation was aborted","AbortError");if(I){const i=this.pendingCallbacks.get(e)||[];i.push(I),this.pendingCallbacks.set(e,i)}let C=this.pendingRequests.get(e);if(!C){const i=(async()=>{try{const o=await g();if(o===void 0)throw new Error("Failed to create audio buffer.");return o}finally{this.pendingRequests.delete(e),this.pendingCallbacks.delete(e)}})();return t?.addEventListener("abort",()=>{t.aborted&&(this.pendingRequests.delete(e),this.pendingCallbacks.delete(e))},{once:!0}),this.pendingRequests.set(e,i),i}return C}static async updateMetadata(e,g,t){const I={url:g,timestamp:Date.now(),...t};await e.put(`${g}:meta`,new Response(JSON.stringify(I),{headers:{"Content-Type":"application/json"}}))}static async getBufferFromCache(e,g){try{const t=await g.match(e);return t&&t.ok?await t.arrayBuffer():null}catch(t){return console.error("Failed to get data from cache:",t),null}}static async fetchAndCacheBuffer(e,g,t,I,C,i){const o=new Headers;t&&o.append("If-None-Match",t),I&&o.append("If-Modified-Since",I),console.debug(`[AudioCache] Fetching ${e}`,{headers:Object.fromEntries(o.entries()),hasEtag:!!t,hasLastModified:!!I});const s=await fetch(e,{headers:o,signal:C});if(console.debug(`[AudioCache] Response ${e}`,{status:s.status,statusText:s.statusText,etag:s.headers?.get("ETag"),lastModified:s.headers?.get("Last-Modified"),cacheControl:s.headers?.get("Cache-Control")}),s.status===304){const A=await g.match(e);if(A){i?.onCacheHit&&i.onCacheHit({url:e,cacheType:"browser",timestamp:Date.now()});const n=Date.now(),c=s.headers?.get("Cache-Control");return await this.updateMetadata(g,e,{timestamp:n,etag:t,lastModified:I,...c?{cacheControl:c}:{}}),await A.arrayBuffer()}else{console.warn(`Cache inconsistency detected for ${e}: 304 response but no cached body. Re-fetching.`);const n=await fetch(e,{signal:C});if(n.status===200){const c=n.clone(),h=n.headers.get("ETag"),d=n.headers.get("Last-Modified"),m=n.headers.get("Cache-Control");try{await Promise.all([g.put(e,c),this.updateMetadata(g,e,{timestamp:Date.now(),etag:h||void 0,lastModified:d||void 0,cacheControl:m||void 0})])}catch(b){throw await g.delete(e),await g.delete(`${e}:meta`),b}if(n.body){const{stream:b,total:f}=this.createProgressTrackingStream(n,e);return await this.collectStreamToArrayBuffer(b,f||void 0)}else return await n.arrayBuffer()}else throw new Error(`Failed to fetch resource after cache inconsistency: ${n.status} ${n.statusText}`)}}if(s.status===200){const A=s.clone(),n=s.headers.get("ETag"),c=s.headers.get("Last-Modified"),h=s.headers.get("Cache-Control");try{await Promise.all([g.put(e,A),this.updateMetadata(g,e,{timestamp:Date.now(),etag:n||void 0,lastModified:c||void 0,cacheControl:h||void 0})])}catch(d){throw await g.delete(e),await g.delete(`${e}:meta`),d}}if(C?.aborted)throw new DOMException("Operation was aborted","AbortError");if(s.body){const{stream:A,total:n}=this.createProgressTrackingStream(s,e);return await this.collectStreamToArrayBuffer(A,n||void 0)}else return await s.arrayBuffer()}static createProgressTrackingStream(e,g){const t=e.headers.get("content-length"),I=t?parseInt(t,10):null;let C=0;if(!e.body)throw new Error("Response body is null");const i=e.body.getReader();return{stream:new ReadableStream({start(s){function A(){return i.read().then(({done:n,value:c})=>{if(n){r.callAllCallbacks(g,"onLoadingProgress",{url:g,loaded:C,total:I,progress:I?1:-1,timestamp:Date.now()}),s.close();return}if(c){C+=c.byteLength;const h=I?C/I:-1;r.callAllCallbacks(g,"onLoadingProgress",{url:g,loaded:C,total:I,progress:h,timestamp:Date.now()}),s.enqueue(c)}return A()}).catch(n=>{s.error(n)})}return A()},cancel(s){return i.cancel(s)}}),total:I}}static async collectStreamToArrayBuffer(e,g){const t=e.getReader();try{if(g!==void 0&&g>0){const I=new ArrayBuffer(g),C=new Uint8Array(I);let i=0;for(;;){const{done:o,value:s}=await t.read();if(o)break;s&&(C.set(s,i),i+=s.byteLength)}return I}else{let I=new Uint8Array(8192),C=0;for(;;){const{done:i,value:o}=await t.read();if(i)break;if(o){if(C+o.byteLength>I.length){const s=Math.max(I.length*2,C+o.byteLength),A=new Uint8Array(s);A.set(I.subarray(0,C)),I=A}I.set(o,C),C+=o.byteLength}}return I.slice(0,C).buffer}}finally{t.releaseLock()}}static async decodeAudioData(e,g){try{return await e.decodeAudioData(g)}catch(t){throw console.error("Failed to decode audio data:",t),t}}static async getMetadataFromCache(e,g){try{const t=await g.match(e+":meta");return t&&t.ok?await t.json():null}catch(t){return console.error("Failed to get metadata from cache:",t),null}}async getAudioBuffer(e,g,t,I){if(I?.onLoadingStart&&I.onLoadingStart({url:g,timestamp:Date.now()}),r.decodedBuffers.has(g))return I?.onCacheHit&&I.onCacheHit({url:g,cacheType:"memory",timestamp:Date.now()}),r.decodedBuffers.get(g);if(g.startsWith("data:")){const s=g.split(",")[1],A=Uint8Array.from(atob(s),c=>c.charCodeAt(0)).buffer,n=await r.decodeAudioData(e,A);return r.decodedBuffers.set(g,n),n}const C=await r.openCache(),i=await r.getMetadataFromCache(g,C),o=(()=>{if(!i||D(i.cacheControl))return!0;const s=Y(i.cacheControl);if(s!==null){const A=(Date.now()-i.timestamp)/1e3;if(s>0&&A<s)return!1}return i.etag||i.lastModified?!0:Date.now()-i.timestamp>r.cacheExpirationTime})();return r.getOrCreatePendingRequest(g,async()=>{if(o){I?.onCacheMiss&&I.onCacheMiss({url:g,reason:i?"expired":"not-found",timestamp:Date.now()});try{const s=await r.fetchAndCacheBuffer(g,C,i?.etag,i?.lastModified,t,{onCacheHit:I?.onCacheHit});I?.onLoadingComplete&&I.onLoadingComplete({url:g,duration:0,size:s.byteLength,timestamp:Date.now()});const A=await r.decodeAudioData(e,s);return r.decodedBuffers.set(g,A),A}catch(s){throw I?.onCacheError&&I.onCacheError({url:g,error:s,operation:"get",timestamp:Date.now()}),s}}else{const s=await r.getBufferFromCache(g,C);if(s){I?.onCacheHit&&I.onCacheHit({url:g,cacheType:"browser",timestamp:Date.now()});const A=await r.decodeAudioData(e,s);return r.decodedBuffers.set(g,A),A}else{I?.onCacheError&&I.onCacheError({url:g,error:new Error("Cache inconsistency: metadata exists but body is missing"),operation:"get",timestamp:Date.now()});const A=await r.fetchAndCacheBuffer(g,C,i?.etag,i?.lastModified,t,{onCacheHit:I?.onCacheHit}),n=await r.decodeAudioData(e,A);return r.decodedBuffers.set(g,n),n}}},t,{onLoadingProgress:I?.onLoadingProgress})}clearMemoryCache(){r.decodedBuffers=new w(R),r.pendingRequests.clear()}}class y{listeners={};on(e,g){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:g,once:!1}),()=>this.off(e,g)}once(e,g){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:g,once:!0}),()=>this.off(e,g)}off(e,g){const t=this.listeners[e];t&&(this.listeners[e]=t.filter(I=>I.fn!==g))}emit(e,g){const t=this.listeners[e];t&&(t.forEach(I=>I.fn(g)),this.listeners[e]=t.filter(I=>!I.once))}emitAsync(e,g){const t=this.listeners[e];if(t){const I=t.map(C=>Promise.resolve().then(()=>C.fn(g)).catch(i=>console.error(`Error in listener for event ${e}:`,i)));return this.listeners[e]=t.filter(C=>!C.once),Promise.all(I).then(()=>{})}return Promise.resolve()}removeAllListeners(){this.listeners={}}}class X{constructor(e=[]){this.sounds=e}_position=[0,0,0];loopCount=0;playIndex=0;preplayRandom(){if(this.sounds.length===0)return;const g=this.randomSound().preplay();return g.length>0?g[0]:void 0}playRandom(){const e=this.preplayRandom();return e&&e.play(),e}preplayOrdered(e=!0){if(this.sounds.length===0)return;const t=this.sounds[this.playIndex].preplay();if(t.length!==0)return this.playIndex=(this.playIndex+1)%this.sounds.length,!e&&this.playIndex===0&&(this.playIndex=this.sounds.length),t[0]}playOrdered(e=!0){const g=this.preplayOrdered(e);return g&&g.play(),g}get duration(){return this.sounds.map(e=>e.duration).reduce((e,g)=>Math.max(e,g),0)}seek(e){this.sounds.forEach(g=>g.seek&&g.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(g=>g.preplay()).flat()}play(){const e=[];return this.preplay().forEach(g=>{g.play(),e.push(g)}),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,g,t){return Promise.all(this.sounds.map(I=>I.fadeTo(e,g,t))).then(()=>{})}fadeIn(e,g){return Promise.all(this.sounds.map(t=>t.fadeIn(e,g))).then(()=>{})}fadeOut(e,g){return Promise.all(this.sounds.map(t=>t.fadeOut(e,g))).then(()=>{})}stopWithFade(e,g){return Promise.all(this.sounds.map(t=>t.stopWithFade(e,g))).then(()=>{})}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.sounds.forEach(g=>g.loop(e)),this.loopCount)}addFilter(e){this.sounds.forEach(g=>g.addFilter(e))}removeFilter(e){this.sounds.forEach(g=>g.removeFilter(e))}set position(e){this._position=e,this.sounds.forEach(g=>g.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(e=>e.volume).reduce((e,g)=>e+g,0)/this.sounds.length}set volume(e){this.sounds.forEach(g=>g.volume=e)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(e){this.sounds.forEach(g=>g.playbackRate=e)}}class p{_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 g=this._filters.length;if(this._filters=this._filters.filter(t=>t!==e),this._filters.length===g)throw new Error("Cannot remove filter that was never added to this container")}applyFilters(e){return this._filters.reduce((g,t)=>(g.connect(t),t),e),this._filters.length>0?this._filters[this._filters.length-1]:e}get filters(){return this._filters}addFilters(e){e.forEach(g=>this.addFilter(g))}removeFilters(e){e.forEach(g=>this.removeFilter(g))}cleanup(){this._filters.forEach(e=>e.disconnect()),this._filters=[]}}class S extends p{context;source;gainNode;panner;constructor(e,g,t,I=0){super(),this.source=e,this.gainNode=g,this.context=t,this.panner=t.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[g,t,I]=e;this.panner.positionX.value=g,this.panner.positionY.value=t,this.panner.positionZ.value=I}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.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.source;this.source.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(e){}}class N extends p{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(e){super(),this.context=e,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(e=>{this.stream=e,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new S(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(e=>{console.error("Error initializing microphone stream:",e)}),this.streamPlayback?[this.streamPlayback]:[]}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 H(a){class e extends a{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 t=this.preplay();return t.forEach(I=>I.play()),t}stop(){this.playbacks.forEach(t=>{t.stop(),t.cleanup()}),this.playbacks=[]}pause(){this.playbacks.forEach(t=>t.pause())}addFilter(t){super.addFilter(t)}removeFilter(t){super.removeFilter(t)}get isPlaying(){return this.playbacks.some(t=>t.isPlaying)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(t){this._threeDOptions.positionX=t[0],this._threeDOptions.positionY=t[1],this._threeDOptions.positionZ=t[2],this.playbacks.forEach(I=>I.position=t)}get threeDOptions(){return this._threeDOptions}set threeDOptions(t){this._threeDOptions={...this._threeDOptions,...t},this.playbacks.forEach(I=>I.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(t){this._stereoPan=t,this.playbacks.forEach(I=>I.stereoPan=t)}get volume(){return this._volume}set volume(t){this._volume=t,this.playbacks.forEach(I=>I.volume=t)}fadeTo(t,I,C){return this._volume=t,Promise.all(this.playbacks.map(i=>i.fadeTo(t,I,C))).then(()=>{})}fadeIn(t,I){return Promise.all(this.playbacks.map(C=>C.fadeIn(t,I))).then(()=>{})}fadeOut(t,I){return Promise.all(this.playbacks.map(C=>C.fadeOut(t,I))).then(()=>{})}stopWithFade(t,I){return this.fadeOut(t,I).then(()=>this.stop())}}return e}function K(a){class e extends a{panner;_panType="stereo";get panType(){return this._panType}setPanType(t,I){this._panType===t&&this.panner||(this.panner&&this.panner.disconnect(),this._panType=t,t==="stereo"?this.panner=I.createStereoPanner():this.panner=I.createPanner())}setPannerNode(t){this.panner=t}get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(t){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");t=v(t,-1,1),this.panner.pan.setValueAtTime(v(t,-1,1),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 t=this.panner;return{coneInnerAngle:t.coneInnerAngle,coneOuterAngle:t.coneOuterAngle,coneOuterGain:t.coneOuterGain,distanceModel:t.distanceModel,maxDistance:t.maxDistance,channelCount:this.panner.channelCount,channelCountMode:t.channelCountMode,channelInterpretation:t.channelInterpretation,panningModel:t.panningModel,refDistance:t.refDistance,rolloffFactor:t.rolloffFactor,positionX:t.positionX.value,positionY:t.positionY.value,positionZ:t.positionZ.value,orientationX:t.orientationX.value,orientationY:t.orientationY.value,orientationZ:t.orientationZ.value}}set threeDOptions(t){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 I=this.panner;I.coneInnerAngle=t.coneInnerAngle!==void 0?t.coneInnerAngle:I.coneInnerAngle,I.coneOuterAngle=t.coneOuterAngle!==void 0?t.coneOuterAngle:I.coneOuterAngle,I.coneOuterGain=t.coneOuterGain!==void 0?t.coneOuterGain:I.coneOuterGain,I.distanceModel=t.distanceModel||I.distanceModel,I.maxDistance=t.maxDistance!==void 0?t.maxDistance:I.maxDistance,I.channelCount=t.channelCount!==void 0?t.channelCount:I.channelCount,I.channelCountMode=t.channelCountMode||I.channelCountMode,I.channelInterpretation=t.channelInterpretation||I.channelInterpretation,I.panningModel=t.panningModel||I.panningModel,I.refDistance=t.refDistance!==void 0?t.refDistance:I.refDistance,I.rolloffFactor=t.rolloffFactor!==void 0?t.rolloffFactor:I.rolloffFactor,I.positionX.value=t.positionX!==void 0?t.positionX:I.positionX.value,I.positionY.value=t.positionY!==void 0?t.positionY:I.positionY.value,I.positionZ.value=t.positionZ!==void 0?t.positionZ:I.positionZ.value,I.orientationX.value=t.orientationX!==void 0?t.orientationX:I.orientationX.value,I.orientationY.value=t.orientationY!==void 0?t.orientationY:I.orientationY.value,I.orientationZ.value=t.orientationZ!==void 0?t.orientationZ:I.orientationZ.value}set position(t){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[I,C,i]=t,o=this.panner;o.positionX.value=I,o.positionY.value=C,o.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 t=this.panner;return[t.positionX.value,t.positionY.value,t.positionZ.value]}cleanup(){this.panner&&(this.panner.disconnect(),this.panner=void 0),super.cleanup()}}return e}function v(a,e,g){return Math.min(Math.max(a,e),g)}function F(a){class e extends a{gainNode;_fadeTimeout;_isFading=!1;setGainNode(t){this.gainNode=t}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(t){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.cancelFade(),this.gainNode.gain.value=t}get isFading(){return this._isFading}fadeTo(t,I,C="linear"){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");this.cancelFade();const i=this.gainNode.context.currentTime,o=i+I/1e3;return this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,i),C==="exponential"?this.gainNode.gain.exponentialRampToValueAtTime(t===0?1e-4:t,o):this.gainNode.gain.linearRampToValueAtTime(t,o),this._isFading=!0,new Promise(s=>{this._fadeTimeout=setTimeout(()=>{this._isFading=!1,t===0&&C==="exponential"&&this.gainNode&&(this.gainNode.gain.value=0),s()},I)})}cancelFade(){if(this._fadeTimeout&&(clearTimeout(this._fadeTimeout),this._fadeTimeout=void 0),this._isFading&&this.gainNode){const t=this.gainNode.context.currentTime;this.gainNode.gain.cancelScheduledValues(t),this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,t)}this._isFading=!1}fadeIn(t,I){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");const C=this.gainNode.gain.value;return this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(C,t,I)}fadeOut(t,I){return this.fadeTo(0,t,I)}}return e}class W extends K(F(p)){source;_playing=!1;origin;eventEmitter=new y;constructor(){super()}get isPlaying(){return this.source?this._playing:!1}on(e,g){this.eventEmitter.on(e,g)}off(e,g){this.eventEmitter.off(e,g)}emit(e,g){this.eventEmitter.emit(e,g)}async emitAsync(e,g){return this.eventEmitter.emitAsync(e,g)}fadeTo(e,g,t="linear"){return this.emit("fadeStart",{target:e,duration:g,type:t}),super.fadeTo(e,g,t).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 W{constructor(e,g,t){super(),this.origin=e,this.context=e.context,this.loopCount=e.loopCount,this.setPanType(e.panType,e.context),this.source=g,"buffer"in g&&g.buffer&&(this.buffer=g.buffer),this.setupSourceNode(g),this.source.connect(this.panner),this.setGainNode(t),this.panner.connect(this.gainNode),this.refreshFilters()}context;loopCount=0;currentLoop=0;buffer;_offset=0;_startTime=0;_state=0;_playbackRate=1;_fadeInConfig;_fadeOutConfig;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}set playbackRate(e){if(e<=0)throw new Error("Playback rate must be greater than 0");if(this._state===1){const g=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=g,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._fadeOutConfig?this.fadeOut(this._fadeOutConfig.duration,this._fadeOutConfig.type).then(()=>this.stop()):this.stop():(this.seek(0),"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():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];try{return this._state===2?"mediaElement"in this.source&&this.source.mediaElement?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,this.source.mediaElement.play()):"start"in this.source&&this.source.start&&(this.recreateSource(),this.source.start(0,this._offset)),this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()}),[this]}catch(e){throw this.emitAsync("error",{error:e,errorType:"source",timestamp:Date.now(),recoverable:!0}),e}}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,g,t){return t?.perLoop&&(this._fadeInConfig={duration:e,type:g||"linear",perLoop:!0,targetVolume:this.gainNode.gain.value}),super.fadeIn(e,g)}configureFadeOut(e,g){this._fadeOutConfig={duration:e,type:g||"linear"}}stopWithFade(e,g){return this.fadeOut(e,g).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(!isFinite(e)||e<0)throw new Error("Invalid time value for seek");const g=this._state===1;g&&this.pause(),this._offset=e,"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.currentTime=e),g&&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}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&&(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 g=this.source.mediaElement;g.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 g=e.panType||this.panType,t=this.context.createGain();let I;if("buffer"in this.source&&this.source.buffer)I=this.context.createBufferSource(),I.buffer=this.source.buffer;else if("mediaElement"in this.source&&this.source.mediaElement)I=this.context.createMediaElementSource(this.source.mediaElement);else throw new Error("Unsupported source type");const C=e.loopCount!==void 0?e.loopCount:this.loopCount,i=new Z(this.origin,I,t);return i.loopCount=C,i.currentLoop=this.currentLoop,i.setPanType(g,this.context),i.volume=this.volume,i.playbackRate=this._playbackRate,i._offset=this._offset,i._state=this._state,this._filters.forEach(o=>{const s=this.context.createBiquadFilter();s.type=o.type,s.frequency.value=o.frequency.value,s.Q.value=o.Q.value,s.gain.value=o.gain.value,i.addFilter(s)}),this._state===1&&i.play(),i}}class u extends H(p){constructor(e,g,t,I,C=B.Buffer,i="HRTF",o){super(),this.url=e,this.globalGainNode=I,this.soundType=C,this.panType=i,this._cacophony=o,this.buffer=g,this.context=t}buffer;context;loopCount=0;_playbackRate=1;eventEmitter=new y;get cacophony(){return this._cacophony}get volume(){return super.volume}on(e,g){this.eventEmitter.on(e,g)}off(e,g){this.eventEmitter.off(e,g)}emit(e,g){this.eventEmitter.emit(e,g)}async emitAsync(e,g){return this.eventEmitter.emitAsync(e,g)}clone(e={}){const g=e.panType||this.panType,t=e.stereoPan!==void 0?e.stereoPan:this.stereoPan,I=e.threeDOptions||this.threeDOptions,C=e.loopCount!==void 0?e.loopCount:this.loopCount,i=e.playbackRate||this.playbackRate,o=e.volume!==void 0?e.volume:this.volume,s=e.position!==void 0?e.position:this.position,A=e.filters&&e.filters.length?e.filters:this._filters,n=new u(this.url,this.buffer,this.context,this.globalGainNode,this.soundType,g,this.cacophony);return n.loop(C),n.playbackRate=i,n.volume=o,g==="HRTF"?(n.threeDOptions=I,n.position=s):n.stereoPan=t,n.addFilters(A),n}preplay(){try{let e;if(this.buffer)e=this.context.createBufferSource(),e.buffer=this.buffer;else{const I=new Audio;I.crossOrigin="anonymous",I.src=this.url,I.preload="auto",e=this.context.createMediaElementSource(I)}const g=this.context.createGain();g.connect(this.globalGainNode);const t=new Z(this,e,g);return t.setGainNode(g),t.volume=this.volume,t.playbackRate=this.playbackRate,this._filters.forEach(I=>{const C=this.context.createBiquadFilter();C.type=I.type,C.frequency.value=I.frequency.value,C.Q.value=I.Q.value,C.gain.value=I.gain.value,t.addFilter(C)}),this.panType==="HRTF"?(t.threeDOptions=this.threeDOptions,t.position=this.position):this.panType==="stereo"&&(t.stereoPan=this.stereoPan),t.on("error",I=>{this.emitAsync("soundError",{url:this.url,error:I.error,errorType:"playback",timestamp:I.timestamp,recoverable:I.recoverable})}),this.playbacks.push(t),[t]}catch(e){const g={url:this.url,error:e,errorType:"playback",timestamp:Date.now(),recoverable:!0};throw this.emitAsync("soundError",g),e}}play(e){const g=super.play();if(this.emit("play",g[0]),e)for(const t of g)e.fadeIn!==void 0&&t.fadeIn(e.fadeIn,e.fadeType,{perLoop:e.fadeInPerLoop}),e.fadeOut!==void 0&&t.configureFadeOut(e.fadeOut,e.fadeType);return g}stop(){super.stop(),this.emit("stop",void 0)}pause(){super.pause(),this.emit("pause",void 0)}seek(e){this.playbacks.forEach(g=>g.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(g=>g.loop(e)),this.loopCount)}get playbackRate(){return this._playbackRate}set playbackRate(e){this._playbackRate=e,this.playbacks.forEach(g=>g.playbackRate=e),this.emit("rateChange",e)}set volume(e){super.volume=e,this.emit("volumeChange",e)}cleanup(){this.playbacks.forEach(e=>e.cleanup()),this.playbacks=[],this.eventEmitter.removeAllListeners()}}const P=(a,e)=>{var g=new Uint8Array(a.byteLength+e.byteLength);return g.set(new Uint8Array(a),0),g.set(new Uint8Array(e),a.byteLength),g.buffer};function T(a,e,g){const t=[];let I=0,C;if(g?.aborted){console.error("Stream error:",new DOMException("Operation was aborted","AbortError"));return}fetch(a,g?{signal:g}:void 0).then(function(o){if(!o.ok)throw new Error("HTTP error, status = "+o.status);if(!o.body)throw new Error("Missing body");C=o.body.getReader();let s=new ArrayBuffer(0);const A=()=>{t.length=0,C&&C.cancel("Stream aborted").catch(()=>{})};g?.addEventListener("abort",A);function n(){return g?.aborted?(A(),Promise.resolve()):C.read().then(({value:c,done:h})=>{if(g?.aborted){A();return}let d=null;if(c){if(s.byteLength?d=P(s,c.buffer):(s=c.buffer.slice(0,44),d=c.buffer),e.decodeAudioData(d,function(m){g?.aborted||(t.push(m),t.length&&i())},function(m){console.log("err(decodeAudioData): "+m)}),h){console.log("done"),g?.removeEventListener("abort",A);return}n()}}).catch(c=>{g?.aborted||c.name==="AbortError"||console.error("Stream read error:",c)})}n()}).catch(function(o){console.error("Stream error:",o)});function i(){for(;t.length;){let o=t.shift();const s=e.createBufferSource();if(!o)return;s.buffer=o,s.connect(e.destination),I==0&&(I=e.currentTime+.02),s.start(I),I+=s.buffer.duration}}}function M(a){class e extends W{_oscillatorOptions={};get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(t){this._oscillatorOptions=t,this.source&&this.source instanceof OscillatorNode&&(this.oscillatorOptions.detune&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency&&(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&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency&&(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&&this.source.stop&&(this.source.stop(),this._playing=!1)}pause(){this.stop()}get frequency(){return this.source.frequency.value}set frequency(t){this.source.frequency.value=t,this.oscillatorOptions.frequency=t}get detune(){return this.source.detune.value}set detune(t){this.source.detune.value=t,this.oscillatorOptions.detune=t}get type(){return this.source.type}set type(t){this.source.type=t,this.oscillatorOptions.type=t}}return e}class z extends M(K(F(p))){constructor(e,g,t){super(),this.origin=e,this.source=g,this.context=e.context,this.setPanType(e.panType,e.context),this.source.connect(this.panner),this.setGainNode(t),this.panner.connect(this.gainNode),this.refreshFilters()}context;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()}}class G extends H(p){constructor(e,g,t=B.Oscillator,I="HRTF",C={},i){super(),this.context=e,this.globalGainNode=g,this.soundType=t,this.panType=I,this.cacophony=i,this.context=e,this._oscillatorOptions=C}_oscillatorOptions;playbacks=[];eventEmitter=new y;on(e,g){this.eventEmitter.on(e,g)}off(e,g){this.eventEmitter.off(e,g)}emit(e,g){this.eventEmitter.emit(e,g)}async emitAsync(e,g){return this.eventEmitter.emitAsync(e,g)}clone(e={}){const g=e.panType||this.panType,t=e.stereoPan!==void 0?e.stereoPan:this.stereoPan??0,I=e.threeDOptions||this.threeDOptions,C=e.volume!==void 0?e.volume:this.volume,i=e.position&&e.position.length?e.position:this.position,o=e.filters&&e.filters.length?e.filters:this._filters,s=e.oscillatorOptions||this._oscillatorOptions,A=new G(this.context,this.globalGainNode,this.soundType,g,s,this.cacophony);return A._volume=C,A._position=i,A._stereoPan=t,A._threeDOptions=I,A.addFilters(o),A}preplay(){const e=this.context.createOscillator();return this.createPlayback(e)}createPlayback(e){this.oscillatorOptions.detune&&(e.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency&&(e.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(e.type=this.oscillatorOptions.type);const g=this.context.createGain();g.connect(this.globalGainNode);const t=new z(this,e,g);return t.volume=this.volume,this._filters.forEach(I=>{const C=this.context.createBiquadFilter();C.type=I.type,C.frequency.value=I.frequency.value,C.Q.value=I.Q.value,C.gain.value=I.gain.value,t.addFilter(C)}),this.panType==="HRTF"?(t.threeDOptions=this.threeDOptions,t.position=this.position):this.panType==="stereo"&&(t.stereoPan=this.stereoPan),this.playbacks.push(t),[t]}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()})}get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(e){this._oscillatorOptions=e,this.playbacks.forEach(g=>{g.source instanceof OscillatorNode&&(this.oscillatorOptions.detune&&(g.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency&&(g.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(g.source.type=this.oscillatorOptions.type))})}get frequency(){return this.oscillatorOptions.frequency||440}set frequency(e){this._oscillatorOptions.frequency=e,this.playbacks.forEach(g=>g.frequency=e),this.emit("frequencyChange",e)}get detune(){return this.oscillatorOptions.detune}set detune(e){this._oscillatorOptions.detune=e,this.playbacks.forEach(g=>g.detune=e),this.emit("detuneChange",e)}get type(){return this.oscillatorOptions.type||"sine"}set type(e){this._oscillatorOptions.type=e,this.playbacks.forEach(g=>g.type=e),this.emit("typeChange",e)}}var B=(a=>(a.HTML="HTML",a.Streaming="Streaming",a.Buffer="Buffer",a.Oscillator="oscillator",a))(B||{});class Q{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;eventEmitter=new y;cache;constructor(e,g){this.context=e||new V.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.cache=g||new r,this.finalizationRegistry=new FinalizationRegistry(t=>{t.cleanup()})}on(e,g){this.eventEmitter.on(e,g)}off(e,g){this.eventEmitter.off(e,g)}emit(e,g){this.eventEmitter.emit(e,g)}async emitAsync(e,g){return this.eventEmitter.emitAsync(e,g)}async loadWorklets(e){this.context.audioWorklet?await this.createWorkletNode("phase-vocoder",E,e):console.warn("AudioWorklet not supported")}async createWorkletNode(e,g,t){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{return new V.AudioWorkletNode(this.context,e)}catch(I){console.error(I),console.log("Loading worklet from url",g);try{await this.context.audioWorklet.addModule(g,{credentials:"same-origin",...t&&{signal:t}})}catch(C){throw console.error(C),C}return new V.AudioWorkletNode(this.context,e)}}clearMemoryCache(){this.cache.clearMemoryCache()}createOscillator(e,g="HRTF"){return new G(this.context,this.globalGainNode,"oscillator",g,e,this)}async createSound(e,g="Buffer",t="HRTF",I){if(typeof e=="object")return Promise.resolve(new u("",e,this.context,this.globalGainNode,"Buffer",t,this));const C=e;if(g==="HTML"){const i=new Audio;return i.src=C,i.crossOrigin="anonymous",Promise.resolve(new u(C,void 0,this.context,this.globalGainNode,"HTML",t,this))}return g==="Streaming"?Promise.resolve(new u(C,void 0,this.context,this.globalGainNode,"Streaming",t,this)):this.cache.getAudioBuffer(this.context,C,I,{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 u(C,i,this.context,this.globalGainNode,g,t,this))}async createGroup(e){const g=new X;return e.forEach(t=>g.addSound(t)),g}async createGroupFromUrls(e,g="Buffer",t="HRTF",I){const C=new X;return(await Promise.all(e.map(o=>this.createSound(o,g,t,I)))).forEach(o=>C.addSound(o)),C}async createStream(e,g){return T(e,this.context,g),new u(e,void 0,this.context,this.globalGainNode,"Streaming","HRTF",this)}createBiquadFilter=({type:e,frequency:g,gain:t,Q:I})=>{g===void 0&&(g=350);const C=this.context.createBiquadFilter();return C.type=e||"lowpass",C.frequency.value=g,C.gain.value=t||0,C.Q.value=I||1,C};createPanner({coneInnerAngle:e,coneOuterAngle:g,coneOuterGain:t,distanceModel:I,maxDistance:C,channelCount:i,channelCountMode:o,channelInterpretation:s,panningModel:A,refDistance:n,rolloffFactor:c,positionX:h,positionY:d,positionZ:m,orientationX:b,orientationY:f,orientationZ:k}){const l=this.context.createPanner();return l.coneInnerAngle=e||360,l.coneOuterAngle=g||360,l.coneOuterGain=t||0,l.distanceModel=I||"inverse",l.maxDistance=C||1e4,l.channelCount=i||2,l.channelCountMode=o||"clamped-max",l.channelInterpretation=s||"speakers",l.panningModel=A||"HRTF",l.refDistance=n||1,l.rolloffFactor=c||1,l.positionX.value=h||0,l.positionY.value=d||0,l.positionZ.value=m||0,l.orientationX.value=b||0,l.orientationY.value=f||0,l.orientationZ.value=k||0,l}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(e){this.globalGainNode.gain.value=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))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(e){e!==this.muted&&(e?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((e,g)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(t=>{const I=new N(this.context);I.play(),e(I)}).catch(t=>{g(t)})})}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:g,up:t}=e,[I,C,i]=g,[o,s,A]=t;this.listener.forwardX.value=I,this.listener.forwardY.value=C,this.listener.forwardZ.value=i,this.listener.upX.value=o,this.listener.upY.value=s,this.listener.upZ.value=A}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(e){const[g,t,I]=e;this.listener.upX.value=g,this.listener.upY.value=t,this.listener.upZ.value=I}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(e){const[g,t,I]=e;this.listener.forwardX.value=g,this.listener.forwardY.value=t,this.listener.forwardZ.value=I}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(e){const[g,t,I]=e,C=this.context.currentTime;this.listener.positionX.setValueAtTime(g,C),this.listener.positionY.setValueAtTime(t,C),this.listener.positionZ.setValueAtTime(I,C)}}class J{constructor(e=[]){this.synths=e}addSynth(e){this.synths.push(e)}removeSynth(e){const g=this.synths.indexOf(e);if(g!==-1)this.synths.splice(g,1);else throw new Error("Synth not found in group")}play(){this.synths.forEach(e=>e.play())}stop(){this.synths.forEach(e=>e.stop())}setVolume(e){this.synths.forEach(g=>g.volume=e)}set stereoPan(e){this.synths.forEach(g=>g.stereoPan=e)}set position(e){this.synths.forEach(g=>g.position=e)}}exports.Cacophony=Q;exports.Group=X;exports.MicrophonePlayback=S;exports.Playback=Z;exports.Sound=u;exports.SoundType=B;exports.Synth=G;exports.SynthGroup=J;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|