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,167 +1,167 @@
1
- import { AsyncEditFloat32ArrayInputStream } from "../../io/stream";
2
- import { IndexedDbAudioInputStream } from "../inddb_audio_buffer";
3
- import { ArrayAudioBufferSourceNode } from "./array_audio_buffer_source_node";
4
- import { EMPTY, expand, Observable } from "rxjs";
5
- import { AudioSourceNode } from "./audio_source_node";
6
- export class IndexedDbAudioBufferSourceNode extends AudioSourceNode {
7
- constructor(context) {
8
- super(context, 'audio-source-worklet');
9
- this._bufferFillSeconds = AudioSourceNode.DEFAULT_BUFFER_FILL_SECONDS;
10
- this.bufferFillFrames = 0;
11
- this._streamReadFrameLen = AudioSourceNode.DEFAULT_STREAM_READ_FRAME_LEN * 8; // Much overhead fetching small buffers from indexed db, use larger buffer (8192).
12
- this._inddbAudioBuffer = null;
13
- this._audioInputStream = null;
14
- this._aisBufs = null;
15
- this._active = false;
16
- this._endOfStream = false;
17
- this.filledFrames = 0;
18
- this.channelCountMode = 'explicit';
19
- this.port.onmessage = (msgEv) => {
20
- if (msgEv.data) {
21
- let evType = msgEv.data.eventType;
22
- if (evType) {
23
- if ('bufferNotification' === evType) {
24
- this.filledFrames = msgEv.data.filledFrames;
25
- if (!this._endOfStream) {
26
- this.fillBufferObs().subscribe();
27
- }
28
- }
29
- else if ('ended' === evType) {
30
- //console.debug("Inddb audio source ended playback.");
31
- let drainTime = 0;
32
- if (this._inddbAudioBuffer?.sampleRate) {
33
- drainTime = ArrayAudioBufferSourceNode.QUANTUM_FRAME_LEN / this._inddbAudioBuffer.sampleRate;
34
- }
35
- //let dstAny:any=this.context.destination;
36
- //console.debug('Destination node tail-time: '+dstAny['tail-time']);
37
- window.setTimeout(() => {
38
- this.onended?.call(this);
39
- }, drainTime * 1000);
40
- }
41
- }
42
- }
43
- };
44
- }
45
- fillBufferObs(frameOffset) {
46
- let obs = new Observable(subscriber => {
47
- if (frameOffset) {
48
- subscriber.error(new Error("Starting playback from position not equal zero not supported yet."));
49
- }
50
- else {
51
- let filled = this.filledFrames;
52
- let bufLen = 0;
53
- if (this._audioInputStream && this._aisBufs) {
54
- this._audioInputStream.readObs(this._aisBufs).pipe(expand((read) => {
55
- if (read && this._aisBufs) {
56
- let trBuffers = new Array(this.channelCount);
57
- for (let ch = 0; ch < this.channelCount; ch++) {
58
- let adCh = this._aisBufs[ch];
59
- let adChCopy = new Float32Array(read);
60
- bufLen = adChCopy.length;
61
- if (read === adCh.length) {
62
- adChCopy.set(adCh);
63
- }
64
- else {
65
- // Note: slice() does not work here, since it returns a shallow copy.
66
- for (let i = 0; i < read; i++) {
67
- adChCopy[i] = adCh[i];
68
- }
69
- }
70
- trBuffers[ch] = adChCopy.buffer;
71
- }
72
- this.port.postMessage({
73
- cmd: 'data',
74
- chs: this.channelCount,
75
- audioData: trBuffers
76
- }, trBuffers);
77
- filled += read;
78
- //console.debug("IndexedDbAudioBufferSourceNode::fillBufferObs: Sent "+read+" frames to audio source worklet. Filled: "+filled+", to fill: "+this.bufferFillFrames);
79
- if (this._audioInputStream && filled < this.bufferFillFrames) {
80
- //console.debug("IndexedDbAudioBufferSourceNode::fillBufferObs: Next inddb audio input stream readObs");
81
- return this._audioInputStream.readObs(this._aisBufs);
82
- }
83
- else {
84
- //console.debug("Return EMPTY");
85
- return EMPTY;
86
- }
87
- }
88
- else {
89
- //console.debug("IndexedDbAudioBufferSourceNode::fillBufferObs: Return EMPTY (read: "+read+")");
90
- this._endOfStream = true;
91
- this.port.postMessage({
92
- cmd: 'endOfStream'
93
- });
94
- return EMPTY;
95
- }
96
- })).subscribe(subscriber);
97
- }
98
- }
99
- });
100
- return obs;
101
- }
102
- get inddbAudioBuffer() {
103
- return this._inddbAudioBuffer;
104
- }
105
- set inddbAudioBuffer(value) {
106
- this._inddbAudioBuffer = value;
107
- if (this._inddbAudioBuffer?.channelCount) {
108
- this.channelCount = this._inddbAudioBuffer?.channelCount;
109
- this.bufferFillFrames = this._inddbAudioBuffer.sampleRate * this._bufferFillSeconds;
110
- }
111
- }
112
- get bufferFillSeconds() {
113
- return this._bufferFillSeconds;
114
- }
115
- set bufferFillSeconds(value) {
116
- this._bufferFillSeconds = value;
117
- }
118
- start(when, offset, duration) {
119
- if (when) {
120
- throw Error("when parameter currently not supported by IndexedDbAudioBufferSourceNode class");
121
- }
122
- if (this._inddbAudioBuffer) {
123
- let arrAis = new IndexedDbAudioInputStream(this._inddbAudioBuffer);
124
- if (offset === undefined && duration === undefined) {
125
- this._audioInputStream = arrAis;
126
- }
127
- else {
128
- let offsetFrames = 0;
129
- let durationFrames = undefined;
130
- if (offset !== undefined) {
131
- offsetFrames = Math.floor(offset * this._inddbAudioBuffer.sampleRate);
132
- }
133
- if (duration !== undefined) {
134
- durationFrames = Math.floor(duration * this._inddbAudioBuffer.sampleRate);
135
- }
136
- //console.debug("Create AsyncEditFloat32ArrayInputStream: offsetFrames:"+offsetFrames+", durationFrames:"+durationFrames);
137
- this._audioInputStream = new AsyncEditFloat32ArrayInputStream(arrAis, offsetFrames, durationFrames);
138
- }
139
- let chs = this._inddbAudioBuffer.channelCount;
140
- this._aisBufs = new Array(chs);
141
- for (let ch = 0; ch < chs; ch++) {
142
- this._aisBufs[ch] = new Float32Array(this._streamReadFrameLen);
143
- }
144
- this.fillBufferObs().subscribe({
145
- complete: () => {
146
- //console.debug("IndexedDbAudioBufferSourceNode::start: Async play buffer fill completed. Sending start command to audio worklet.");
147
- if (this._active) {
148
- this.port.postMessage({ cmd: 'start' });
149
- if (offset) {
150
- this._playStartTime = this.context.currentTime - offset;
151
- }
152
- else {
153
- this._playStartTime = this.context.currentTime;
154
- }
155
- }
156
- }
157
- });
158
- this._active = true;
159
- }
160
- }
161
- stop() {
162
- this._active = false;
163
- this.port.postMessage({ cmd: 'stop' });
164
- this.onended?.call(this);
165
- }
166
- }
1
+ import { AsyncEditFloat32ArrayInputStream } from "../../io/stream";
2
+ import { IndexedDbAudioInputStream } from "../inddb_audio_buffer";
3
+ import { ArrayAudioBufferSourceNode } from "./array_audio_buffer_source_node";
4
+ import { EMPTY, expand, Observable } from "rxjs";
5
+ import { AudioSourceNode } from "./audio_source_node";
6
+ export class IndexedDbAudioBufferSourceNode extends AudioSourceNode {
7
+ constructor(context) {
8
+ super(context, 'audio-source-worklet');
9
+ this._bufferFillSeconds = AudioSourceNode.DEFAULT_BUFFER_FILL_SECONDS;
10
+ this.bufferFillFrames = 0;
11
+ this._streamReadFrameLen = AudioSourceNode.DEFAULT_STREAM_READ_FRAME_LEN * 8; // Much overhead fetching small buffers from indexed db, use larger buffer (8192).
12
+ this._inddbAudioBuffer = null;
13
+ this._audioInputStream = null;
14
+ this._aisBufs = null;
15
+ this._active = false;
16
+ this._endOfStream = false;
17
+ this.filledFrames = 0;
18
+ this.channelCountMode = 'explicit';
19
+ this.port.onmessage = (msgEv) => {
20
+ if (msgEv.data) {
21
+ let evType = msgEv.data.eventType;
22
+ if (evType) {
23
+ if ('bufferNotification' === evType) {
24
+ this.filledFrames = msgEv.data.filledFrames;
25
+ if (!this._endOfStream) {
26
+ this.fillBufferObs().subscribe();
27
+ }
28
+ }
29
+ else if ('ended' === evType) {
30
+ //console.debug("Inddb audio source ended playback.");
31
+ let drainTime = 0;
32
+ if (this._inddbAudioBuffer?.sampleRate) {
33
+ drainTime = ArrayAudioBufferSourceNode.QUANTUM_FRAME_LEN / this._inddbAudioBuffer.sampleRate;
34
+ }
35
+ //let dstAny:any=this.context.destination;
36
+ //console.debug('Destination node tail-time: '+dstAny['tail-time']);
37
+ window.setTimeout(() => {
38
+ this.onended?.call(this);
39
+ }, drainTime * 1000);
40
+ }
41
+ }
42
+ }
43
+ };
44
+ }
45
+ fillBufferObs(frameOffset) {
46
+ let obs = new Observable(subscriber => {
47
+ if (frameOffset) {
48
+ subscriber.error(new Error("Starting playback from position not equal zero not supported yet."));
49
+ }
50
+ else {
51
+ let filled = this.filledFrames;
52
+ let bufLen = 0;
53
+ if (this._audioInputStream && this._aisBufs) {
54
+ this._audioInputStream.readObs(this._aisBufs).pipe(expand((read) => {
55
+ if (read && this._aisBufs) {
56
+ let trBuffers = new Array(this.channelCount);
57
+ for (let ch = 0; ch < this.channelCount; ch++) {
58
+ let adCh = this._aisBufs[ch];
59
+ let adChCopy = new Float32Array(read);
60
+ bufLen = adChCopy.length;
61
+ if (read === adCh.length) {
62
+ adChCopy.set(adCh);
63
+ }
64
+ else {
65
+ // Note: slice() does not work here, since it returns a shallow copy.
66
+ for (let i = 0; i < read; i++) {
67
+ adChCopy[i] = adCh[i];
68
+ }
69
+ }
70
+ trBuffers[ch] = adChCopy.buffer;
71
+ }
72
+ this.port.postMessage({
73
+ cmd: 'data',
74
+ chs: this.channelCount,
75
+ audioData: trBuffers
76
+ }, trBuffers);
77
+ filled += read;
78
+ //console.debug("IndexedDbAudioBufferSourceNode::fillBufferObs: Sent "+read+" frames to audio source worklet. Filled: "+filled+", to fill: "+this.bufferFillFrames);
79
+ if (this._audioInputStream && filled < this.bufferFillFrames) {
80
+ //console.debug("IndexedDbAudioBufferSourceNode::fillBufferObs: Next inddb audio input stream readObs");
81
+ return this._audioInputStream.readObs(this._aisBufs);
82
+ }
83
+ else {
84
+ //console.debug("Return EMPTY");
85
+ return EMPTY;
86
+ }
87
+ }
88
+ else {
89
+ //console.debug("IndexedDbAudioBufferSourceNode::fillBufferObs: Return EMPTY (read: "+read+")");
90
+ this._endOfStream = true;
91
+ this.port.postMessage({
92
+ cmd: 'endOfStream'
93
+ });
94
+ return EMPTY;
95
+ }
96
+ })).subscribe(subscriber);
97
+ }
98
+ }
99
+ });
100
+ return obs;
101
+ }
102
+ get inddbAudioBuffer() {
103
+ return this._inddbAudioBuffer;
104
+ }
105
+ set inddbAudioBuffer(value) {
106
+ this._inddbAudioBuffer = value;
107
+ if (this._inddbAudioBuffer?.channelCount) {
108
+ this.channelCount = this._inddbAudioBuffer?.channelCount;
109
+ this.bufferFillFrames = this._inddbAudioBuffer.sampleRate * this._bufferFillSeconds;
110
+ }
111
+ }
112
+ get bufferFillSeconds() {
113
+ return this._bufferFillSeconds;
114
+ }
115
+ set bufferFillSeconds(value) {
116
+ this._bufferFillSeconds = value;
117
+ }
118
+ start(when, offset, duration) {
119
+ if (when) {
120
+ throw Error("when parameter currently not supported by IndexedDbAudioBufferSourceNode class");
121
+ }
122
+ if (this._inddbAudioBuffer) {
123
+ let arrAis = new IndexedDbAudioInputStream(this._inddbAudioBuffer);
124
+ if (offset === undefined && duration === undefined) {
125
+ this._audioInputStream = arrAis;
126
+ }
127
+ else {
128
+ let offsetFrames = 0;
129
+ let durationFrames = undefined;
130
+ if (offset !== undefined) {
131
+ offsetFrames = Math.floor(offset * this._inddbAudioBuffer.sampleRate);
132
+ }
133
+ if (duration !== undefined) {
134
+ durationFrames = Math.floor(duration * this._inddbAudioBuffer.sampleRate);
135
+ }
136
+ //console.debug("Create AsyncEditFloat32ArrayInputStream: offsetFrames:"+offsetFrames+", durationFrames:"+durationFrames);
137
+ this._audioInputStream = new AsyncEditFloat32ArrayInputStream(arrAis, offsetFrames, durationFrames);
138
+ }
139
+ let chs = this._inddbAudioBuffer.channelCount;
140
+ this._aisBufs = new Array(chs);
141
+ for (let ch = 0; ch < chs; ch++) {
142
+ this._aisBufs[ch] = new Float32Array(this._streamReadFrameLen);
143
+ }
144
+ this.fillBufferObs().subscribe({
145
+ complete: () => {
146
+ //console.debug("IndexedDbAudioBufferSourceNode::start: Async play buffer fill completed. Sending start command to audio worklet.");
147
+ if (this._active) {
148
+ this.port.postMessage({ cmd: 'start' });
149
+ if (offset) {
150
+ this._playStartTime = this.context.currentTime - offset;
151
+ }
152
+ else {
153
+ this._playStartTime = this.context.currentTime;
154
+ }
155
+ }
156
+ }
157
+ });
158
+ this._active = true;
159
+ }
160
+ }
161
+ stop() {
162
+ this._active = false;
163
+ this.port.postMessage({ cmd: 'stop' });
164
+ this.onended?.call(this);
165
+ }
166
+ }
167
167
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZGJfYXVkaW9fYnVmZmVyX3NvdXJjZV9ub2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3BsYXliYWNrL2luZGRiX2F1ZGlvX2J1ZmZlcl9zb3VyY2Vfbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsZ0NBQWdDLEVBQStCLE1BQU0saUJBQWlCLENBQUM7QUFDL0YsT0FBTyxFQUF1Qix5QkFBeUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ3RGLE9BQU8sRUFBQywwQkFBMEIsRUFBQyxNQUFNLGtDQUFrQyxDQUFDO0FBQzVFLE9BQU8sRUFBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUMvQyxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFFcEQsTUFBTSxPQUFPLDhCQUErQixTQUFRLGVBQWU7SUFZakUsWUFBWSxPQUFxQjtRQUUvQixLQUFLLENBQUMsT0FBTyxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFaakMsdUJBQWtCLEdBQUcsZUFBZSxDQUFDLDJCQUEyQixDQUFDO1FBQ2pFLHFCQUFnQixHQUFHLENBQUMsQ0FBQztRQUNyQix3QkFBbUIsR0FBQyxlQUFlLENBQUMsNkJBQTZCLEdBQUcsQ0FBQyxDQUFDLENBQUUsa0ZBQWtGO1FBQzFKLHNCQUFpQixHQUEyQixJQUFJLENBQUM7UUFDakQsc0JBQWlCLEdBQW1DLElBQUksQ0FBQztRQUN6RCxhQUFRLEdBQXFCLElBQUksQ0FBQztRQUNsQyxZQUFPLEdBQUMsS0FBSyxDQUFDO1FBQ2QsaUJBQVksR0FBQyxLQUFLLENBQUM7UUFDbkIsaUJBQVksR0FBRyxDQUFDLENBQUM7UUFLdkIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFVBQVUsQ0FBQztRQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFD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OlsiaW1wb3J0IHtBc3luY0VkaXRGbG9hdDMyQXJyYXlJbnB1dFN0cmVhbSwgQXN5bmNGbG9hdDMyQXJyYXlJbnB1dFN0cmVhbX0gZnJvbSBcIi4uLy4uL2lvL3N0cmVhbVwiO1xyXG5pbXBvcnQge0luZGV4ZWREYkF1ZGlvQnVmZmVyLCBJbmRleGVkRGJBdWRpb0lucHV0U3RyZWFtfSBmcm9tIFwiLi4vaW5kZGJfYXVkaW9fYnVmZmVyXCI7XHJcbmltcG9ydCB7QXJyYXlBdWRpb0J1ZmZlclNvdXJjZU5vZGV9IGZyb20gXCIuL2FycmF5X2F1ZGlvX2J1ZmZlcl9zb3VyY2Vfbm9kZVwiO1xyXG5pbXBvcnQge0VNUFRZLCBleHBhbmQsIE9ic2VydmFibGV9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7QXVkaW9Tb3VyY2VOb2RlfSBmcm9tIFwiLi9hdWRpb19zb3VyY2Vfbm9kZVwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEluZGV4ZWREYkF1ZGlvQnVmZmVyU291cmNlTm9kZSBleHRlbmRzIEF1ZGlvU291cmNlTm9kZSB7XHJcblxyXG4gIHByaXZhdGUgX2J1ZmZlckZpbGxTZWNvbmRzID0gQXVkaW9Tb3VyY2VOb2RlLkRFRkFVTFRfQlVGRkVSX0ZJTExfU0VDT05EUztcclxuICBwcml2YXRlIGJ1ZmZlckZpbGxGcmFtZXMgPSAwO1xyXG4gIHByaXZhdGUgX3N0cmVhbVJlYWRGcmFtZUxlbj1BdWRpb1NvdXJjZU5vZGUuREVGQVVMVF9TVFJFQU1fUkVBRF9GUkFNRV9MRU4gKiA4OyAgLy8gTXVjaCBvdmVyaGVhZCBmZXRjaGluZyBzbWFsbCBidWZmZXJzIGZyb20gaW5kZXhlZCBkYiwgdXNlIGxhcmdlciBidWZmZXIgKDgxOTIpLlxyXG4gIHByaXZhdGUgX2luZGRiQXVkaW9CdWZmZXI6SW5kZXhlZERiQXVkaW9CdWZmZXJ8bnVsbD1udWxsO1xyXG4gIHByaXZhdGUgX2F1ZGlvSW5wdXRTdHJlYW06QXN5bmNGbG9hdDMyQXJyYXlJbnB1dFN0cmVhbXxudWxsPW51bGw7XHJcbiAgcHJpdmF0ZSBfYWlzQnVmczpGbG9hdDMyQXJyYXlbXXxudWxsPW51bGw7XHJcbiAgcHJpdmF0ZSBfYWN0aXZlPWZhbHNlO1xyXG4gIHByaXZhdGUgX2VuZE9mU3RyZWFtPWZhbHNlO1xyXG4gIHByaXZhdGUgZmlsbGVkRnJhbWVzID0gMDtcclxuXHJcbiAgY29uc3RydWN0b3IoY29udGV4dDogQXVkaW9Db250ZXh0KSB7XHJcblxyXG4gICAgc3VwZXIoY29udGV4dCwgJ2F1ZGlvLXNvdXJjZS13b3JrbGV0Jyk7XHJcbiAgICB0aGlzLmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xyXG4gICAgdGhpcy5wb3J0Lm9ubWVzc2FnZSA9IChtc2dFdjogTWVzc2FnZUV2ZW50KSA9PiB7XHJcbiAgICAgIGlmIChtc2dFdi5kYXRhKSB7XHJcbiAgICAgICAgbGV0IGV2VHlwZSA9IG1zZ0V2LmRhdGEuZXZlbnRUeXBlO1xyXG4gICAgICAgIGlmIChldlR5cGUpIHtcclxuICAgICAgICAgIGlmICgnYnVmZmVyTm90aWZpY2F0aW9uJyA9PT0gZXZUeXBlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZmlsbGVkRnJhbWVzID0gbXNnRXYuZGF0YS5maWxsZWRGcmFtZXM7XHJcbiAgICAgICAgICAgIGlmKCF0aGlzLl9lbmRPZlN0cmVhbSkge1xyXG4gICAgICAgICAgICAgIHRoaXMuZmlsbEJ1ZmZlck9icygpLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKCdlbmRlZCcgPT09IGV2VHlwZSkge1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJJbmRkYiBhdWRpbyBzb3VyY2UgZW5kZWQgcGxheWJhY2suXCIpO1xyXG4gICAgICAgICAgICBsZXQgZHJhaW5UaW1lID0gMDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2luZGRiQXVkaW9CdWZmZXI/LnNhbXBsZVJhdGUpIHtcclxuICAgICAgICAgICAgICBkcmFpblRpbWUgPSBBcnJheUF1ZGlvQnVmZmVyU291cmNlTm9kZS5RVUFOVFVNX0ZSQU1FX0xFTiAvIHRoaXMuX2luZGRiQXVkaW9CdWZmZXIuc2FtcGxlUmF0ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvL2xldCBkc3RBbnk6YW55PXRoaXMuY29udGV4dC5kZXN0aW5hdGlvbjtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdEZXN0aW5hdGlvbiBub2RlIHRhaWwtdGltZTogJytkc3RBbnlbJ3RhaWwtdGltZSddKTtcclxuICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMub25lbmRlZD8uY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgfSwgZHJhaW5UaW1lICogMTAwMCk7XHJcblxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBmaWxsQnVmZmVyT2JzKGZyYW1lT2Zmc2V0PzpudW1iZXIpOk9ic2VydmFibGU8bnVtYmVyfG51bGw+IHtcclxuXHJcbiAgICAgIGxldCBvYnMgPSBuZXcgT2JzZXJ2YWJsZTxudW1iZXIgfCBudWxsPihzdWJzY3JpYmVyID0+IHtcclxuICAgICAgICBpZihmcmFtZU9mZnNldCl7XHJcbiAgICAgICAgICBzdWJzY3JpYmVyLmVycm9yKG5ldyBFcnJvcihcIlN0YXJ0aW5nIHBsYXliYWNrIGZyb20gcG9zaXRpb24gbm90IGVxdWFsIHplcm8gbm90IHN1cHBvcnRlZCB5ZXQuXCIpKTtcclxuICAgICAgICB9ZWxzZSB7XHJcbiAgICAgICAgICBsZXQgZmlsbGVkID0gdGhpcy5maWxsZWRGcmFtZXM7XHJcbiAgICAgICAgICBsZXQgYnVmTGVuID0gMDtcclxuICAgICAgICAgIGlmICh0aGlzLl9hdWRpb0lucHV0U3RyZWFtICYmIHRoaXMuX2Fpc0J1ZnMpIHtcclxuICAgICAgICAgICAgdGhpcy5fYXVkaW9JbnB1dFN0cmVhbS5yZWFkT2JzKHRoaXMuX2Fpc0J1ZnMpLnBpcGUoXHJcbiAgICAgICAgICAgICAgZXhwYW5kKChyZWFkKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChyZWFkICYmIHRoaXMuX2Fpc0J1ZnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgdHJCdWZmZXJzID0gbmV3IEFycmF5PGFueT4odGhpcy5jaGFubmVsQ291bnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGNoID0gMDsgY2ggPCB0aGlzLmNoYW5uZWxDb3VudDsgY2grKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgbGV0IGFkQ2ggPSB0aGlzLl9haXNCdWZzW2NoXTtcclxuICAgICAgICAgICAgICAgICAgICAgIGxldCBhZENoQ29weSA9IG5ldyBGbG9hdDMyQXJyYXkocmVhZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICBidWZMZW4gPSBhZENoQ29weS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICBpZihyZWFkPT09YWRDaC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRDaENvcHkuc2V0KGFkQ2gpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGU6IHNsaWNlKCkgZG9lcyBub3Qgd29yayBoZXJlLCBzaW5jZSBpdCByZXR1cm5zIGEgc2hhbGxvdyBjb3B5LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IobGV0IGk9MDtpPHJlYWQ7aSsrKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBhZENoQ29weVtpXT1hZENoW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICB0ckJ1ZmZlcnNbY2hdID0gYWRDaENvcHkuYnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgY21kOiAnZGF0YScsXHJcbiAgICAgICAgICAgICAgICAgICAgICBjaHM6IHRoaXMuY2hhbm5lbENvdW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgYXVkaW9EYXRhOiB0ckJ1ZmZlcnNcclxuICAgICAgICAgICAgICAgICAgICB9LCB0ckJ1ZmZlcnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbGxlZCArPSByZWFkO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkluZGV4ZWREYkF1ZGlvQnVmZmVyU291cmNlTm9kZTo6ZmlsbEJ1ZmZlck9iczogU2VudCBcIityZWFkK1wiIGZyYW1lcyB0byBhdWRpbyBzb3VyY2Ugd29ya2xldC4gRmlsbGVkOiBcIitmaWxsZWQrXCIsIHRvIGZpbGw6IFwiK3RoaXMuYnVmZmVyRmlsbEZyYW1lcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvSW5wdXRTdHJlYW0gJiYgZmlsbGVkIDwgdGhpcy5idWZmZXJGaWxsRnJhbWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJJbmRleGVkRGJBdWRpb0J1ZmZlclNvdXJjZU5vZGU6OmZpbGxCdWZmZXJPYnM6IE5leHQgaW5kZGIgYXVkaW8gaW5wdXQgc3RyZWFtIHJlYWRPYnNcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYXVkaW9JbnB1dFN0cmVhbS5yZWFkT2JzKHRoaXMuX2Fpc0J1ZnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUuZGVidWcoXCJSZXR1cm4gRU1QVFlcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkluZGV4ZWREYkF1ZGlvQnVmZmVyU291cmNlTm9kZTo6ZmlsbEJ1ZmZlck9iczogUmV0dXJuIEVNUFRZIChyZWFkOiBcIityZWFkK1wiKVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbmRPZlN0cmVhbT10cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgICBjbWQ6ICdlbmRPZlN0cmVhbSdcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRU1QVFk7XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICkuc3Vic2NyaWJlKHN1YnNjcmliZXIpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIHJldHVybiBvYnM7XHJcbiAgfVxyXG5cclxuXHJcbiAgZ2V0IGluZGRiQXVkaW9CdWZmZXIoKTogSW5kZXhlZERiQXVkaW9CdWZmZXIgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl9pbmRkYkF1ZGlvQnVmZmVyXHJcbiAgfVxyXG5cclxuICBzZXQgaW5kZGJBdWRpb0J1ZmZlcih2YWx1ZTogSW5kZXhlZERiQXVkaW9CdWZmZXIgfCBudWxsKSB7XHJcbiAgICB0aGlzLl9pbmRkYkF1ZGlvQnVmZmVyID0gdmFsdWU7XHJcbiAgICBpZiAodGhpcy5faW5kZGJBdWRpb0J1ZmZlcj8uY2hhbm5lbENvdW50KSB7XHJcbiAgICAgIHRoaXMuY2hhbm5lbENvdW50ID0gdGhpcy5faW5kZGJBdWRpb0J1ZmZlcj8uY2hhbm5lbENvdW50O1xyXG4gICAgICB0aGlzLmJ1ZmZlckZpbGxGcmFtZXMgPSB0aGlzLl9pbmRkYkF1ZGlvQnVmZmVyLnNhbXBsZVJhdGUgKiB0aGlzLl9idWZmZXJGaWxsU2Vjb25kcztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldCBidWZmZXJGaWxsU2Vjb25kcygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2J1ZmZlckZpbGxTZWNvbmRzO1xyXG4gIH1cclxuXHJcbiAgc2V0IGJ1ZmZlckZpbGxTZWNvbmRzKHZhbHVlOiBudW1iZXIpIHtcclxuICAgIHRoaXMuX2J1ZmZlckZpbGxTZWNvbmRzID0gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBzdGFydCh3aGVuPzogbnVtYmVyIHwgdW5kZWZpbmVkLG9mZnNldD86IG51bWJlciB8IHVuZGVmaW5lZCxkdXJhdGlvbj86IG51bWJlciB8IHVuZGVmaW5lZCk6IHZvaWQge1xyXG4gICAgaWYgKHdoZW4pIHtcclxuICAgICAgdGhyb3cgRXJyb3IoXCJ3aGVuIHBhcmFtZXRlciBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCBieSBJbmRleGVkRGJBdWRpb0J1ZmZlclNvdXJjZU5vZGUgY2xhc3NcIilcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5faW5kZGJBdWRpb0J1ZmZlcikge1xyXG4gICAgICBsZXQgYXJyQWlzPW5ldyBJbmRleGVkRGJBdWRpb0lucHV0U3RyZWFtKHRoaXMuX2luZGRiQXVkaW9CdWZmZXIpO1xyXG4gICAgICBpZihvZmZzZXQ9PT11bmRlZmluZWQgJiYgZHVyYXRpb249PT11bmRlZmluZWQpe1xyXG4gICAgICAgIHRoaXMuX2F1ZGlvSW5wdXRTdHJlYW0gPSBhcnJBaXM7XHJcbiAgICAgIH1lbHNle1xyXG4gICAgICAgIGxldCBvZmZzZXRGcmFtZXM9MDtcclxuICAgICAgICBsZXQgZHVyYXRpb25GcmFtZXM9dW5kZWZpbmVkO1xyXG4gICAgICAgIGlmKG9mZnNldCE9PXVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgb2Zmc2V0RnJhbWVzPU1hdGguZmxvb3Iob2Zmc2V0ICogdGhpcy5faW5kZGJBdWRpb0J1ZmZlci5zYW1wbGVSYXRlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYoZHVyYXRpb24hPT11bmRlZmluZWQpe1xyXG4gICAgICAgICAgZHVyYXRpb25GcmFtZXM9TWF0aC5mbG9vcihkdXJhdGlvbiAqIHRoaXMuX2luZGRiQXVkaW9CdWZmZXIuc2FtcGxlUmF0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vY29uc29sZS5kZWJ1ZyhcIkNyZWF0ZSBBc3luY0VkaXRGbG9hdDMyQXJyYXlJbnB1dFN0cmVhbTogb2Zmc2V0RnJhbWVzOlwiK29mZnNldEZyYW1lcytcIiwgZHVyYXRpb25GcmFtZXM6XCIrZHVyYXRpb25GcmFtZXMpO1xyXG4gICAgICAgIHRoaXMuX2F1ZGlvSW5wdXRTdHJlYW09bmV3IEFzeW5jRWRpdEZsb2F0MzJBcnJheUlucHV0U3RyZWFtKGFyckFpcyxvZmZzZXRGcmFtZXMsZHVyYXRpb25GcmFtZXMpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBsZXQgY2hzPXRoaXMuX2luZGRiQXVkaW9CdWZmZXIuY2hhbm5lbENvdW50O1xyXG4gICAgICB0aGlzLl9haXNCdWZzPW5ldyBBcnJheTxGbG9hdDMyQXJyYXk+KGNocyk7XHJcbiAgICAgIGZvcihsZXQgY2g9MDtjaDxjaHM7Y2grKyl7XHJcbiAgICAgICAgdGhpcy5fYWlzQnVmc1tjaF09bmV3IEZsb2F0MzJBcnJheSh0aGlzLl9zdHJlYW1SZWFkRnJhbWVMZW4pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmZpbGxCdWZmZXJPYnMoKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgIGNvbXBsZXRlOiAoKT0+e1xyXG4gICAgICAgICAgLy9jb25zb2xlLmRlYnVnKFwiSW5kZXhlZERiQXVkaW9CdWZmZXJTb3VyY2VOb2RlOjpzdGFydDogQXN5bmMgcGxheSBidWZmZXIgZmlsbCBjb21wbGV0ZWQuIFNlbmRpbmcgc3RhcnQgY29tbWFuZCB0byBhdWRpbyB3b3JrbGV0LlwiKTtcclxuICAgICAgICAgIGlmKHRoaXMuX2FjdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2Uoe2NtZDogJ3N0YXJ0J30pO1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0KSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fcGxheVN0YXJ0VGltZSA9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZSAtIG9mZnNldDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICB0aGlzLl9wbGF5U3RhcnRUaW1lID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgdGhpcy5fYWN0aXZlPXRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdG9wKCkge1xyXG4gICAgdGhpcy5fYWN0aXZlPWZhbHNlO1xyXG4gICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlKHtjbWQ6ICdzdG9wJ30pO1xyXG4gICAgdGhpcy5vbmVuZGVkPy5jYWxsKHRoaXMpO1xyXG4gIH1cclxuXHJcbn1cclxuXHJcbiJdfQ==