speechrecorderng 3.6.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/esm2022/lib/action/action.mjs +73 -0
  2. package/{esm2020 → esm2022}/lib/audio/array_audio_buffer.mjs +163 -163
  3. package/{esm2020 → esm2022}/lib/audio/array_audio_buffer_input_stream.mjs +85 -85
  4. package/{esm2020 → esm2022}/lib/audio/array_audio_buffer_random_access_stream.mjs +15 -15
  5. package/esm2022/lib/audio/audio_data_holder.mjs +264 -0
  6. package/{esm2020 → esm2022}/lib/audio/audio_display.mjs +93 -93
  7. package/{esm2020 → esm2022}/lib/audio/audio_player.mjs +213 -213
  8. package/esm2022/lib/audio/capture/capture.mjs +855 -0
  9. package/esm2022/lib/audio/context.mjs +79 -0
  10. package/{esm2020 → esm2022}/lib/audio/dsp/level_measure.mjs +515 -515
  11. package/{esm2020 → esm2022}/lib/audio/format.mjs +16 -16
  12. package/esm2022/lib/audio/impl/wavformat.mjs +6 -0
  13. package/{esm2020 → esm2022}/lib/audio/impl/wavreader.mjs +133 -133
  14. package/esm2022/lib/audio/impl/wavwriter.mjs +105 -0
  15. package/esm2022/lib/audio/inddb_audio_buffer.mjs +508 -0
  16. package/{esm2020 → esm2022}/lib/audio/io/stream.mjs +58 -58
  17. package/esm2022/lib/audio/net_audio_buffer.mjs +293 -0
  18. package/{esm2020 → esm2022}/lib/audio/persistor.mjs +80 -80
  19. package/{esm2020 → esm2022}/lib/audio/playback/array_audio_buffer_source_node.mjs +125 -125
  20. package/esm2022/lib/audio/playback/audio_source_node.mjs +18 -0
  21. package/esm2022/lib/audio/playback/audio_source_worklet_module_loader.mjs +167 -0
  22. package/{esm2020 → esm2022}/lib/audio/playback/inddb_audio_buffer_source_node.mjs +166 -166
  23. package/{esm2020 → esm2022}/lib/audio/playback/net_audio_buffer_source_node.mjs +217 -217
  24. package/esm2022/lib/audio/playback/player.mjs +402 -0
  25. package/esm2022/lib/audio/ui/audio_canvas_layer_comp.mjs +347 -0
  26. package/{esm2020 → esm2022}/lib/audio/ui/audio_display_control.mjs +65 -65
  27. package/{esm2020 → esm2022}/lib/audio/ui/audio_display_scroll_pane.mjs +139 -139
  28. package/{esm2020 → esm2022}/lib/audio/ui/audiosignal.mjs +524 -524
  29. package/{esm2020 → esm2022}/lib/audio/ui/common.mjs +18 -18
  30. package/esm2022/lib/audio/ui/container.mjs +414 -0
  31. package/{esm2020 → esm2022}/lib/audio/ui/livelevel.mjs +352 -352
  32. package/esm2022/lib/audio/ui/scroll_pane_horizontal.mjs +11 -0
  33. package/esm2022/lib/audio/ui/sonagram.mjs +900 -0
  34. package/esm2022/lib/db/inddb.mjs +120 -0
  35. package/esm2022/lib/dsp/utils.mjs +48 -0
  36. package/{esm2020 → esm2022}/lib/io/BinaryReader.mjs +84 -84
  37. package/esm2022/lib/io/BinaryWriter.mjs +74 -0
  38. package/{esm2020 → esm2022}/lib/io/stream.mjs +258 -258
  39. package/{esm2020 → esm2022}/lib/math/2d/geometry.mjs +27 -27
  40. package/esm2022/lib/math/complex.mjs +58 -0
  41. package/{esm2020 → esm2022}/lib/math/dft.mjs +195 -195
  42. package/{esm2020 → esm2022}/lib/media/utils.mjs +13 -13
  43. package/esm2022/lib/net/uploader.mjs +367 -0
  44. package/{esm2020 → esm2022}/lib/recorder_component.mjs +64 -64
  45. package/esm2022/lib/speechrecorder/project/project.mjs +49 -0
  46. package/esm2022/lib/speechrecorder/project/project.service.mjs +64 -0
  47. package/{esm2020 → esm2022}/lib/speechrecorder/recording.mjs +123 -123
  48. package/esm2022/lib/speechrecorder/recordings/basic_recording.service.mjs +218 -0
  49. package/esm2022/lib/speechrecorder/recordings/recordings.service.mjs +1014 -0
  50. package/{esm2020 → esm2022}/lib/speechrecorder/script/script.mjs +114 -114
  51. package/{esm2020 → esm2022}/lib/speechrecorder/script/script.service.mjs +47 -47
  52. package/esm2022/lib/speechrecorder/session/audiorecorder.mjs +1179 -0
  53. package/esm2022/lib/speechrecorder/session/basicrecorder.mjs +668 -0
  54. package/esm2022/lib/speechrecorder/session/controlpanel.mjs +416 -0
  55. package/{esm2020 → esm2022}/lib/speechrecorder/session/item.mjs +29 -29
  56. package/{esm2020 → esm2022}/lib/speechrecorder/session/progress.mjs +69 -69
  57. package/{esm2020 → esm2022}/lib/speechrecorder/session/prompting.mjs +571 -571
  58. package/{esm2020 → esm2022}/lib/speechrecorder/session/recorder_combi_pane.mjs +65 -65
  59. package/esm2022/lib/speechrecorder/session/recording_file_cache.mjs +195 -0
  60. package/{esm2020 → esm2022}/lib/speechrecorder/session/recording_list.mjs +103 -103
  61. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +63 -63
  62. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +51 -51
  63. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +104 -104
  64. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +381 -381
  65. package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file.mjs +67 -67
  66. package/esm2022/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +288 -0
  67. package/{esm2020 → esm2022}/lib/speechrecorder/session/session.mjs +1 -1
  68. package/esm2022/lib/speechrecorder/session/session.service.mjs +69 -0
  69. package/{esm2020 → esm2022}/lib/speechrecorder/session/session_finished_dialog.mjs +29 -29
  70. package/esm2022/lib/speechrecorder/session/sessionmanager.mjs +1386 -0
  71. package/{esm2020 → esm2022}/lib/speechrecorder/session/warning_bar.mjs +28 -28
  72. package/{esm2020 → esm2022}/lib/speechrecorder/spruploader.mjs +22 -22
  73. package/{esm2020 → esm2022}/lib/speechrecorder/startstopsignal/startstopsignal.mjs +1 -1
  74. package/esm2022/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +57 -0
  75. package/{esm2020 → esm2022}/lib/speechrecorderng.component.mjs +388 -388
  76. package/{esm2020 → esm2022}/lib/speechrecorderng.module.mjs +100 -100
  77. package/{esm2020 → esm2022}/lib/spr.config.mjs +26 -26
  78. package/{esm2020 → esm2022}/lib/spr.module.version.mjs +2 -2
  79. package/{esm2020 → esm2022}/lib/ui/canvas_layer_comp.mjs +38 -38
  80. package/{esm2020 → esm2022}/lib/ui/message_dialog.mjs +30 -30
  81. package/esm2022/lib/ui/recordingitem_display.mjs +253 -0
  82. package/{esm2020 → esm2022}/lib/ui/responsive_component.mjs +24 -24
  83. package/{esm2020 → esm2022}/lib/utils/scrollIntoViewToBottom.mjs +23 -23
  84. package/esm2022/lib/utils/ua-parser.mjs +190 -0
  85. package/esm2022/lib/utils/utils.mjs +105 -0
  86. package/esm2022/lib/utils/wake_lock.mjs +114 -0
  87. package/{esm2020 → esm2022}/lib/utils/wake_lock_media.mjs +1 -1
  88. package/{esm2020 → esm2022}/public-api.mjs +33 -33
  89. package/{esm2020 → esm2022}/speechrecorderng.mjs +4 -4
  90. package/{fesm2020 → fesm2022}/speechrecorderng.mjs +16518 -16454
  91. package/fesm2022/speechrecorderng.mjs.map +1 -0
  92. package/index.d.ts +5 -5
  93. package/lib/action/action.d.ts +27 -27
  94. package/lib/audio/array_audio_buffer.d.ts +31 -31
  95. package/lib/audio/array_audio_buffer_input_stream.d.ts +14 -14
  96. package/lib/audio/array_audio_buffer_random_access_stream.d.ts +9 -9
  97. package/lib/audio/audio_data_holder.d.ts +84 -84
  98. package/lib/audio/audio_display.d.ts +36 -36
  99. package/lib/audio/audio_player.d.ts +47 -47
  100. package/lib/audio/capture/capture.d.ts +67 -67
  101. package/lib/audio/context.d.ts +6 -6
  102. package/lib/audio/dsp/level_measure.d.ts +60 -60
  103. package/lib/audio/format.d.ts +11 -11
  104. package/lib/audio/impl/wavformat.d.ts +5 -5
  105. package/lib/audio/impl/wavreader.d.ts +16 -16
  106. package/lib/audio/impl/wavwriter.d.ts +13 -13
  107. package/lib/audio/inddb_audio_buffer.d.ts +68 -68
  108. package/lib/audio/io/stream.d.ts +28 -28
  109. package/lib/audio/net_audio_buffer.d.ts +57 -57
  110. package/lib/audio/persistor.d.ts +29 -29
  111. package/lib/audio/playback/array_audio_buffer_source_node.d.ts +18 -18
  112. package/lib/audio/playback/audio_source_node.d.ts +10 -10
  113. package/lib/audio/playback/audio_source_worklet_module_loader.d.ts +4 -4
  114. package/lib/audio/playback/inddb_audio_buffer_source_node.d.ts +21 -21
  115. package/lib/audio/playback/net_audio_buffer_source_node.d.ts +27 -27
  116. package/lib/audio/playback/player.d.ts +65 -65
  117. package/lib/audio/ui/audio_canvas_layer_comp.d.ts +68 -68
  118. package/lib/audio/ui/audio_display_control.d.ts +25 -25
  119. package/lib/audio/ui/audio_display_scroll_pane.d.ts +26 -26
  120. package/lib/audio/ui/audiosignal.d.ts +30 -30
  121. package/lib/audio/ui/common.d.ts +11 -11
  122. package/lib/audio/ui/container.d.ts +63 -63
  123. package/lib/audio/ui/livelevel.d.ts +60 -60
  124. package/lib/audio/ui/scroll_pane_horizontal.d.ts +5 -5
  125. package/lib/audio/ui/sonagram.d.ts +37 -37
  126. package/lib/db/inddb.d.ts +21 -21
  127. package/lib/dsp/utils.d.ts +19 -19
  128. package/lib/io/BinaryReader.d.ts +18 -18
  129. package/lib/io/BinaryWriter.d.ts +15 -15
  130. package/lib/io/stream.d.ts +59 -59
  131. package/lib/math/2d/geometry.d.ts +18 -18
  132. package/lib/math/complex.d.ts +17 -17
  133. package/lib/math/dft.d.ts +22 -22
  134. package/lib/media/utils.d.ts +3 -3
  135. package/lib/net/uploader.d.ts +81 -81
  136. package/lib/recorder_component.d.ts +16 -16
  137. package/lib/speechrecorder/project/project.d.ts +59 -59
  138. package/lib/speechrecorder/project/project.service.d.ts +21 -21
  139. package/lib/speechrecorder/recording.d.ts +51 -51
  140. package/lib/speechrecorder/recordings/basic_recording.service.d.ts +27 -27
  141. package/lib/speechrecorder/recordings/recordings.service.d.ts +48 -48
  142. package/lib/speechrecorder/script/script.d.ts +80 -79
  143. package/lib/speechrecorder/script/script.service.d.ts +16 -16
  144. package/lib/speechrecorder/session/audiorecorder.d.ts +122 -122
  145. package/lib/speechrecorder/session/basicrecorder.d.ts +139 -139
  146. package/lib/speechrecorder/session/controlpanel.d.ts +109 -107
  147. package/lib/speechrecorder/session/item.d.ts +12 -12
  148. package/lib/speechrecorder/session/progress.d.ts +17 -17
  149. package/lib/speechrecorder/session/prompting.d.ts +121 -121
  150. package/lib/speechrecorder/session/recorder_combi_pane.d.ts +32 -32
  151. package/lib/speechrecorder/session/recording_file_cache.d.ts +33 -33
  152. package/lib/speechrecorder/session/recording_list.d.ts +24 -24
  153. package/lib/speechrecorder/session/recordingfile/recording-file-meta.component.d.ts +15 -15
  154. package/lib/speechrecorder/session/recordingfile/recording-file-navi.component.d.ts +20 -20
  155. package/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.d.ts +31 -31
  156. package/lib/speechrecorder/session/recordingfile/recording-file-view.component.d.ts +55 -55
  157. package/lib/speechrecorder/session/recordingfile/recording-file.d.ts +7 -7
  158. package/lib/speechrecorder/session/recordingfile/recordingfile-service.d.ts +24 -24
  159. package/lib/speechrecorder/session/session.d.ts +15 -15
  160. package/lib/speechrecorder/session/session.service.d.ts +20 -20
  161. package/lib/speechrecorder/session/session_finished_dialog.d.ts +10 -10
  162. package/lib/speechrecorder/session/sessionmanager.d.ts +129 -123
  163. package/lib/speechrecorder/session/warning_bar.d.ts +8 -8
  164. package/lib/speechrecorder/spruploader.d.ts +11 -11
  165. package/lib/speechrecorder/startstopsignal/startstopsignal.d.ts +10 -10
  166. package/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.d.ts +11 -11
  167. package/lib/speechrecorderng.component.d.ts +61 -61
  168. package/lib/speechrecorderng.module.d.ts +56 -56
  169. package/lib/spr.config.d.ts +17 -17
  170. package/lib/spr.module.version.d.ts +1 -1
  171. package/lib/ui/canvas_layer_comp.d.ts +13 -13
  172. package/lib/ui/message_dialog.d.ts +10 -10
  173. package/lib/ui/recordingitem_display.d.ts +84 -84
  174. package/lib/ui/responsive_component.d.ts +9 -9
  175. package/lib/utils/scrollIntoViewToBottom.d.ts +9 -9
  176. package/lib/utils/ua-parser.d.ts +43 -43
  177. package/lib/utils/utils.d.ts +19 -19
  178. package/lib/utils/wake_lock.d.ts +23 -23
  179. package/lib/utils/wake_lock_media.d.ts +1 -1
  180. package/package.json +17 -23
  181. package/public-api.d.ts +33 -33
  182. package/esm2020/lib/action/action.mjs +0 -73
  183. package/esm2020/lib/audio/audio_data_holder.mjs +0 -264
  184. package/esm2020/lib/audio/capture/capture.mjs +0 -855
  185. package/esm2020/lib/audio/context.mjs +0 -79
  186. package/esm2020/lib/audio/impl/wavformat.mjs +0 -6
  187. package/esm2020/lib/audio/impl/wavwriter.mjs +0 -105
  188. package/esm2020/lib/audio/inddb_audio_buffer.mjs +0 -508
  189. package/esm2020/lib/audio/net_audio_buffer.mjs +0 -293
  190. package/esm2020/lib/audio/playback/audio_source_node.mjs +0 -18
  191. package/esm2020/lib/audio/playback/audio_source_worklet_module_loader.mjs +0 -167
  192. package/esm2020/lib/audio/playback/player.mjs +0 -402
  193. package/esm2020/lib/audio/ui/audio_canvas_layer_comp.mjs +0 -347
  194. package/esm2020/lib/audio/ui/container.mjs +0 -414
  195. package/esm2020/lib/audio/ui/scroll_pane_horizontal.mjs +0 -11
  196. package/esm2020/lib/audio/ui/sonagram.mjs +0 -900
  197. package/esm2020/lib/db/inddb.mjs +0 -120
  198. package/esm2020/lib/dsp/utils.mjs +0 -48
  199. package/esm2020/lib/io/BinaryWriter.mjs +0 -74
  200. package/esm2020/lib/math/complex.mjs +0 -58
  201. package/esm2020/lib/net/uploader.mjs +0 -367
  202. package/esm2020/lib/speechrecorder/project/project.mjs +0 -49
  203. package/esm2020/lib/speechrecorder/project/project.service.mjs +0 -64
  204. package/esm2020/lib/speechrecorder/recordings/basic_recording.service.mjs +0 -216
  205. package/esm2020/lib/speechrecorder/recordings/recordings.service.mjs +0 -1014
  206. package/esm2020/lib/speechrecorder/session/audiorecorder.mjs +0 -1179
  207. package/esm2020/lib/speechrecorder/session/basicrecorder.mjs +0 -666
  208. package/esm2020/lib/speechrecorder/session/controlpanel.mjs +0 -409
  209. package/esm2020/lib/speechrecorder/session/recording_file_cache.mjs +0 -195
  210. package/esm2020/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +0 -288
  211. package/esm2020/lib/speechrecorder/session/session.service.mjs +0 -69
  212. package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +0 -1333
  213. package/esm2020/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +0 -57
  214. package/esm2020/lib/ui/recordingitem_display.mjs +0 -253
  215. package/esm2020/lib/utils/ua-parser.mjs +0 -190
  216. package/esm2020/lib/utils/utils.mjs +0 -105
  217. package/esm2020/lib/utils/wake_lock.mjs +0 -114
  218. package/fesm2015/speechrecorderng.mjs +0 -17708
  219. package/fesm2015/speechrecorderng.mjs.map +0 -1
  220. package/fesm2020/speechrecorderng.mjs.map +0 -1
@@ -1,126 +1,126 @@
1
- import { ArrayAudioBufferInputStream } from "../array_audio_buffer_input_stream";
2
- import { EditFloat32ArrayInputStream } from "../../io/stream";
3
- import { AudioSourceNode } from "./audio_source_node";
4
- export class ArrayAudioBufferSourceNode extends AudioSourceNode {
5
- constructor(context) {
6
- super(context, 'audio-source-worklet');
7
- this._bufferFillSeconds = AudioSourceNode.DEFAULT_BUFFER_FILL_SECONDS;
8
- this.bufferFillFrames = 0;
9
- this._arrayAudioBuffer = null;
10
- this._audioInputStream = null;
11
- this._aisBufs = null;
12
- this.filledFrames = 0;
13
- this.channelCountMode = 'explicit';
14
- this.port.onmessage = (msgEv) => {
15
- if (msgEv.data) {
16
- let evType = msgEv.data.eventType;
17
- if (evType) {
18
- if ('bufferNotification' === evType) {
19
- this.filledFrames = msgEv.data.filledFrames;
20
- //console.debug("Buffer notification: filled frames: " + this.filledFrames);
21
- this.fillBuffer();
22
- }
23
- else if ('ended' === evType) {
24
- let drainTime = 0;
25
- if (this._arrayAudioBuffer?.sampleRate) {
26
- drainTime = ArrayAudioBufferSourceNode.QUANTUM_FRAME_LEN / this._arrayAudioBuffer.sampleRate;
27
- }
28
- //let dstAny:any=this.context.destination;
29
- //console.debug('Destination node tail-time: '+dstAny['tail-time']);
30
- window.setTimeout(() => {
31
- this.onended?.call(this);
32
- }, drainTime * 1000);
33
- }
34
- }
35
- }
36
- };
37
- }
38
- fillBuffer() {
39
- if (this._arrayAudioBuffer && this._audioInputStream && this._aisBufs) {
40
- let filled = this.filledFrames;
41
- let bufLen = 0;
42
- while (filled < this.bufferFillFrames) {
43
- let read = this._audioInputStream.read(this._aisBufs);
44
- //console.log("ArrayAudioBufferSourceNode: read: "+read)
45
- if (read) {
46
- let trBuffers = new Array(this.channelCount);
47
- for (let ch = 0; ch < this.channelCount; ch++) {
48
- let adCh = this._aisBufs[ch];
49
- let adChCopy = new Float32Array(adCh.length);
50
- bufLen = adChCopy.length;
51
- adChCopy.set(adCh);
52
- trBuffers[ch] = adChCopy.buffer;
53
- }
54
- this.port.postMessage({
55
- cmd: 'data',
56
- chs: this.channelCount,
57
- audioData: trBuffers
58
- }, trBuffers);
59
- filled += read;
60
- }
61
- else {
62
- this.port.postMessage({
63
- cmd: 'endOfStream'
64
- });
65
- break;
66
- }
67
- }
68
- }
69
- }
70
- get arrayAudioBuffer() {
71
- return this._arrayAudioBuffer;
72
- }
73
- set arrayAudioBuffer(value) {
74
- this._arrayAudioBuffer = value;
75
- if (this._arrayAudioBuffer?.channelCount) {
76
- this.channelCount = this._arrayAudioBuffer?.channelCount;
77
- this.bufferFillFrames = this._arrayAudioBuffer.sampleRate * this._bufferFillSeconds;
78
- }
79
- }
80
- get bufferFillSeconds() {
81
- return this._bufferFillSeconds;
82
- }
83
- set bufferFillSeconds(value) {
84
- this._bufferFillSeconds = value;
85
- }
86
- start(when, offset, duration) {
87
- if (when) {
88
- throw Error("when parameter currently not supported by ArrayAudioBufferSourceNode class");
89
- }
90
- if (this._arrayAudioBuffer) {
91
- let arrAis = new ArrayAudioBufferInputStream(this._arrayAudioBuffer);
92
- if (offset === undefined && duration === undefined) {
93
- this._audioInputStream = arrAis;
94
- }
95
- else {
96
- let offsetFrames = 0;
97
- let durationFrames = undefined;
98
- if (offset !== undefined) {
99
- offsetFrames = Math.floor(offset * this._arrayAudioBuffer.sampleRate);
100
- }
101
- if (duration !== undefined) {
102
- durationFrames = Math.floor(duration * this._arrayAudioBuffer.sampleRate);
103
- }
104
- this._audioInputStream = new EditFloat32ArrayInputStream(arrAis, offsetFrames, durationFrames);
105
- }
106
- let chs = this._arrayAudioBuffer.channelCount;
107
- this._aisBufs = new Array(chs);
108
- for (let ch = 0; ch < chs; ch++) {
109
- this._aisBufs[ch] = new Float32Array(ArrayAudioBufferSourceNode.DEFAULT_STREAM_READ_FRAME_LEN);
110
- }
111
- this.fillBuffer();
112
- this.port.postMessage({ cmd: 'start' });
113
- if (offset) {
114
- this._playStartTime = this.context.currentTime - offset;
115
- }
116
- else {
117
- this._playStartTime = this.context.currentTime;
118
- }
119
- }
120
- }
121
- stop() {
122
- this.port.postMessage({ cmd: 'stop' });
123
- this.onended?.call(this);
124
- }
125
- }
1
+ import { ArrayAudioBufferInputStream } from "../array_audio_buffer_input_stream";
2
+ import { EditFloat32ArrayInputStream } from "../../io/stream";
3
+ import { AudioSourceNode } from "./audio_source_node";
4
+ export class ArrayAudioBufferSourceNode extends AudioSourceNode {
5
+ constructor(context) {
6
+ super(context, 'audio-source-worklet');
7
+ this._bufferFillSeconds = AudioSourceNode.DEFAULT_BUFFER_FILL_SECONDS;
8
+ this.bufferFillFrames = 0;
9
+ this._arrayAudioBuffer = null;
10
+ this._audioInputStream = null;
11
+ this._aisBufs = null;
12
+ this.filledFrames = 0;
13
+ this.channelCountMode = 'explicit';
14
+ this.port.onmessage = (msgEv) => {
15
+ if (msgEv.data) {
16
+ let evType = msgEv.data.eventType;
17
+ if (evType) {
18
+ if ('bufferNotification' === evType) {
19
+ this.filledFrames = msgEv.data.filledFrames;
20
+ //console.debug("Buffer notification: filled frames: " + this.filledFrames);
21
+ this.fillBuffer();
22
+ }
23
+ else if ('ended' === evType) {
24
+ let drainTime = 0;
25
+ if (this._arrayAudioBuffer?.sampleRate) {
26
+ drainTime = ArrayAudioBufferSourceNode.QUANTUM_FRAME_LEN / this._arrayAudioBuffer.sampleRate;
27
+ }
28
+ //let dstAny:any=this.context.destination;
29
+ //console.debug('Destination node tail-time: '+dstAny['tail-time']);
30
+ window.setTimeout(() => {
31
+ this.onended?.call(this);
32
+ }, drainTime * 1000);
33
+ }
34
+ }
35
+ }
36
+ };
37
+ }
38
+ fillBuffer() {
39
+ if (this._arrayAudioBuffer && this._audioInputStream && this._aisBufs) {
40
+ let filled = this.filledFrames;
41
+ let bufLen = 0;
42
+ while (filled < this.bufferFillFrames) {
43
+ let read = this._audioInputStream.read(this._aisBufs);
44
+ //console.log("ArrayAudioBufferSourceNode: read: "+read)
45
+ if (read) {
46
+ let trBuffers = new Array(this.channelCount);
47
+ for (let ch = 0; ch < this.channelCount; ch++) {
48
+ let adCh = this._aisBufs[ch];
49
+ let adChCopy = new Float32Array(adCh.length);
50
+ bufLen = adChCopy.length;
51
+ adChCopy.set(adCh);
52
+ trBuffers[ch] = adChCopy.buffer;
53
+ }
54
+ this.port.postMessage({
55
+ cmd: 'data',
56
+ chs: this.channelCount,
57
+ audioData: trBuffers
58
+ }, trBuffers);
59
+ filled += read;
60
+ }
61
+ else {
62
+ this.port.postMessage({
63
+ cmd: 'endOfStream'
64
+ });
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ get arrayAudioBuffer() {
71
+ return this._arrayAudioBuffer;
72
+ }
73
+ set arrayAudioBuffer(value) {
74
+ this._arrayAudioBuffer = value;
75
+ if (this._arrayAudioBuffer?.channelCount) {
76
+ this.channelCount = this._arrayAudioBuffer?.channelCount;
77
+ this.bufferFillFrames = this._arrayAudioBuffer.sampleRate * this._bufferFillSeconds;
78
+ }
79
+ }
80
+ get bufferFillSeconds() {
81
+ return this._bufferFillSeconds;
82
+ }
83
+ set bufferFillSeconds(value) {
84
+ this._bufferFillSeconds = value;
85
+ }
86
+ start(when, offset, duration) {
87
+ if (when) {
88
+ throw Error("when parameter currently not supported by ArrayAudioBufferSourceNode class");
89
+ }
90
+ if (this._arrayAudioBuffer) {
91
+ let arrAis = new ArrayAudioBufferInputStream(this._arrayAudioBuffer);
92
+ if (offset === undefined && duration === undefined) {
93
+ this._audioInputStream = arrAis;
94
+ }
95
+ else {
96
+ let offsetFrames = 0;
97
+ let durationFrames = undefined;
98
+ if (offset !== undefined) {
99
+ offsetFrames = Math.floor(offset * this._arrayAudioBuffer.sampleRate);
100
+ }
101
+ if (duration !== undefined) {
102
+ durationFrames = Math.floor(duration * this._arrayAudioBuffer.sampleRate);
103
+ }
104
+ this._audioInputStream = new EditFloat32ArrayInputStream(arrAis, offsetFrames, durationFrames);
105
+ }
106
+ let chs = this._arrayAudioBuffer.channelCount;
107
+ this._aisBufs = new Array(chs);
108
+ for (let ch = 0; ch < chs; ch++) {
109
+ this._aisBufs[ch] = new Float32Array(ArrayAudioBufferSourceNode.DEFAULT_STREAM_READ_FRAME_LEN);
110
+ }
111
+ this.fillBuffer();
112
+ this.port.postMessage({ cmd: 'start' });
113
+ if (offset) {
114
+ this._playStartTime = this.context.currentTime - offset;
115
+ }
116
+ else {
117
+ this._playStartTime = this.context.currentTime;
118
+ }
119
+ }
120
+ }
121
+ stop() {
122
+ this.port.postMessage({ cmd: 'stop' });
123
+ this.onended?.call(this);
124
+ }
125
+ }
126
126
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXlfYXVkaW9fYnVmZmVyX3NvdXJjZV9ub2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3BsYXliYWNrL2FycmF5X2F1ZGlvX2J1ZmZlcl9zb3VyY2Vfbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUMvRSxPQUFPLEVBQUMsMkJBQTJCLEVBQTBCLE1BQU0saUJBQWlCLENBQUM7QUFDckYsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRXBELE1BQU0sT0FBTywwQkFBMkIsU0FBUSxlQUFlO0lBVTdELFlBQVksT0FBcUI7UUFFL0IsS0FBSyxDQUFDLE9BQU8sRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBVmpDLHVCQUFrQixHQUFHLGVBQWUsQ0FBQywyQkFBMkIsQ0FBQztRQUNqRSxxQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFDckIsc0JBQWlCLEdBQTRCLElBQUksQ0FBQztRQUNsRCxzQkFBaUIsR0FBOEIsSUFBSSxDQUFDO1FBQ3BELGFBQVEsR0FBcUIsSUFBSSxDQUFDO1FBRWxDLGlCQUFZLEdBQUcsQ0FBQyxDQUFDO1FBS3ZCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxVQUFVLENBQUM7UUFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxLQUFtQixFQUFFLEVBQUU7WUFDNUMsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFO2dCQUNkLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO2dCQUNsQyxJQUFJLE1BQU0sRUFBRTtvQkFDVixJQUFJLG9CQUFvQixLQUFLLE1BQU0sRUFBRTt3QkFDbkMsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVks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QUFlLEdBQUcsQ0FBQyxDQUFDO1lBQzNDLEtBQUksSUFBSSxFQUFFLEdBQUMsQ0FBQyxFQUFDLEVBQUUsR0FBQyxHQUFHLEVBQUMsRUFBRSxFQUFFLEVBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEdBQUMsSUFBSSxZQUFZLENBQUMsMEJBQTBCLENBQUMsNkJBQTZCLENBQUMsQ0FBQzthQUM5RjtZQUVELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDO1lBQ3BDLElBQUcsTUFBTSxFQUFFO2dCQUNULElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDO2FBQ3pEO2lCQUFJO2dCQUNILElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7YUFDaEQ7U0FDSjtJQUNELENBQUM7SUFFRCxJQUFJO1FBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBQyxHQUFHLEVBQUUsTUFBTSxFQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQixDQUFDO0NBRUYiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0FycmF5QXVkaW9CdWZmZXJ9IGZyb20gXCIuLi9hcnJheV9hdWRpb19idWZmZXJcIjtcclxuaW1wb3J0IHtBcnJheUF1ZGlvQnVmZmVySW5wdXRTdHJlYW19IGZyb20gXCIuLi9hcnJheV9hdWRpb19idWZmZXJfaW5wdXRfc3RyZWFtXCI7XHJcbmltcG9ydCB7RWRpdEZsb2F0MzJBcnJheUlucHV0U3RyZWFtLCBGbG9hdDMyQXJyYXlJbnB1dFN0cmVhbX0gZnJvbSBcIi4uLy4uL2lvL3N0cmVhbVwiO1xyXG5pbXBvcnQge0F1ZGlvU291cmNlTm9kZX0gZnJvbSBcIi4vYXVkaW9fc291cmNlX25vZGVcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZSBleHRlbmRzIEF1ZGlvU291cmNlTm9kZSB7XHJcblxyXG4gIHByaXZhdGUgX2J1ZmZlckZpbGxTZWNvbmRzID0gQXVkaW9Tb3VyY2VOb2RlLkRFRkFVTFRfQlVGRkVSX0ZJTExfU0VDT05EUztcclxuICBwcml2YXRlIGJ1ZmZlckZpbGxGcmFtZXMgPSAwO1xyXG4gIHByaXZhdGUgX2FycmF5QXVkaW9CdWZmZXI6IEFycmF5QXVkaW9CdWZmZXIgfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIF9hdWRpb0lucHV0U3RyZWFtOkZsb2F0MzJBcnJheUlucHV0U3RyZWFtfG51bGw9bnVsbDtcclxuICBwcml2YXRlIF9haXNCdWZzOkZsb2F0MzJBcnJheVtdfG51bGw9bnVsbDtcclxuXHJcbiAgcHJpdmF0ZSBmaWxsZWRGcmFtZXMgPSAwO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBBdWRpb0NvbnRleHQpIHtcclxuXHJcbiAgICBzdXBlcihjb250ZXh0LCAnYXVkaW8tc291cmNlLXdvcmtsZXQnKTtcclxuICAgIHRoaXMuY2hhbm5lbENvdW50TW9kZSA9ICdleHBsaWNpdCc7XHJcbiAgICB0aGlzLnBvcnQub25tZXNzYWdlID0gKG1zZ0V2OiBNZXNzYWdlRXZlbnQpID0+IHtcclxuICAgICAgaWYgKG1zZ0V2LmRhdGEpIHtcclxuICAgICAgICBsZXQgZXZUeXBlID0gbXNnRXYuZGF0YS5ldmVudFR5cGU7XHJcbiAgICAgICAgaWYgKGV2VHlwZSkge1xyXG4gICAgICAgICAgaWYgKCdidWZmZXJOb3RpZmljYXRpb24nID09PSBldlR5cGUpIHtcclxuICAgICAgICAgICAgdGhpcy5maWxsZWRGcmFtZXMgPSBtc2dFdi5kYXRhLmZpbGxlZEZyYW1lcztcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiQnVmZmVyIG5vdGlmaWNhdGlvbjogZmlsbGVkIGZyYW1lczogXCIgKyB0aGlzLmZpbGxlZEZyYW1lcyk7XHJcbiAgICAgICAgICAgIHRoaXMuZmlsbEJ1ZmZlcigpO1xyXG4gICAgICAgICAgfSBlbHNlIGlmICgnZW5kZWQnID09PSBldlR5cGUpIHtcclxuICAgICAgICAgICAgbGV0IGRyYWluVGltZSA9IDA7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9hcnJheUF1ZGlvQnVmZmVyPy5zYW1wbGVSYXRlKSB7XHJcbiAgICAgICAgICAgICAgZHJhaW5UaW1lID0gQXJyYXlBdWRpb0J1ZmZlclNvdXJjZU5vZGUuUVVBTlRVTV9GUkFNRV9MRU4gLyB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyLnNhbXBsZVJhdGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy9sZXQgZHN0QW55OmFueT10aGlzLmNvbnRleHQuZGVzdGluYXRpb247XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZygnRGVzdGluYXRpb24gbm9kZSB0YWlsLXRpbWU6ICcrZHN0QW55Wyd0YWlsLXRpbWUnXSk7XHJcbiAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICB0aGlzLm9uZW5kZWQ/LmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgIH0sIGRyYWluVGltZSAqIDEwMDApO1xyXG5cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZmlsbEJ1ZmZlcigpIHtcclxuICAgIGlmICh0aGlzLl9hcnJheUF1ZGlvQnVmZmVyICYmIHRoaXMuX2F1ZGlvSW5wdXRTdHJlYW0gJiYgdGhpcy5fYWlzQnVmcykge1xyXG4gICAgICBsZXQgZmlsbGVkID0gdGhpcy5maWxsZWRGcmFtZXM7XHJcbiAgICAgIGxldCBidWZMZW4gPSAwO1xyXG5cclxuICAgICAgd2hpbGUoZmlsbGVkPCB0aGlzLmJ1ZmZlckZpbGxGcmFtZXMpIHtcclxuICAgICAgICBsZXQgcmVhZCA9IHRoaXMuX2F1ZGlvSW5wdXRTdHJlYW0ucmVhZCh0aGlzLl9haXNCdWZzKTtcclxuICAgICAgICAvL2NvbnNvbGUubG9nKFwiQXJyYXlBdWRpb0J1ZmZlclNvdXJjZU5vZGU6IHJlYWQ6IFwiK3JlYWQpXHJcbiAgICAgICAgaWYgKHJlYWQpIHtcclxuICAgICAgICAgIGxldCB0ckJ1ZmZlcnMgPSBuZXcgQXJyYXk8YW55Pih0aGlzLmNoYW5uZWxDb3VudCk7XHJcbiAgICAgICAgICBmb3IgKGxldCBjaCA9IDA7IGNoIDwgdGhpcy5jaGFubmVsQ291bnQ7IGNoKyspIHtcclxuICAgICAgICAgICAgbGV0IGFkQ2ggPSB0aGlzLl9haXNCdWZzW2NoXTtcclxuICAgICAgICAgICAgbGV0IGFkQ2hDb3B5ID0gbmV3IEZsb2F0MzJBcnJheShhZENoLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIGJ1ZkxlbiA9IGFkQ2hDb3B5Lmxlbmd0aDtcclxuICAgICAgICAgICAgYWRDaENvcHkuc2V0KGFkQ2gpO1xyXG4gICAgICAgICAgICB0ckJ1ZmZlcnNbY2hdID0gYWRDaENvcHkuYnVmZmVyO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgY21kOiAnZGF0YScsXHJcbiAgICAgICAgICAgIGNoczogdGhpcy5jaGFubmVsQ291bnQsXHJcbiAgICAgICAgICAgIGF1ZGlvRGF0YTogdHJCdWZmZXJzXHJcbiAgICAgICAgICB9LCB0ckJ1ZmZlcnMpO1xyXG4gICAgICAgICAgZmlsbGVkKz1yZWFkO1xyXG4gICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtcclxuICAgICAgICAgICAgY21kOiAnZW5kT2ZTdHJlYW0nXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBhcnJheUF1ZGlvQnVmZmVyKCk6IEFycmF5QXVkaW9CdWZmZXIgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyO1xyXG4gIH1cclxuXHJcbiAgc2V0IGFycmF5QXVkaW9CdWZmZXIodmFsdWU6IEFycmF5QXVkaW9CdWZmZXIgfCBudWxsKSB7XHJcbiAgICB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyID0gdmFsdWU7XHJcbiAgICBpZiAodGhpcy5fYXJyYXlBdWRpb0J1ZmZlcj8uY2hhbm5lbENvdW50KSB7XHJcbiAgICAgIHRoaXMuY2hhbm5lbENvdW50ID0gdGhpcy5fYXJyYXlBdWRpb0J1ZmZlcj8uY2hhbm5lbENvdW50O1xyXG4gICAgICB0aGlzLmJ1ZmZlckZpbGxGcmFtZXMgPSB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyLnNhbXBsZVJhdGUgKiB0aGlzLl9idWZmZXJGaWxsU2Vjb25kcztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBidWZmZXJGaWxsU2Vjb25kcygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2J1ZmZlckZpbGxTZWNvbmRzO1xyXG4gIH1cclxuXHJcbiAgc2V0IGJ1ZmZlckZpbGxTZWNvbmRzKHZhbHVlOiBudW1iZXIpIHtcclxuICAgIHRoaXMuX2J1ZmZlckZpbGxTZWNvbmRzID0gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBzdGFydCh3aGVuPzogbnVtYmVyIHwgdW5kZWZpbmVkLG9mZnNldD86IG51bWJlciB8IHVuZGVmaW5lZCxkdXJhdGlvbj86IG51bWJlciB8IHVuZGVmaW5lZCk6IHZvaWQge1xyXG4gICAgaWYgKHdoZW4pIHtcclxuICAgICAgdGhyb3cgRXJyb3IoXCJ3aGVuIHBhcmFtZXRlciBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCBieSBBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZSBjbGFzc1wiKVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9hcnJheUF1ZGlvQnVmZmVyKSB7XHJcbiAgICAgIGxldCBhcnJBaXM9bmV3IEFycmF5QXVkaW9CdWZmZXJJbnB1dFN0cmVhbSh0aGlzLl9hcnJheUF1ZGlvQnVmZmVyKTtcclxuICAgICAgaWYob2Zmc2V0PT09dW5kZWZpbmVkICYmIGR1cmF0aW9uPT09dW5kZWZpbmVkKXtcclxuICAgICAgICB0aGlzLl9hdWRpb0lucHV0U3RyZWFtID0gYXJyQWlzO1xyXG4gICAgICB9ZWxzZXtcclxuICAgICAgICBsZXQgb2Zmc2V0RnJhbWVzPTA7XHJcbiAgICAgICAgbGV0IGR1cmF0aW9uRnJhbWVzPXVuZGVmaW5lZDtcclxuICAgICAgICBpZihvZmZzZXQhPT11bmRlZmluZWQpIHtcclxuICAgICAgICAgIG9mZnNldEZyYW1lcz1NYXRoLmZsb29yKG9mZnNldCAqIHRoaXMuX2FycmF5QXVkaW9CdWZmZXIuc2FtcGxlUmF0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKGR1cmF0aW9uIT09dW5kZWZpbmVkKXtcclxuICAgICAgICAgIGR1cmF0aW9uRnJhbWVzPU1hdGguZmxvb3IoZHVyYXRpb24gKiB0aGlzLl9hcnJheUF1ZGlvQnVmZmVyLnNhbXBsZVJhdGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9hdWRpb0lucHV0U3RyZWFtPW5ldyBFZGl0RmxvYXQzMkFycmF5SW5wdXRTdHJlYW0oYXJyQWlzLG9mZnNldEZyYW1lcyxkdXJhdGlvbkZyYW1lcyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICBsZXQgY2hzPXRoaXMuX2FycmF5QXVkaW9CdWZmZXIuY2hhbm5lbENvdW50O1xyXG4gICAgdGhpcy5fYWlzQnVmcz1uZXcgQXJyYXk8RmxvYXQzMkFycmF5PihjaHMpO1xyXG4gICAgZm9yKGxldCBjaD0wO2NoPGNocztjaCsrKXtcclxuICAgICAgdGhpcy5fYWlzQnVmc1tjaF09bmV3IEZsb2F0MzJBcnJheShBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZS5ERUZBVUxUX1NUUkVBTV9SRUFEX0ZSQU1FX0xFTik7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5maWxsQnVmZmVyKCk7XHJcbiAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2NtZDogJ3N0YXJ0J30pO1xyXG4gICAgICBpZihvZmZzZXQpIHtcclxuICAgICAgICB0aGlzLl9wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lIC0gb2Zmc2V0O1xyXG4gICAgICB9ZWxzZXtcclxuICAgICAgICB0aGlzLl9wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xyXG4gICAgICB9XHJcbiAgfVxyXG4gIH1cclxuXHJcbiAgc3RvcCgpIHtcclxuICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7Y21kOiAnc3RvcCd9KTtcclxuICAgIHRoaXMub25lbmRlZD8uY2FsbCh0aGlzKTtcclxuICB9XHJcblxyXG59XHJcbiJdfQ==
@@ -0,0 +1,18 @@
1
+ export class AudioSourceNode extends AudioWorkletNode {
2
+ constructor() {
3
+ super(...arguments);
4
+ this._playStartTime = null;
5
+ this.onended = null;
6
+ }
7
+ static { this.DEFAULT_BUFFER_FILL_SECONDS = 10; }
8
+ static { this.DEFAULT_STREAM_READ_FRAME_LEN = 1024; }
9
+ static { this.QUANTUM_FRAME_LEN = 128; }
10
+ get playPositionTime() {
11
+ let ppt = null;
12
+ if (this._playStartTime !== null) {
13
+ ppt = this.context.currentTime - this._playStartTime;
14
+ }
15
+ return ppt;
16
+ }
17
+ }
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW9fc291cmNlX25vZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zcGVlY2hyZWNvcmRlcm5nL3NyYy9saWIvYXVkaW8vcGxheWJhY2svYXVkaW9fc291cmNlX25vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxPQUFnQixlQUFnQixTQUFRLGdCQUFnQjtJQUE5RDs7UUFJWSxtQkFBYyxHQUFhLElBQUksQ0FBQztRQVcxQyxZQUFPLEdBQXdCLElBQUksQ0FBQztJQUN0QyxDQUFDO2FBZmlCLGdDQUEyQixHQUFHLEVBQUUsQUFBTCxDQUFNO2FBQ2pDLGtDQUE2QixHQUFDLElBQUksQUFBTCxDQUFNO2FBQ25DLHNCQUFpQixHQUFHLEdBQUcsQUFBTixDQUFPO0lBS3hDLElBQUksZ0JBQWdCO1FBQ2xCLElBQUksR0FBRyxHQUFDLElBQUksQ0FBQztRQUNiLElBQUcsSUFBSSxDQUFDLGNBQWMsS0FBRyxJQUFJLEVBQUU7WUFDN0IsR0FBRyxHQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7U0FDckQ7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgYWJzdHJhY3QgY2xhc3MgQXVkaW9Tb3VyY2VOb2RlIGV4dGVuZHMgQXVkaW9Xb3JrbGV0Tm9kZSB7XHJcbiAgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfQlVGRkVSX0ZJTExfU0VDT05EUyA9IDEwO1xyXG4gIHN0YXRpYyByZWFkb25seSBERUZBVUxUX1NUUkVBTV9SRUFEX0ZSQU1FX0xFTj0xMDI0O1xyXG4gIHN0YXRpYyByZWFkb25seSBRVUFOVFVNX0ZSQU1FX0xFTiA9IDEyODtcclxuICBwcm90ZWN0ZWQgX3BsYXlTdGFydFRpbWU6bnVtYmVyfG51bGw9bnVsbDtcclxuICBwdWJsaWMgYWJzdHJhY3Qgc3RhcnQod2hlbj86IG51bWJlciB8IHVuZGVmaW5lZCxvZmZzZXQ/OiBudW1iZXIgfCB1bmRlZmluZWQsZHVyYXRpb24/OiBudW1iZXIgfCB1bmRlZmluZWQpOiB2b2lkO1xyXG4gIHB1YmxpYyBhYnN0cmFjdCBzdG9wKCk6dm9pZDtcclxuXHJcbiAgZ2V0IHBsYXlQb3NpdGlvblRpbWUoKTpudW1iZXJ8bnVsbCB7XHJcbiAgICBsZXQgcHB0PW51bGw7XHJcbiAgICBpZih0aGlzLl9wbGF5U3RhcnRUaW1lIT09bnVsbCkge1xyXG4gICAgICBwcHQ9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZSAtIHRoaXMuX3BsYXlTdGFydFRpbWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcHB0O1xyXG4gIH1cclxuICBvbmVuZGVkOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcclxufVxyXG4iXX0=
@@ -0,0 +1,167 @@
1
+ // Code from audio_source_worklet.js as string constant to be loaded as module
2
+ // Changes in audio_source_worklet.js must be copied and pasted to this string constant
3
+ const aswpStr = "\n" +
4
+ "// Important note: Changes in audio_source_worklet.js must be copied and pasted to the string constant aswpStr in audio_source_worklet_module_loader.ts\n" +
5
+ "\n" +
6
+ "\n" +
7
+ "class AudioSourceProcessor extends AudioWorkletProcessor{\n" +
8
+ "\n" +
9
+ " filledFrames=0;\n" +
10
+ " audioBuffers=new Array();\n" +
11
+ " currentAudioBuffer=null;\n" +
12
+ " currentAudioBufferFramePos=0;\n" +
13
+ " currentAudioBufferAvail=0;\n" +
14
+ " running=false;\n" +
15
+ " stalled=false;\n" +
16
+ " stopped=false;\n" +
17
+ " endOfStream=false;\n" +
18
+ " ended=false;\n" +
19
+ "\n" +
20
+ " constructor() {\n" +
21
+ " super({numberOfInputs:0,numberOfOutputs:1});\n" +
22
+ " this.port.onmessage=(msgEv)=>{\n" +
23
+ " // received audio playback data from application\n" +
24
+ " //console.debug(\"Audio source worklet msg: Received.\");\n" +
25
+ "\n" +
26
+ " if(msgEv.data.cmd){\n" +
27
+ " if('data'===msgEv.data.cmd) {\n" +
28
+ " let chs = msgEv.data.chs;\n" +
29
+ "\n" +
30
+ " let audioData = new Array(chs);\n" +
31
+ " for (let ch = 0; ch < chs; ch++) {\n" +
32
+ " audioData[ch] = new Float32Array(msgEv.data.audioData[ch]);\n" +
33
+ " }\n" +
34
+ " let msgChBufLen=audioData[0].length;\n" +
35
+ " this.audioBuffers.push(audioData);\n" +
36
+ " this.filledFrames += msgChBufLen;\n" +
37
+ " //console.debug(\"Audio source worklet msg: Filled \" + this.filledFrames+ \" in \"+this.audioBuffers.length+\" buffers.\");\n" +
38
+ "\n" +
39
+ " }else if('start'===msgEv.data.cmd){\n" +
40
+ " this.running=true;\n" +
41
+ " }else if('stop'===msgEv.data.cmd){\n" +
42
+ " //console.debug(\"Stop...\");\n" +
43
+ " this.running=false;\n" +
44
+ " this.stopped=true;\n" +
45
+ " // clear buffers\n" +
46
+ " this.filledFrames=0;\n" +
47
+ " while(this.audioBuffers.length > 0) {\n" +
48
+ " this.audioBuffers.pop();\n" +
49
+ " }\n" +
50
+ " this.currentAudioBuffer=new Float32Array(0);\n" +
51
+ " }else if('endOfStream'===msgEv.data.cmd){\n" +
52
+ " this.endOfStream=true;\n" +
53
+ " }else if('continue'===msgEv.data.cmd){\n" +
54
+ " console.debug(\"Continue after stalled...\");\n" +
55
+ " this.stalled=false;\n" +
56
+ " this.port.postMessage({eventType: 'resumed'});\n" +
57
+ " }\n" +
58
+ " }\n" +
59
+ " }\n" +
60
+ " }\n" +
61
+ "\n" +
62
+ " process(\n" +
63
+ " inputs,\n" +
64
+ " outputs,\n" +
65
+ " parameters\n" +
66
+ " ){\n" +
67
+ " //console.debug(\"Audio source worklet: process \"+outputs.length+ \" output buffers.\");\n" +
68
+ " // copy ring buffer data to outputs\n" +
69
+ " if(!this.running || this.stalled){\n" +
70
+ " if(this.endOfStream) {\n" +
71
+ " this.ended = true;\n" +
72
+ " this.port.postMessage({eventType: 'ended'});\n" +
73
+ " }\n" +
74
+ " return !this.ended && !this.stopped;\n" +
75
+ " }\n" +
76
+ "\n" +
77
+ " let output=outputs[0];\n" +
78
+ " let chs=output.length;\n" +
79
+ " //console.debug(\"Audio source worklet: Output channels: \"+chs);\n" +
80
+ " if(chs>0) {\n" +
81
+ "\n" +
82
+ " let outCh0 = output[0];\n" +
83
+ " let outChLen = outCh0.length;\n" +
84
+ "\n" +
85
+ " if(!this.currentAudioBuffer){\n" +
86
+ " // get first buffer\n" +
87
+ " let nxtBuff=this.audioBuffers.shift();\n" +
88
+ " if(nxtBuff) {\n" +
89
+ " this.currentAudioBuffer = nxtBuff;\n" +
90
+ " this.currentAudioBufferFramePos=0;\n" +
91
+ " this.currentAudioBufferAvail=this.currentAudioBuffer[0].length;\n" +
92
+ " }else{\n" +
93
+ " return true;\n" +
94
+ " }\n" +
95
+ " }\n" +
96
+ "\n" +
97
+ " let copied=0;\n" +
98
+ " do{\n" +
99
+ " if(this.currentAudioBufferAvail===0){\n" +
100
+ " let nxtBuff=this.audioBuffers.shift();\n" +
101
+ " if(nxtBuff){\n" +
102
+ " this.currentAudioBuffer=nxtBuff;\n" +
103
+ " this.currentAudioBufferFramePos=0;\n" +
104
+ " this.currentAudioBufferAvail=this.currentAudioBuffer[0].length;\n" +
105
+ " //console.debug(\"Next buffer with \"+this.currentAudioBufferAvail+ \" frames\");\n" +
106
+ " this.port.postMessage({eventType:'bufferNotification',filledFrames:this.filledFrames});\n" +
107
+ " }else{\n" +
108
+ " if(this.endOfStream) {\n" +
109
+ " this.ended = true;\n" +
110
+ " this.port.postMessage({eventType: 'ended'});\n" +
111
+ " //console.debug(\"Stream ended\");\n" +
112
+ " }else{\n" +
113
+ " if(!this.stalled) {\n" +
114
+ " this.stalled = true;\n" +
115
+ " this.port.postMessage({eventType: 'stalled'});\n" +
116
+ " }\n" +
117
+ " }\n" +
118
+ " break;\n" +
119
+ " }\n" +
120
+ " }\n" +
121
+ " //console.debug(\"outChLen: \"+outChLen+\", copied: \"+copied+\", current avail: \"+this.currentAudioBufferAvail);\n" +
122
+ " let toCopy=outChLen-copied;\n" +
123
+ " if(toCopy>this.currentAudioBufferAvail){\n" +
124
+ " toCopy=this.currentAudioBufferAvail;\n" +
125
+ " }\n" +
126
+ " //console.debug(\"Copy \"+toCopy+\" frames...\");\n" +
127
+ " for(let ch=0;ch<chs;ch++) {\n" +
128
+ " let outCh=output[ch];\n" +
129
+ " for (let i = 0; i < toCopy; i++) {\n" +
130
+ " outCh[copied+i]=this.currentAudioBuffer[ch][this.currentAudioBufferFramePos+i];\n" +
131
+ " }\n" +
132
+ " }\n" +
133
+ " copied+=toCopy;\n" +
134
+ " this.currentAudioBufferFramePos+=toCopy;\n" +
135
+ " this.currentAudioBufferAvail-=toCopy;\n" +
136
+ "\n" +
137
+ " }while(copied<outChLen);\n" +
138
+ " this.filledFrames-=copied;\n" +
139
+ " //console.debug(\"Copied \"+copied+\" frames.\");\n" +
140
+ " }\n" +
141
+ " return !this.ended;\n" +
142
+ " }\n" +
143
+ "}\n" +
144
+ "\n" +
145
+ "registerProcessor('audio-source-worklet',AudioSourceProcessor);\n";
146
+ export class AudioSourceWorkletModuleLoader {
147
+ static { this.moduleLoaded = false; }
148
+ static loadModule(context) {
149
+ return new Promise((resolve, reject) => {
150
+ if (AudioSourceWorkletModuleLoader.moduleLoaded) {
151
+ resolve.call(self);
152
+ }
153
+ else {
154
+ const audioWorkletModuleBlob = new Blob([aswpStr], { type: 'text/javascript' });
155
+ const audioWorkletModuleBlobUrl = window.URL.createObjectURL(audioWorkletModuleBlob);
156
+ context.audioWorklet.addModule(audioWorkletModuleBlobUrl).then(() => {
157
+ AudioSourceWorkletModuleLoader.moduleLoaded = true;
158
+ resolve.call(self);
159
+ }).catch((reason) => {
160
+ console.error(reason);
161
+ reject.call(reason);
162
+ });
163
+ }
164
+ });
165
+ }
166
+ }
167
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW9fc291cmNlX3dvcmtsZXRfbW9kdWxlX2xvYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVjaHJlY29yZGVybmcvc3JjL2xpYi9hdWRpby9wbGF5YmFjay9hdWRpb19zb3VyY2Vfd29ya2xldF9tb2R1bGVfbG9hZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhFQUE4RTtBQUM5RSx1RkFBdUY7QUFFdkYsTUFBTSxPQUFPLEdBQUcsSUFBSTtJQUNsQiwySkFBMko7SUFDM0osSUFBSTtJQUNKLElBQUk7SUFDSiw2REFBNkQ7SUFDN0QsSUFBSTtJQUNKLHVCQUF1QjtJQUN2QixpQ0FBaUM7SUFDakMsZ0NBQWdDO0lBQ2hDLHFDQUFxQztJQUNyQyxrQ0FBa0M7SUFDbEMsc0JBQXNCO0lBQ3RCLHNCQUFzQjtJQUN0QixzQkFBc0I7SUFDdEIsMEJBQTBCO0lBQzFCLG9CQUFvQjtJQUNwQixJQUFJO0lBQ0osdUJBQXVCO0lBQ3ZCLHdEQUF3RDtJQUN4RCwwQ0FBMEM7SUFDMUMsOERBQThEO0lBQzlELHVFQUF1RTtJQUN2RSxJQUFJO0lBQ0osaUNBQWlDO0lBQ2pDLDZDQUE2QztJQUM3QywyQ0FBMkM7SUFDM0MsSUFBSTtJQUNKLGlEQUFpRDtJQUNqRCxvREFBb0Q7SUFDcEQsK0VBQStFO0lBQy9FLG1CQUFtQjtJQUNuQixzREFBc0Q7SUFDdEQsb0RBQW9EO0lBQ3BELG1EQUFtRDtJQUNuRCw4SUFBOEk7SUFDOUksSUFBSTtJQUNKLG1EQUFtRDtJQUNuRCxvQ0FBb0M7SUFDcEMsa0RBQWtEO0lBQ2xELCtDQUErQztJQUMvQyxxQ0FBcUM7SUFDckMsb0NBQW9DO0lBQ3BDLGtDQUFrQztJQUNsQyxzQ0FBc0M7SUFDdEMsdURBQXVEO0lBQ3ZELDRDQUE0QztJQUM1QyxtQkFBbUI7SUFDbkIsOERBQThEO0lBQzlELHlEQUF5RDtJQUN6RCx3Q0FBd0M7SUFDeEMsc0RBQXNEO0lB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Q0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3RCLENBQUMsQ0FBQyxDQUFDO2FBRUo7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb2RlIGZyb20gYXVkaW9fc291cmNlX3dvcmtsZXQuanMgYXMgc3RyaW5nIGNvbnN0YW50IHRvIGJlIGxvYWRlZCBhcyBtb2R1bGVcclxuLy8gQ2hhbmdlcyBpbiBhdWRpb19zb3VyY2Vfd29ya2xldC5qcyBtdXN0IGJlIGNvcGllZCBhbmQgcGFzdGVkIHRvIHRoaXMgc3RyaW5nIGNvbnN0YW50XHJcblxyXG5jb25zdCBhc3dwU3RyID0gXCJcXG5cIiArXHJcbiAgXCIvLyBJbXBvcnRhbnQgbm90ZTogQ2hhbmdlcyBpbiBhdWRpb19zb3VyY2Vfd29ya2xldC5qcyBtdXN0IGJlIGNvcGllZCBhbmQgcGFzdGVkIHRvIHRoZSBzdHJpbmcgY29uc3RhbnQgYXN3cFN0ciBpbiBhdWRpb19zb3VyY2Vfd29ya2xldF9tb2R1bGVfbG9hZGVyLnRzXFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiY2xhc3MgQXVkaW9Tb3VyY2VQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgIGZpbGxlZEZyYW1lcz0wO1xcblwiICtcclxuICBcIiAgICBhdWRpb0J1ZmZlcnM9bmV3IEFycmF5KCk7XFxuXCIgK1xyXG4gIFwiICAgIGN1cnJlbnRBdWRpb0J1ZmZlcj1udWxsO1xcblwiICtcclxuICBcIiAgICBjdXJyZW50QXVkaW9CdWZmZXJGcmFtZVBvcz0wO1xcblwiICtcclxuICBcIiAgICBjdXJyZW50QXVkaW9CdWZmZXJBdmFpbD0wO1xcblwiICtcclxuICBcIiAgICBydW5uaW5nPWZhbHNlO1xcblwiICtcclxuICBcIiAgICBzdGFsbGVkPWZhbHNlO1xcblwiICtcclxuICBcIiAgICBzdG9wcGVkPWZhbHNlO1xcblwiICtcclxuICBcIiAgICBlbmRPZlN0cmVhbT1mYWxzZTtcXG5cIiArXHJcbiAgXCIgICAgZW5kZWQ9ZmFsc2U7XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgIGNvbnN0cnVjdG9yKCkge1xcblwiICtcclxuICBcIiAgICAgICAgc3VwZXIoe251bWJlck9mSW5wdXRzOjAsbnVtYmVyT2ZPdXRwdXRzOjF9KTtcXG5cIiArXHJcbiAgXCIgICAgICAgIHRoaXMucG9ydC5vbm1lc3NhZ2U9KG1zZ0V2KT0+e1xcblwiICtcclxuICBcIiAgICAgICAgICAvLyByZWNlaXZlZCBhdWRpbyBwbGF5YmFjayBkYXRhIGZyb20gYXBwbGljYXRpb25cXG5cIiArXHJcbiAgXCIgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFxcXCJBdWRpbyBzb3VyY2Ugd29ya2xldCBtc2c6IFJlY2VpdmVkLlxcXCIpO1xcblwiICtcclxuICBcIlxcblwiICtcclxuICBcIiAgICAgICAgICBpZihtc2dFdi5kYXRhLmNtZCl7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgaWYoJ2RhdGEnPT09bXNnRXYuZGF0YS5jbWQpIHtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIGxldCBjaHMgPSBtc2dFdi5kYXRhLmNocztcXG5cIiArXHJcbiAgXCJcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIGxldCBhdWRpb0RhdGEgPSBuZXcgQXJyYXkoY2hzKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCBjaHM7IGNoKyspIHtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgICAgYXVkaW9EYXRhW2NoXSA9IG5ldyBGbG9hdDMyQXJyYXkobXNnRXYuZGF0YS5hdWRpb0RhdGFbY2hdKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIGxldCBtc2dDaEJ1Zkxlbj1hdWRpb0RhdGFbMF0ubGVuZ3RoO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5hdWRpb0J1ZmZlcnMucHVzaChhdWRpb0RhdGEpO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5maWxsZWRGcmFtZXMgKz0gbXNnQ2hCdWZMZW47XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0IG1zZzogRmlsbGVkIFxcXCIgKyB0aGlzLmZpbGxlZEZyYW1lcysgXFxcIiBpbiBcXFwiK3RoaXMuYXVkaW9CdWZmZXJzLmxlbmd0aCtcXFwiIGJ1ZmZlcnMuXFxcIik7XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgfWVsc2UgaWYoJ3N0YXJ0Jz09PW1zZ0V2LmRhdGEuY21kKXtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIHRoaXMucnVubmluZz10cnVlO1xcblwiICtcclxuICBcIiAgICAgICAgICAgIH1lbHNlIGlmKCdzdG9wJz09PW1zZ0V2LmRhdGEuY21kKXtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiU3RvcC4uLlxcXCIpO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nPWZhbHNlO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5zdG9wcGVkPXRydWU7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAvLyBjbGVhciBidWZmZXJzXFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0aGlzLmZpbGxlZEZyYW1lcz0wO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgd2hpbGUodGhpcy5hdWRpb0J1ZmZlcnMubGVuZ3RoID4gMCkge1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQnVmZmVycy5wb3AoKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyPW5ldyBGbG9hdDMyQXJyYXkoMCk7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgfWVsc2UgaWYoJ2VuZE9mU3RyZWFtJz09PW1zZ0V2LmRhdGEuY21kKXtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIHRoaXMuZW5kT2ZTdHJlYW09dHJ1ZTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICB9ZWxzZSBpZignY29udGludWUnPT09bXNnRXYuZGF0YS5jbWQpe1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgY29uc29sZS5kZWJ1ZyhcXFwiQ29udGludWUgYWZ0ZXIgc3RhbGxlZC4uLlxcXCIpO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5zdGFsbGVkPWZhbHNlO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtldmVudFR5cGU6ICdyZXN1bWVkJ30pO1xcblwiICtcclxuICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgfVxcblwiICtcclxuICBcIiAgICAgICAgfVxcblwiICtcclxuICBcIiAgICB9XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiIHByb2Nlc3MoXFxuXCIgK1xyXG4gIFwiICAgICAgaW5wdXRzLFxcblwiICtcclxuICBcIiAgICAgIG91dHB1dHMsXFxuXCIgK1xyXG4gIFwiICAgICAgcGFyYW1ldGVyc1xcblwiICtcclxuICBcIiAgKXtcXG5cIiArXHJcbiAgXCIgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0OiBwcm9jZXNzIFxcXCIrb3V0cHV0cy5sZW5ndGgrIFxcXCIgb3V0cHV0IGJ1ZmZlcnMuXFxcIik7XFxuXCIgK1xyXG4gIFwiICAgICAgLy8gY29weSByaW5nIGJ1ZmZlciBkYXRhIHRvIG91dHB1dHNcXG5cIiArXHJcbiAgXCIgICAgICAgIGlmKCF0aGlzLnJ1bm5pbmcgfHwgdGhpcy5zdGFsbGVkKXtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICBpZih0aGlzLmVuZE9mU3RyZWFtKSB7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2V2ZW50VHlwZTogJ2VuZGVkJ30pO1xcblwiICtcclxuICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgcmV0dXJuICF0aGlzLmVuZGVkICYmICF0aGlzLnN0b3BwZWQ7XFxuXCIgK1xyXG4gIFwiICAgICAgICB9XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgICAgICBsZXQgb3V0cHV0PW91dHB1dHNbMF07XFxuXCIgK1xyXG4gIFwiICAgICAgICBsZXQgY2hzPW91dHB1dC5sZW5ndGg7XFxuXCIgK1xyXG4gIFwiICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIkF1ZGlvIHNvdXJjZSB3b3JrbGV0OiBPdXRwdXQgY2hhbm5lbHM6IFxcXCIrY2hzKTtcXG5cIiArXHJcbiAgXCIgICAgICAgIGlmKGNocz4wKSB7XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgICAgICAgIGxldCBvdXRDaDAgPSBvdXRwdXRbMF07XFxuXCIgK1xyXG4gIFwiICAgICAgICAgIGxldCBvdXRDaExlbiA9IG91dENoMC5sZW5ndGg7XFxuXCIgK1xyXG4gIFwiXFxuXCIgK1xyXG4gIFwiICAgICAgICAgIGlmKCF0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlcil7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgLy8gZ2V0IGZpcnN0IGJ1ZmZlclxcblwiICtcclxuICBcIiAgICAgICAgICAgIGxldCBueHRCdWZmPXRoaXMuYXVkaW9CdWZmZXJzLnNoaWZ0KCk7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgaWYobnh0QnVmZikge1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXIgPSBueHRCdWZmO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXJGcmFtZVBvcz0wO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbD10aGlzLmN1cnJlbnRBdWRpb0J1ZmZlclswXS5sZW5ndGg7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgfWVsc2V7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICB9XFxuXCIgK1xyXG4gIFwiICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCJcXG5cIiArXHJcbiAgXCIgICAgICAgICAgbGV0IGNvcGllZD0wO1xcblwiICtcclxuICBcIiAgICAgICAgICBkb3tcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICBpZih0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckF2YWlsPT09MCl7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICBsZXQgbnh0QnVmZj10aGlzLmF1ZGlvQnVmZmVycy5zaGlmdCgpO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgaWYobnh0QnVmZil7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyPW54dEJ1ZmY7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudEF1ZGlvQnVmZmVyRnJhbWVQb3M9MDtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbD10aGlzLmN1cnJlbnRBdWRpb0J1ZmZlclswXS5sZW5ndGg7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiTmV4dCBidWZmZXIgd2l0aCBcXFwiK3RoaXMuY3VycmVudEF1ZGlvQnVmZmVyQXZhaWwrIFxcXCIgZnJhbWVzXFxcIik7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7ZXZlbnRUeXBlOididWZmZXJOb3RpZmljYXRpb24nLGZpbGxlZEZyYW1lczp0aGlzLmZpbGxlZEZyYW1lc30pO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgfWVsc2V7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIGlmKHRoaXMuZW5kT2ZTdHJlYW0pIHtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgICAgICB0aGlzLmVuZGVkID0gdHJ1ZTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2V2ZW50VHlwZTogJ2VuZGVkJ30pO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcXFwiU3RyZWFtIGVuZGVkXFxcIik7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIH1lbHNle1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICAgIGlmKCF0aGlzLnN0YWxsZWQpIHtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhbGxlZCA9IHRydWU7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2V2ZW50VHlwZTogJ3N0YWxsZWQnfSk7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgICAgfVxcblwiICtcclxuICBcIiAgICAgICAgICAgICAgICB9XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICAgIGJyZWFrO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgfVxcblwiICtcclxuICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXFxcIm91dENoTGVuOiBcXFwiK291dENoTGVuK1xcXCIsIGNvcGllZDogXFxcIitjb3BpZWQrXFxcIiwgY3VycmVudCBhdmFpbDogXFxcIit0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckF2YWlsKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICBsZXQgdG9Db3B5PW91dENoTGVuLWNvcGllZDtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICBpZih0b0NvcHk+dGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbCl7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICB0b0NvcHk9dGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbDtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICB9XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFxcXCJDb3B5IFxcXCIrdG9Db3B5K1xcXCIgZnJhbWVzLi4uXFxcIik7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgZm9yKGxldCBjaD0wO2NoPGNocztjaCsrKSB7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgICBsZXQgb3V0Q2g9b3V0cHV0W2NoXTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdG9Db3B5OyBpKyspIHtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICAgICAgb3V0Q2hbY29waWVkK2ldPXRoaXMuY3VycmVudEF1ZGlvQnVmZmVyW2NoXVt0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckZyYW1lUG9zK2ldO1xcblwiICtcclxuICBcIiAgICAgICAgICAgICAgfVxcblwiICtcclxuICBcIiAgICAgICAgICAgIH1cXG5cIiArXHJcbiAgXCIgICAgICAgICAgICBjb3BpZWQrPXRvQ29weTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgICB0aGlzLmN1cnJlbnRBdWRpb0J1ZmZlckZyYW1lUG9zKz10b0NvcHk7XFxuXCIgK1xyXG4gIFwiICAgICAgICAgICAgdGhpcy5jdXJyZW50QXVkaW9CdWZmZXJBdmFpbC09dG9Db3B5O1xcblwiICtcclxuICBcIlxcblwiICtcclxuICBcIiAgICAgICAgICB9d2hpbGUoY29waWVkPG91dENoTGVuKTtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgdGhpcy5maWxsZWRGcmFtZXMtPWNvcGllZDtcXG5cIiArXHJcbiAgXCIgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFxcXCJDb3BpZWQgXFxcIitjb3BpZWQrXFxcIiBmcmFtZXMuXFxcIik7XFxuXCIgK1xyXG4gIFwiICAgICAgICB9XFxuXCIgK1xyXG4gIFwiICAgICByZXR1cm4gIXRoaXMuZW5kZWQ7XFxuXCIgK1xyXG4gIFwiICB9XFxuXCIgK1xyXG4gIFwifVxcblwiICtcclxuICBcIlxcblwiICtcclxuICBcInJlZ2lzdGVyUHJvY2Vzc29yKCdhdWRpby1zb3VyY2Utd29ya2xldCcsQXVkaW9Tb3VyY2VQcm9jZXNzb3IpO1xcblwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEF1ZGlvU291cmNlV29ya2xldE1vZHVsZUxvYWRlcntcclxuXHJcbiAgcHJpdmF0ZSBzdGF0aWMgbW9kdWxlTG9hZGVkPWZhbHNlO1xyXG5cclxuICBzdGF0aWMgbG9hZE1vZHVsZShjb250ZXh0OiBBdWRpb0NvbnRleHQpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIGlmIChBdWRpb1NvdXJjZVdvcmtsZXRNb2R1bGVMb2FkZXIubW9kdWxlTG9hZGVkKSB7XHJcbiAgICAgICAgcmVzb2x2ZS5jYWxsKHNlbGYpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldE1vZHVsZUJsb2IgPSBuZXcgQmxvYihbYXN3cFN0cl0sIHt0eXBlOiAndGV4dC9qYXZhc2NyaXB0J30pO1xyXG4gICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldE1vZHVsZUJsb2JVcmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChhdWRpb1dvcmtsZXRNb2R1bGVCbG9iKTtcclxuICAgICAgICBjb250ZXh0LmF1ZGlvV29ya2xldC5hZGRNb2R1bGUoYXVkaW9Xb3JrbGV0TW9kdWxlQmxvYlVybCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICBBdWRpb1NvdXJjZVdvcmtsZXRNb2R1bGVMb2FkZXIubW9kdWxlTG9hZGVkID0gdHJ1ZTtcclxuICAgICAgICAgIHJlc29sdmUuY2FsbChzZWxmKTtcclxuICAgICAgICB9KS5jYXRjaCgocmVhc29uKSA9PiB7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKHJlYXNvbik7XHJcbiAgICAgICAgICByZWplY3QuY2FsbChyZWFzb24pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcbiJdfQ==