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,19 +1,19 @@
1
- export class Point {
2
- constructor(_x, _y) {
3
- this._x = _x;
4
- this._y = _y;
5
- }
6
- get x() {
7
- return this._x;
8
- }
9
- get y() {
10
- return this._y;
11
- }
12
- }
13
- export class Marker {
14
- constructor() {
15
- this.name = null;
16
- this.framePosition = null;
17
- }
18
- }
1
+ export class Point {
2
+ constructor(_x, _y) {
3
+ this._x = _x;
4
+ this._y = _y;
5
+ }
6
+ get x() {
7
+ return this._x;
8
+ }
9
+ get y() {
10
+ return this._y;
11
+ }
12
+ }
13
+ export class Marker {
14
+ constructor() {
15
+ this.name = null;
16
+ this.framePosition = null;
17
+ }
18
+ }
19
19
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3VpL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDSSxNQUFNLE9BQU8sS0FBSztJQUNkLFlBQW9CLEVBQVMsRUFBUyxFQUFTO1FBQTNCLE9BQUUsR0FBRixFQUFFLENBQU87UUFBUyxPQUFFLEdBQUYsRUFBRSxDQUFPO0lBQy9DLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUNELElBQUksQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNuQixDQUFDO0NBQ0o7QUFDRCxNQUFNLE9BQU8sTUFBTTtJQUFuQjtRQUNJLFNBQUksR0FBYyxJQUFJLENBQUM7UUFDdkIsa0JBQWEsR0FBYyxJQUFJLENBQUM7SUFFcEMsQ0FBQztDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiXHJcbiAgICBleHBvcnQgY2xhc3MgUG9pbnQge1xyXG4gICAgICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX3g6bnVtYmVyLHByaXZhdGUgX3k6bnVtYmVyKSB7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGdldCB4KCk6bnVtYmVye1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5feDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZ2V0IHkoKTpudW1iZXJ7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl95O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGV4cG9ydCBjbGFzcyBNYXJrZXIge1xyXG4gICAgICAgIG5hbWU6IHN0cmluZ3xudWxsPW51bGw7XHJcbiAgICAgICAgZnJhbWVQb3NpdGlvbjogbnVtYmVyfG51bGw9bnVsbDtcclxuXHJcbiAgICB9XHJcblxyXG5cclxuIl19
@@ -0,0 +1,414 @@
1
+ import { HostListener, Input, Output, EventEmitter } from '@angular/core';
2
+ import { AudioSignal } from './audiosignal';
3
+ import { Sonagram } from './sonagram';
4
+ import { Point } from './common';
5
+ import { Component, ViewChild } from '@angular/core';
6
+ import { Position, Dimension, Rectangle } from "../../math/2d/geometry";
7
+ import { BasicAudioCanvasLayerComponent } from "./audio_canvas_layer_comp";
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "./audiosignal";
10
+ import * as i2 from "./sonagram";
11
+ /*
12
+ ResizeObserver not yet available in official Typescript declaration
13
+ Crreated declaration from IDL until its available.
14
+ See specs:
15
+ https://www.w3.org/TR/resize-observer
16
+
17
+ */
18
+ // interface ResizeObserverSize {
19
+ // readonly inlineSize:number;
20
+ // readonly blockSize:number;
21
+ // }
22
+ //
23
+ // declare interface ResizeObserverEntry{
24
+ // readonly target: Element;
25
+ // readonly contentRect: DOMRectReadOnly ;
26
+ // readonly borderBoxSize: Array<ResizeObserverSize> ;
27
+ // readonly contentBoxSize: Array<ResizeObserverSize> ;
28
+ // readonly devicePixelContentBoxSize: Array<ResizeObserverSize> ;
29
+ // }
30
+ //
31
+ // declare interface ResizeObserverCallback {
32
+ // (entries: Array<ResizeObserverEntry>, observer: ResizeObserver):void;
33
+ // }
34
+ //
35
+ // declare enum ResizeObserverBoxOptions {
36
+ // "border-box", "content-box", "device-pixel-content-box"
37
+ // };
38
+ // // Declare Resizeobserver
39
+ // declare class ResizeObserver{
40
+ // constructor(callback: ResizeObserverCallback);
41
+ // observe: (el:Element,opts: ResizeObserverBoxOptions | null)=>void;
42
+ // unobserve: (el:Element)=>void;
43
+ // disconnect: ()=>void;
44
+ // }
45
+ /*
46
+ * Container component for audio display.
47
+ * The display elements are children of a virtual canvas. The virtual canvas makes it possible to have high zoom factors with very wide virtual audio displays.
48
+ * Only the visible part of the virtual canvas is implemented as a browser canvas and therefore consuming memory.
49
+ * The visible part has the same width as the viewport of the scroll pane parent.
50
+ * The virtual canvas itself is implemented as an HTML div element.
51
+ * The layout of the component is updated on resize of the parent or changes of the zoom factor.
52
+ */
53
+ export class AudioClipUIContainer extends BasicAudioCanvasLayerComponent {
54
+ static { this.DIVIDER_PIXEL_SIZE = 10; }
55
+ get xZoom() {
56
+ return this._xZoom;
57
+ }
58
+ set xZoom(value) {
59
+ this.userAction = true;
60
+ this._xZoom = value;
61
+ this.layout();
62
+ this.userAction = false;
63
+ }
64
+ set fixFitToPanel(value) {
65
+ this._fixFitToPanel = value;
66
+ if (value) {
67
+ // we don't need clip bounds
68
+ this.bounds = null;
69
+ this._xZoom = null;
70
+ }
71
+ else {
72
+ // hold current zoom value
73
+ //this._xZoom=this.ce.offsetWidth/this._audioData.duration;
74
+ }
75
+ this.layout();
76
+ }
77
+ constructor(ref) {
78
+ super();
79
+ this.ref = ref;
80
+ this._audioClip = null;
81
+ this.pointer = null;
82
+ this.selecting = null;
83
+ this.selection = null;
84
+ this.selectionEventEmitter = new EventEmitter();
85
+ this._playFramePosition = null;
86
+ this.dragStartMouseY = null;
87
+ this.dragStartY = null;
88
+ this.dividerPosition = 0.5;
89
+ this.userAction = false;
90
+ this._xZoom = null; // pixels per second
91
+ // if true the complete audio file is shown, the display fits to the visible panel, the x-zoom factor is variable, this is the default
92
+ this._fixFitToPanel = true;
93
+ this.parentE = this.ref.nativeElement;
94
+ }
95
+ ngOnInit() {
96
+ this.ce = this.ceRef.nativeElement;
97
+ this.dc = this.canvasRef.nativeElement;
98
+ }
99
+ ngAfterViewInit() {
100
+ this.layout();
101
+ const heightListener = new MutationObserver((mrs, mo) => {
102
+ let layout = false;
103
+ mrs.forEach((mr) => {
104
+ if (!this.userAction && 'attributes' === mr.type && ('class' === mr.attributeName || 'style' === mr.attributeName)) {
105
+ layout = true;
106
+ }
107
+ });
108
+ if (layout) {
109
+ // re-layout required
110
+ this.layout(false);
111
+ }
112
+ });
113
+ heightListener.observe(this.ce, { attributes: true, childList: true, characterData: true });
114
+ heightListener.observe(this.dc, { attributes: true, childList: true, characterData: true });
115
+ const resizeObserver = new ResizeObserver((entries, obs) => {
116
+ //console.log("Resize observed:");
117
+ entries.forEach((e) => {
118
+ //console.log(e.contentRect.width+"x"+e.contentRect.height);
119
+ this.layout();
120
+ });
121
+ });
122
+ resizeObserver.observe(this.ce);
123
+ }
124
+ onResize(event) {
125
+ this.layout();
126
+ }
127
+ mouseover(me) {
128
+ this.dividerCursorPosition(me, true);
129
+ }
130
+ mouseleave(me) {
131
+ this.dividerCursorPosition(me, false);
132
+ }
133
+ mousedown(me) {
134
+ this.dragStartMouseY = me.clientY;
135
+ this.dragStartY = this.dc.offsetTop;
136
+ this.dragStartMouseY = me.clientY;
137
+ }
138
+ onMouseup(me) {
139
+ if (this.dragStartY != null) {
140
+ this.userAction = true;
141
+ this.dividerDrag(me);
142
+ this.layout(false);
143
+ this.dragStartY = null;
144
+ this.userAction = false;
145
+ }
146
+ }
147
+ onMousemove(me) {
148
+ if (this.dragStartY != null) {
149
+ this.userAction = true;
150
+ this.dividerDrag(me);
151
+ this.layoutScaled();
152
+ this.userAction = true;
153
+ }
154
+ }
155
+ pointerPositionChanged(pp) {
156
+ this.pointer = pp;
157
+ }
158
+ selectingChanged(s) {
159
+ this.selecting = s;
160
+ }
161
+ selectionChanged(s) {
162
+ this.selection = s;
163
+ if (this._audioClip) {
164
+ this._audioClip.selection = s;
165
+ }
166
+ this.selectionEventEmitter.emit(this.selection);
167
+ }
168
+ canvasMousePos(c, e) {
169
+ const cr = c.getBoundingClientRect();
170
+ const x = e.x - cr.left;
171
+ const y = e.y - cr.top;
172
+ return new Point(x, y);
173
+ }
174
+ dividerCursorPosition(e, show) {
175
+ if (this.dc) {
176
+ this.canvasMousePos(this.dc, e);
177
+ }
178
+ }
179
+ dividerDrag(e) {
180
+ if (this.dc && this.dragStartMouseY && this.dragStartY) {
181
+ const dragOffset = e.clientY - this.dragStartMouseY;
182
+ const ceHeight = this.ce.offsetHeight;
183
+ let newTop = (this.dragStartY + dragOffset);
184
+ if (newTop < 0) {
185
+ newTop = 0;
186
+ }
187
+ if (newTop > ceHeight - AudioClipUIContainer.DIVIDER_PIXEL_SIZE) {
188
+ newTop = ceHeight - AudioClipUIContainer.DIVIDER_PIXEL_SIZE;
189
+ }
190
+ this.dc.style.top = newTop.toString() + 'px';
191
+ this.dividerPosition = (this.dc.offsetTop + AudioClipUIContainer.DIVIDER_PIXEL_SIZE / 2) / ceHeight;
192
+ if (this.dividerPosition > 1.0) {
193
+ this.dividerPosition = 1.0;
194
+ }
195
+ if (this.dividerPosition < 0.0) {
196
+ this.dividerPosition = 0.0;
197
+ }
198
+ this.drawDivider();
199
+ }
200
+ }
201
+ drawDivider() {
202
+ const w = this.dc.width;
203
+ const h = this.dc.height;
204
+ const g = this.dc.getContext('2d');
205
+ if (g && w > 10 && h >= 1) {
206
+ g.fillStyle = 'white';
207
+ g.fillRect(0, 0, w, h);
208
+ g.fillStyle = 'black';
209
+ g.fillRect(5, 5, w - 10, 1);
210
+ }
211
+ }
212
+ clipBounds(clipBounds) {
213
+ this.bounds = clipBounds;
214
+ this.layout();
215
+ }
216
+ currentXZoom() {
217
+ let xz = this._xZoom;
218
+ if (xz == null && this._audioDataHolder) {
219
+ let ow = this.ce.offsetWidth;
220
+ if (ow < 1) {
221
+ // at least one pixel width to avoid x-zoom zero values
222
+ ow = 1;
223
+ }
224
+ xz = ow / this._audioDataHolder.duration;
225
+ }
226
+ return xz;
227
+ }
228
+ _layout(clear, redraw) {
229
+ let ceBcr = this.ce.getBoundingClientRect();
230
+ const ceBcrIntW = Math.floor(ceBcr.width);
231
+ const ceBcrIntH = Math.floor(ceBcr.height);
232
+ // height available for plugins (audiosignal and sonagram)
233
+ let psH = ceBcrIntH - AudioClipUIContainer.DIVIDER_PIXEL_SIZE;
234
+ if (psH < 0) {
235
+ psH = 0;
236
+ }
237
+ // audio signal height
238
+ const asH = Math.round(psH * this.dividerPosition);
239
+ // sonagram height (rest: available height minus divider height minus audiosignal height)
240
+ let soH = ceBcrIntH - AudioClipUIContainer.DIVIDER_PIXEL_SIZE - asH;
241
+ if (soH < 0) {
242
+ soH = 0;
243
+ }
244
+ // sonagram top position
245
+ const soTop = asH + AudioClipUIContainer.DIVIDER_PIXEL_SIZE;
246
+ // Visible bounds
247
+ // left position
248
+ let vbLeft = 0;
249
+ // width
250
+ let vbWidth = ceBcrIntW;
251
+ if (!this._fixFitToPanel && this.bounds) {
252
+ vbLeft = Math.round(this.bounds.position.left);
253
+ vbWidth = Math.round(this.bounds.dimension.width);
254
+ }
255
+ // Divider
256
+ // left position
257
+ let vbLeftStyl = vbLeft + 'px';
258
+ if (this.dc.style.left != vbLeftStyl) {
259
+ this.dc.style.left = vbLeftStyl;
260
+ }
261
+ // top position
262
+ //const dTop = asH;
263
+ const dTopStr = asH + 'px';
264
+ if (this.dc.style.top != dTopStr) {
265
+ this.dc.style.top = dTopStr;
266
+ }
267
+ // width
268
+ let vbWidthStyle = vbWidth + 'px';
269
+ if (this.dc.style.width != vbWidthStyle) {
270
+ this.dc.style.width = vbWidthStyle;
271
+ }
272
+ if (this.dc.width != vbWidth) {
273
+ this.dc.width = vbWidth;
274
+ }
275
+ // height
276
+ if (this.dc.height != AudioClipUIContainer.DIVIDER_PIXEL_SIZE) {
277
+ this.dc.height = AudioClipUIContainer.DIVIDER_PIXEL_SIZE;
278
+ }
279
+ let divPixelSizeStyle = AudioClipUIContainer.DIVIDER_PIXEL_SIZE.toString() + 'px';
280
+ if (this.dc.style.height != divPixelSizeStyle) {
281
+ this.dc.style.height = divPixelSizeStyle;
282
+ }
283
+ this.drawDivider();
284
+ // Virtual dimension, only width is used
285
+ let virtualDim = new Dimension(ceBcrIntW, 0);
286
+ // Visible bounds of container
287
+ let br = new Rectangle(new Position(vbLeft, 0), new Dimension(vbWidth, ceBcrIntH));
288
+ // Set container bounds
289
+ this.layoutBounds(br, virtualDim, false);
290
+ // Visible bounds of audiosignal
291
+ let asR = new Rectangle(new Position(vbLeft, 0), new Dimension(vbWidth, asH));
292
+ // Set audiosignal bounds
293
+ this.as.layoutBounds(asR, virtualDim, redraw, clear);
294
+ // Visible bounds of sonagram
295
+ let soR = new Rectangle(new Position(vbLeft, soTop), new Dimension(vbWidth, soH));
296
+ // Set sonagram bounds
297
+ this.so.layoutBounds(soR, virtualDim, redraw, clear);
298
+ }
299
+ layoutScaled() {
300
+ this._layout(false, false);
301
+ }
302
+ layout(clear = true) {
303
+ if (this.ce && this.dc) {
304
+ const clientW = this.ce.clientWidth;
305
+ if (this._audioDataHolder) {
306
+ if (this._fixFitToPanel) {
307
+ // Set the virtual canvas width to the visible width
308
+ if (this.ce.style.width != '100%') {
309
+ //console.log("set width to 100%");
310
+ this.ce.style.width = '100%';
311
+ }
312
+ }
313
+ else {
314
+ if (this._xZoom) {
315
+ // Set the virtual canvas width according to the value of the user selected xZoom value
316
+ const newClW = Math.round(this._xZoom * this._audioDataHolder?.duration);
317
+ this.ce.style.width = newClW + 'px';
318
+ }
319
+ else {
320
+ // Set the virtual canvas width to the visible width only
321
+ this.ce.style.width = clientW + 'px';
322
+ }
323
+ }
324
+ }
325
+ this._layout(clear, true);
326
+ }
327
+ }
328
+ set audioData(audioDataHolder) {
329
+ this._audioClip = null;
330
+ this._audioDataHolder = audioDataHolder;
331
+ this.as.setData(audioDataHolder);
332
+ this.so.setData(audioDataHolder);
333
+ this.layout();
334
+ }
335
+ get audioData() {
336
+ return this._audioDataHolder;
337
+ }
338
+ set audioClip(audioClip) {
339
+ this._audioClip = audioClip;
340
+ let audioData = null;
341
+ let sel = null;
342
+ if (audioClip) {
343
+ audioData = audioClip.audioDataHolder;
344
+ if (this._audioClip) {
345
+ this._audioClip.addSelectionObserver((clip) => {
346
+ this.selection = clip.selection;
347
+ });
348
+ }
349
+ sel = audioClip.selection;
350
+ }
351
+ this._audioDataHolder = audioData;
352
+ this.as.setData(this._audioDataHolder);
353
+ this.so.setData(this._audioDataHolder);
354
+ this.selecting = null;
355
+ this.selection = sel;
356
+ this.layout();
357
+ }
358
+ get playFramePosition() {
359
+ return this._playFramePosition;
360
+ }
361
+ set playFramePosition(playFramePosition) {
362
+ this._playFramePosition = playFramePosition;
363
+ this.as.playFramePosition = playFramePosition;
364
+ this.so.playFramePosition = playFramePosition;
365
+ }
366
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: AudioClipUIContainer, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
367
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: AudioClipUIContainer, selector: "app-audio", inputs: { audioData: "audioData", audioClip: "audioClip" }, outputs: { selectionEventEmitter: "selectionEventEmitter" }, host: { listeners: { "window:resize": "onResize($event)", "document:mouseup": "onMouseup($event)", "document:mousemove": "onMousemove($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["divider"], descendants: true, static: true }, { propertyName: "ceRef", first: true, predicate: ["virtualCanvas"], descendants: true, static: true }, { propertyName: "as", first: true, predicate: AudioSignal, descendants: true, static: true }, { propertyName: "so", first: true, predicate: Sonagram, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
368
+ <div #virtualCanvas>
369
+ <canvas #divider (mousedown)="mousedown($event)" (mouseover)="mouseover($event)"
370
+ (mouseleave)="mouseleave($event)" height="10"></canvas>
371
+ <audio-signal [pointerPosition]="pointer" [selecting]="selecting" [selection]="selection" (pointerPositionEventEmitter)="pointerPositionChanged($event)" (selectingEventEmitter)="selectingChanged($event)" (selectedEventEmitter)="selectionChanged($event)"></audio-signal>
372
+ <audio-sonagram [pointerPosition]="pointer" [selecting]="selecting" [selection]="selection" (pointerPositionEventEmitter)="pointerPositionChanged($event)" (selectingEventEmitter)="selectingChanged($event)" (selectedEventEmitter)="selectionChanged($event)"></audio-sonagram>
373
+ </div>
374
+ `, isInline: true, styles: ["div{margin:0;padding:0;top:0;left:0;width:100%;height:100%;position:relative;box-sizing:border-box;transform:none;overflow:hidden}\n", "canvas{top:0;left:0;width:0;height:0;cursor:ns-resize;position:absolute;z-index:1;transform:none}\n", "audio-signal{top:0;left:0;position:absolute;z-index:1;transform:none}\n", "audio-sonagram{top:0;left:0;position:absolute;z-index:1;transform:none}\n"], dependencies: [{ kind: "component", type: i1.AudioSignal, selector: "audio-signal" }, { kind: "component", type: i2.Sonagram, selector: "audio-sonagram" }] }); }
375
+ }
376
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: AudioClipUIContainer, decorators: [{
377
+ type: Component,
378
+ args: [{ selector: 'app-audio', template: `
379
+ <div #virtualCanvas>
380
+ <canvas #divider (mousedown)="mousedown($event)" (mouseover)="mouseover($event)"
381
+ (mouseleave)="mouseleave($event)" height="10"></canvas>
382
+ <audio-signal [pointerPosition]="pointer" [selecting]="selecting" [selection]="selection" (pointerPositionEventEmitter)="pointerPositionChanged($event)" (selectingEventEmitter)="selectingChanged($event)" (selectedEventEmitter)="selectionChanged($event)"></audio-signal>
383
+ <audio-sonagram [pointerPosition]="pointer" [selecting]="selecting" [selection]="selection" (pointerPositionEventEmitter)="pointerPositionChanged($event)" (selectingEventEmitter)="selectingChanged($event)" (selectedEventEmitter)="selectionChanged($event)"></audio-sonagram>
384
+ </div>
385
+ `, styles: ["div{margin:0;padding:0;top:0;left:0;width:100%;height:100%;position:relative;box-sizing:border-box;transform:none;overflow:hidden}\n", "canvas{top:0;left:0;width:0;height:0;cursor:ns-resize;position:absolute;z-index:1;transform:none}\n", "audio-signal{top:0;left:0;position:absolute;z-index:1;transform:none}\n", "audio-sonagram{top:0;left:0;position:absolute;z-index:1;transform:none}\n"] }]
386
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { canvasRef: [{
387
+ type: ViewChild,
388
+ args: ['divider', { static: true }]
389
+ }], ceRef: [{
390
+ type: ViewChild,
391
+ args: ['virtualCanvas', { static: true }]
392
+ }], as: [{
393
+ type: ViewChild,
394
+ args: [AudioSignal, { static: true }]
395
+ }], so: [{
396
+ type: ViewChild,
397
+ args: [Sonagram, { static: true }]
398
+ }], selectionEventEmitter: [{
399
+ type: Output
400
+ }], onResize: [{
401
+ type: HostListener,
402
+ args: ['window:resize', ['$event']]
403
+ }], onMouseup: [{
404
+ type: HostListener,
405
+ args: ['document:mouseup', ['$event']]
406
+ }], onMousemove: [{
407
+ type: HostListener,
408
+ args: ['document:mousemove', ['$event']]
409
+ }], audioData: [{
410
+ type: Input
411
+ }], audioClip: [{
412
+ type: Input
413
+ }] } });
414
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3VpL2NvbnRhaW5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ3NCLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLFlBQVksRUFDN0UsTUFBTSxlQUFlLENBQUE7QUFDdEIsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGVBQWUsQ0FBQTtBQUN6QyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sWUFBWSxDQUFBO0FBQ25DLE9BQU8sRUFBUyxLQUFLLEVBQUMsTUFBTSxVQUFVLENBQUE7QUFFdEMsT0FBTyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFDLFFBQVEsRUFBQyxTQUFTLEVBQUUsU0FBUyxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFckUsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sMkJBQTJCLENBQUM7Ozs7QUFHekU7Ozs7OztHQU1HO0FBRUgsaUNBQWlDO0FBQ2pDLGdDQUFnQztBQUNoQywrQkFBK0I7QUFDL0IsSUFBSTtBQUNKLEVBQUU7QUFDRix5Q0FBeUM7QUFDekMsOEJBQThCO0FBQzlCLDRDQUE0QztBQUM1Qyx3REFBd0Q7QUFDeEQseURBQXlEO0FBQ3pELG9FQUFvRTtBQUNwRSxJQUFJO0FBQ0osRUFBRTtBQUNGLDZDQUE2QztBQUM3QywwRUFBMEU7QUFDMUUsSUFBSTtBQUNKLEVBQUU7QUFDRiwwQ0FBMEM7QUFDMUMsNERBQTREO0FBQzVELEtBQUs7QUFFTCw0QkFBNEI7QUFDNUIsZ0NBQWdDO0FBQ2hDLG1EQUFtRDtBQUNuRCx1RUFBdUU7QUFDdkUsbUNBQW1DO0FBQ25DLDBCQUEwQjtBQUMxQixJQUFJO0FBRUo7Ozs7Ozs7R0FPRztBQStDSCxNQUFNLE9BQU8sb0JBQXFC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QVEsQ0FBQztnQkFZNUMsV0FBVztzQkFEVixZQUFZO3VCQUFDLG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQXNOMUMsU0FBUztzQkFEWixLQUFLO2dCQWVGLFNBQVM7c0JBRFosS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgRWxlbWVudFJlZiwgQWZ0ZXJWaWV3SW5pdCwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIEV2ZW50RW1pdHRlclxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXHJcbmltcG9ydCB7QXVkaW9TaWduYWx9IGZyb20gJy4vYXVkaW9zaWduYWwnXHJcbmltcG9ydCB7U29uYWdyYW19IGZyb20gJy4vc29uYWdyYW0nXHJcbmltcG9ydCB7TWFya2VyLCBQb2ludH0gZnJvbSAnLi9jb21tb24nXHJcblxyXG5pbXBvcnQge0NvbXBvbmVudCwgVmlld0NoaWxkfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtQb3NpdGlvbixEaW1lbnNpb24sIFJlY3RhbmdsZX0gZnJvbSBcIi4uLy4uL21hdGgvMmQvZ2VvbWV0cnlcIjtcclxuaW1wb3J0IHtBdWRpb0NsaXAsU2VsZWN0aW9ufSBmcm9tIFwiLi4vcGVyc2lzdG9yXCI7XHJcbmltcG9ydCB7QmFzaWNBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50fSBmcm9tIFwiLi9hdWRpb19jYW52YXNfbGF5ZXJfY29tcFwiO1xyXG5pbXBvcnQge0F1ZGlvRGF0YUhvbGRlcn0gZnJvbSBcIi4uL2F1ZGlvX2RhdGFfaG9sZGVyXCI7XHJcblxyXG4vKlxyXG4gIFJlc2l6ZU9ic2VydmVyIG5vdCB5ZXQgYXZhaWxhYmxlIGluIG9mZmljaWFsIFR5cGVzY3JpcHQgZGVjbGFyYXRpb25cclxuICBDcnJlYXRlZCBkZWNsYXJhdGlvbiBmcm9tIElETCB1bnRpbCBpdHMgYXZhaWxhYmxlLlxyXG4gIFNlZSBzcGVjczpcclxuICBodHRwczovL3d3dy53My5vcmcvVFIvcmVzaXplLW9ic2VydmVyXHJcblxyXG4gKi9cclxuXHJcbi8vIGludGVyZmFjZSBSZXNpemVPYnNlcnZlclNpemUge1xyXG4vLyAgIHJlYWRvbmx5IGlubGluZVNpemU6bnVtYmVyO1xyXG4vLyAgIHJlYWRvbmx5IGJsb2NrU2l6ZTpudW1iZXI7XHJcbi8vIH1cclxuLy9cclxuLy8gZGVjbGFyZSBpbnRlcmZhY2UgUmVzaXplT2JzZXJ2ZXJFbnRyeXtcclxuLy8gICByZWFkb25seSB0YXJnZXQ6IEVsZW1lbnQ7XHJcbi8vICAgcmVhZG9ubHkgY29udGVudFJlY3Q6IERPTVJlY3RSZWFkT25seSA7XHJcbi8vICAgcmVhZG9ubHkgYm9yZGVyQm94U2l6ZTogQXJyYXk8UmVzaXplT2JzZXJ2ZXJTaXplPiA7XHJcbi8vICAgcmVhZG9ubHkgY29udGVudEJveFNpemU6IEFycmF5PFJlc2l6ZU9ic2VydmVyU2l6ZT4gO1xyXG4vLyAgIHJlYWRvbmx5IGRldmljZVBpeGVsQ29udGVudEJveFNpemU6IEFycmF5PFJlc2l6ZU9ic2VydmVyU2l6ZT4gO1xyXG4vLyB9XHJcbi8vXHJcbi8vIGRlY2xhcmUgaW50ZXJmYWNlIFJlc2l6ZU9ic2VydmVyQ2FsbGJhY2sge1xyXG4vLyAgIChlbnRyaWVzOiBBcnJheTxSZXNpemVPYnNlcnZlckVudHJ5Piwgb2JzZXJ2ZXI6IFJlc2l6ZU9ic2VydmVyKTp2b2lkO1xyXG4vLyB9XHJcbi8vXHJcbi8vIGRlY2xhcmUgZW51bSBSZXNpemVPYnNlcnZlckJveE9wdGlvbnMge1xyXG4vLyAgIFwiYm9yZGVyLWJveFwiLCBcImNvbnRlbnQtYm94XCIsIFwiZGV2aWNlLXBpeGVsLWNvbnRlbnQtYm94XCJcclxuLy8gfTtcclxuXHJcbi8vIC8vIERlY2xhcmUgUmVzaXplb2JzZXJ2ZXJcclxuLy8gZGVjbGFyZSBjbGFzcyBSZXNpemVPYnNlcnZlcntcclxuLy8gICBjb25zdHJ1Y3RvcihjYWxsYmFjazogUmVzaXplT2JzZXJ2ZXJDYWxsYmFjayk7XHJcbi8vICAgb2JzZXJ2ZTogKGVsOkVsZW1lbnQsb3B0czogUmVzaXplT2JzZXJ2ZXJCb3hPcHRpb25zIHwgbnVsbCk9PnZvaWQ7XHJcbi8vICAgdW5vYnNlcnZlOiAoZWw6RWxlbWVudCk9PnZvaWQ7XHJcbi8vICAgZGlzY29ubmVjdDogKCk9PnZvaWQ7XHJcbi8vIH1cclxuXHJcbi8qXHJcbiAqIENvbnRhaW5lciBjb21wb25lbnQgZm9yIGF1ZGlvIGRpc3BsYXkuXHJcbiAqIFRoZSBkaXNwbGF5IGVsZW1lbnRzIGFyZSBjaGlsZHJlbiBvZiBhIHZpcnR1YWwgY2FudmFzLiBUaGUgdmlydHVhbCBjYW52YXMgbWFrZXMgaXQgcG9zc2libGUgdG8gaGF2ZSBoaWdoIHpvb20gZmFjdG9ycyB3aXRoIHZlcnkgd2lkZSB2aXJ0dWFsIGF1ZGlvIGRpc3BsYXlzLlxyXG4gKiBPbmx5IHRoZSB2aXNpYmxlIHBhcnQgb2YgdGhlIHZpcnR1YWwgY2FudmFzIGlzIGltcGxlbWVudGVkIGFzIGEgYnJvd3NlciBjYW52YXMgYW5kIHRoZXJlZm9yZSBjb25zdW1pbmcgbWVtb3J5LlxyXG4gKiBUaGUgdmlzaWJsZSBwYXJ0IGhhcyB0aGUgc2FtZSB3aWR0aCBhcyB0aGUgdmlld3BvcnQgb2YgdGhlIHNjcm9sbCBwYW5lIHBhcmVudC5cclxuICogVGhlIHZpcnR1YWwgY2FudmFzIGl0c2VsZiBpcyBpbXBsZW1lbnRlZCBhcyBhbiBIVE1MIGRpdiBlbGVtZW50LlxyXG4gKiBUaGUgbGF5b3V0IG9mIHRoZSBjb21wb25lbnQgaXMgdXBkYXRlZCBvbiByZXNpemUgb2YgdGhlIHBhcmVudCBvciBjaGFuZ2VzIG9mIHRoZSB6b29tIGZhY3Rvci5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG5cclxuICBzZWxlY3RvcjogJ2FwcC1hdWRpbycsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxkaXYgI3ZpcnR1YWxDYW52YXM+XHJcbiAgICA8Y2FudmFzICNkaXZpZGVyIChtb3VzZWRvd24pPVwibW91c2Vkb3duKCRldmVudClcIiAobW91c2VvdmVyKT1cIm1vdXNlb3ZlcigkZXZlbnQpXCJcclxuICAgICAgICAgICAgKG1vdXNlbGVhdmUpPVwibW91c2VsZWF2ZSgkZXZlbnQpXCIgaGVpZ2h0PVwiMTBcIj48L2NhbnZhcz5cclxuICAgIDxhdWRpby1zaWduYWwgW3BvaW50ZXJQb3NpdGlvbl09XCJwb2ludGVyXCIgW3NlbGVjdGluZ109XCJzZWxlY3RpbmdcIiBbc2VsZWN0aW9uXT1cInNlbGVjdGlvblwiIChwb2ludGVyUG9zaXRpb25FdmVudEVtaXR0ZXIpPVwicG9pbnRlclBvc2l0aW9uQ2hhbmdlZCgkZXZlbnQpXCIgKHNlbGVjdGluZ0V2ZW50RW1pdHRlcik9XCJzZWxlY3RpbmdDaGFuZ2VkKCRldmVudClcIiAoc2VsZWN0ZWRFdmVudEVtaXR0ZXIpPVwic2VsZWN0aW9uQ2hhbmdlZCgkZXZlbnQpXCI+PC9hdWRpby1zaWduYWw+XHJcbiAgICA8YXVkaW8tc29uYWdyYW0gW3BvaW50ZXJQb3NpdGlvbl09XCJwb2ludGVyXCIgW3NlbGVjdGluZ109XCJzZWxlY3RpbmdcIiBbc2VsZWN0aW9uXT1cInNlbGVjdGlvblwiIChwb2ludGVyUG9zaXRpb25FdmVudEVtaXR0ZXIpPVwicG9pbnRlclBvc2l0aW9uQ2hhbmdlZCgkZXZlbnQpXCIgKHNlbGVjdGluZ0V2ZW50RW1pdHRlcik9XCJzZWxlY3RpbmdDaGFuZ2VkKCRldmVudClcIiAoc2VsZWN0ZWRFdmVudEVtaXR0ZXIpPVwic2VsZWN0aW9uQ2hhbmdlZCgkZXZlbnQpXCI+PC9hdWRpby1zb25hZ3JhbT5cclxuICAgIDwvZGl2PlxyXG4gIGAsXHJcbiAgc3R5bGVzOiBbYGRpdiB7XHJcbiAgICBtYXJnaW46IDA7XHJcbiAgICBwYWRkaW5nOiAwO1xyXG4gICAgdG9wOiAwO1xyXG4gICAgbGVmdDogMDtcclxuICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgaGVpZ2h0OiAxMDAlO1xyXG4gICAgcG9zaXRpb246IHJlbGF0aXZlOyAvKiBUT0RPIGNvbnRhaW5lciBkaXYgcG9zaXRpb24gbXVzdCBub3QgYmUgJ3N0YXRpYycgKGRlZmF1bHQpIHRvIGFjdCBhcyByZWZlcmVuY2UgZm9yIHRoZSBjYW52YXNlcyAqL1xyXG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcclxuICAgIHRyYW5zZm9ybTogbm9uZTtcclxuICAgIG92ZXJmbG93OiBoaWRkZW47XHJcbiAgfWAsIGBjYW52YXN7XHJcbiAgICB0b3A6IDA7XHJcbiAgICBsZWZ0OiAwO1xyXG4gICAgd2lkdGg6IDA7XHJcbiAgICBoZWlnaHQ6IDA7XHJcbiAgICBjdXJzb3I6IG5zLXJlc2l6ZTtcclxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgIHotaW5kZXg6IDE7XHJcbiAgICB0cmFuc2Zvcm06IG5vbmU7XHJcbiAgfWAsIGBhdWRpby1zaWduYWwge1xyXG4gICAgdG9wOiAwO1xyXG4gICAgbGVmdDogMDtcclxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgIHotaW5kZXg6IDE7XHJcbiAgICB0cmFuc2Zvcm06IG5vbmU7XHJcbiAgfWAsIGBhdWRpby1zb25hZ3JhbSB7XHJcbiAgICB0b3A6IDA7XHJcbiAgICBsZWZ0OiAwO1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgei1pbmRleDogMTtcclxuICAgIHRyYW5zZm9ybTogbm9uZTtcclxuICB9YF1cclxuXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBdWRpb0NsaXBVSUNvbnRhaW5lciBleHRlbmRzIEJhc2ljQXVkaW9DYW52YXNMYXllckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCxBZnRlclZpZXdJbml0e1xyXG5cclxuICBwcml2YXRlIHN0YXRpYyBESVZJREVSX1BJWEVMX1NJWkUgPSAxMDtcclxuXHJcbiAgcGFyZW50RTogSFRNTEVsZW1lbnQ7XHJcblxyXG4gIC8vIERpdmlkZXIgY2FudmFzXHJcbiAgQFZpZXdDaGlsZCgnZGl2aWRlcicsIHsgc3RhdGljOiB0cnVlIH0pIGNhbnZhc1JlZiE6IEVsZW1lbnRSZWY7XHJcbiAgZGMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuXHJcbiAgLy8gVmlydHVhbCBjb250YWluZXJcclxuICBAVmlld0NoaWxkKCd2aXJ0dWFsQ2FudmFzJywgeyBzdGF0aWM6IHRydWUgfSkgY2VSZWYhOiBFbGVtZW50UmVmO1xyXG4gIGNlITogSFRNTERpdkVsZW1lbnQ7XHJcblxyXG4gIEBWaWV3Q2hpbGQoQXVkaW9TaWduYWwsIHsgc3RhdGljOiB0cnVlIH0pIGFzITogQXVkaW9TaWduYWw7XHJcbiAgQFZpZXdDaGlsZChTb25hZ3JhbSwgeyBzdGF0aWM6IHRydWUgfSkgc28hOiBTb25hZ3JhbTtcclxuXHJcbiAgcHJpdmF0ZSBfYXVkaW9DbGlwOkF1ZGlvQ2xpcCB8IG51bGw9bnVsbDtcclxuICBwb2ludGVyOiBNYXJrZXJ8bnVsbD1udWxsO1xyXG4gIHNlbGVjdGluZzogU2VsZWN0aW9ufG51bGw9bnVsbDtcclxuICBzZWxlY3Rpb246IFNlbGVjdGlvbnxudWxsPW51bGw7XHJcbiAgQE91dHB1dCgpIHNlbGVjdGlvbkV2ZW50RW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXI8U2VsZWN0aW9uPigpO1xyXG4gIHByaXZhdGUgX3BsYXlGcmFtZVBvc2l0aW9uOiBudW1iZXJ8bnVsbD1udWxsO1xyXG4gIHByaXZhdGUgZHJhZ1N0YXJ0TW91c2VZOiBudW1iZXIgfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIGRyYWdTdGFydFk6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgZGl2aWRlclBvc2l0aW9uID0gMC41O1xyXG5cclxuICB1c2VyQWN0aW9uPWZhbHNlO1xyXG5cclxuICBwcml2YXRlIF94Wm9vbTogbnVtYmVyIHwgbnVsbCA9IG51bGw7IC8vIHBpeGVscyBwZXIgc2Vjb25kXHJcblxyXG4gIGdldCB4Wm9vbSgpOiBudW1iZXIgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl94Wm9vbTtcclxuICB9XHJcblxyXG4gIHNldCB4Wm9vbSh2YWx1ZTogbnVtYmVyIHwgbnVsbCkge1xyXG4gICAgdGhpcy51c2VyQWN0aW9uPXRydWU7XHJcbiAgICB0aGlzLl94Wm9vbSA9IHZhbHVlO1xyXG4gICAgdGhpcy5sYXlvdXQoKVxyXG4gICAgdGhpcy51c2VyQWN0aW9uPWZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLy8gaWYgdHJ1ZSB0aGUgY29tcGxldGUgYXVkaW8gZmlsZSBpcyBzaG93biwgdGhlIGRpc3BsYXkgZml0cyB0byB0aGUgdmlzaWJsZSBwYW5lbCwgdGhlIHgtem9vbSBmYWN0b3IgaXMgdmFyaWFibGUsIHRoaXMgaXMgdGhlIGRlZmF1bHRcclxuICBwcml2YXRlIF9maXhGaXRUb1BhbmVsID0gdHJ1ZTtcclxuXHJcbiAgc2V0IGZpeEZpdFRvUGFuZWwodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuX2ZpeEZpdFRvUGFuZWwgPSB2YWx1ZTtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAvLyB3ZSBkb24ndCBuZWVkICBjbGlwIGJvdW5kc1xyXG4gICAgICB0aGlzLmJvdW5kcz1udWxsO1xyXG4gICAgICB0aGlzLl94Wm9vbSA9IG51bGw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBob2xkIGN1cnJlbnQgem9vbSB2YWx1ZVxyXG4gICAgICAvL3RoaXMuX3hab29tPXRoaXMuY2Uub2Zmc2V0V2lkdGgvdGhpcy5fYXVkaW9EYXRhLmR1cmF0aW9uO1xyXG4gICAgfVxyXG4gICAgdGhpcy5sYXlvdXQoKVxyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWY6IEVsZW1lbnRSZWYpIHtcclxuICAgIHN1cGVyKClcclxuICAgIHRoaXMucGFyZW50RSA9IHRoaXMucmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuY2UgPSB0aGlzLmNlUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLmRjID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMubGF5b3V0KCk7XHJcbiAgICBjb25zdCBoZWlnaHRMaXN0ZW5lciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtcnM6IEFycmF5PE11dGF0aW9uUmVjb3JkPiwgbW86IE11dGF0aW9uT2JzZXJ2ZXIpID0+IHtcclxuXHJcbiAgICAgIGxldCBsYXlvdXQ9ZmFsc2U7XHJcbiAgICAgIG1ycy5mb3JFYWNoKChtcjogTXV0YXRpb25SZWNvcmQpID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMudXNlckFjdGlvbiAmJiAnYXR0cmlidXRlcycgPT09IG1yLnR5cGUgJiYgKCdjbGFzcycgPT09IG1yLmF0dHJpYnV0ZU5hbWUgfHwgJ3N0eWxlJyA9PT0gbXIuYXR0cmlidXRlTmFtZSkpIHtcclxuICAgICAgICAgIGxheW91dD10cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIGlmKGxheW91dCl7XHJcbiAgICAgICAgLy8gcmUtbGF5b3V0IHJlcXVpcmVkXHJcbiAgICAgICAgdGhpcy5sYXlvdXQoZmFsc2UpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBoZWlnaHRMaXN0ZW5lci5vYnNlcnZlKHRoaXMuY2UsIHthdHRyaWJ1dGVzOiB0cnVlLCBjaGlsZExpc3Q6IHRydWUsIGNoYXJhY3RlckRhdGE6IHRydWV9KTtcclxuICAgIGhlaWdodExpc3RlbmVyLm9ic2VydmUodGhpcy5kYywge2F0dHJpYnV0ZXM6IHRydWUsIGNoaWxkTGlzdDogdHJ1ZSwgY2hhcmFjdGVyRGF0YTogdHJ1ZX0pO1xyXG5cclxuICAgIGNvbnN0IHJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKChlbnRyaWVzLG9icykgPT4ge1xyXG4gICAgICAvL2NvbnNvbGUubG9nKFwiUmVzaXplIG9ic2VydmVkOlwiKTtcclxuICAgICAgZW50cmllcy5mb3JFYWNoKChlKT0+e1xyXG4gICAgICAgIC8vY29uc29sZS5sb2coZS5jb250ZW50UmVjdC53aWR0aCtcInhcIitlLmNvbnRlbnRSZWN0LmhlaWdodCk7XHJcbiAgICAgICAgdGhpcy5sYXlvdXQoKTtcclxuICAgICAgfSlcclxuICAgIH0pO1xyXG5cclxuICAgIHJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy5jZSk7XHJcblxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXHJcbiAgb25SZXNpemUoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XHJcbiAgICB0aGlzLmxheW91dCgpO1xyXG4gIH1cclxuXHJcbiAgbW91c2VvdmVyKG1lOiBNb3VzZUV2ZW50KSB7XHJcbiAgICB0aGlzLmRpdmlkZXJDdXJzb3JQb3NpdGlvbihtZSwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBtb3VzZWxlYXZlKG1lOiBNb3VzZUV2ZW50KSB7XHJcbiAgICB0aGlzLmRpdmlkZXJDdXJzb3JQb3NpdGlvbihtZSwgZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgbW91c2Vkb3duKG1lOiBNb3VzZUV2ZW50KSB7XHJcbiAgICB0aGlzLmRyYWdTdGFydE1vdXNlWSA9IG1lLmNsaWVudFk7XHJcbiAgICB0aGlzLmRyYWdTdGFydFkgPSB0aGlzLmRjLm9mZnNldFRvcDtcclxuICAgIHRoaXMuZHJhZ1N0YXJ0TW91c2VZID0gbWUuY2xpZW50WTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNldXAnLCBbJyRldmVudCddKVxyXG4gIG9uTW91c2V1cChtZTogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKHRoaXMuZHJhZ1N0YXJ0WSAhPSBudWxsKSB7XHJcbiAgICAgIHRoaXMudXNlckFjdGlvbj10cnVlO1xyXG4gICAgICB0aGlzLmRpdmlkZXJEcmFnKG1lKTtcclxuICAgICAgdGhpcy5sYXlvdXQoZmFsc2UpO1xyXG4gICAgICB0aGlzLmRyYWdTdGFydFkgPSBudWxsO1xyXG4gICAgICB0aGlzLnVzZXJBY3Rpb249ZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZW1vdmUnLCBbJyRldmVudCddKVxyXG4gIG9uTW91c2Vtb3ZlKG1lOiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5kcmFnU3RhcnRZICE9IG51bGwpIHtcclxuICAgICAgdGhpcy51c2VyQWN0aW9uPXRydWU7XHJcbiAgICAgIHRoaXMuZGl2aWRlckRyYWcobWUpO1xyXG4gICAgICB0aGlzLmxheW91dFNjYWxlZCgpO1xyXG4gICAgICB0aGlzLnVzZXJBY3Rpb249dHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHBvaW50ZXJQb3NpdGlvbkNoYW5nZWQocHA6TWFya2VyKXtcclxuICAgIHRoaXMucG9pbnRlcj1wcFxyXG4gIH1cclxuXHJcbiAgc2VsZWN0aW5nQ2hhbmdlZChzOlNlbGVjdGlvbnwgbnVsbCl7XHJcbiAgICB0aGlzLnNlbGVjdGluZz1zXHJcbiAgfVxyXG5cclxuICBzZWxlY3Rpb25DaGFuZ2VkKHM6U2VsZWN0aW9uKXtcclxuICAgIHRoaXMuc2VsZWN0aW9uPXNcclxuICAgIGlmKHRoaXMuX2F1ZGlvQ2xpcCl7XHJcbiAgICAgIHRoaXMuX2F1ZGlvQ2xpcC5zZWxlY3Rpb249c1xyXG4gICAgfVxyXG4gICAgdGhpcy5zZWxlY3Rpb25FdmVudEVtaXR0ZXIuZW1pdCh0aGlzLnNlbGVjdGlvbilcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2FudmFzTW91c2VQb3MoYzogSFRNTENhbnZhc0VsZW1lbnQsIGU6IE1vdXNlRXZlbnQpOiBQb2ludCB7XHJcbiAgICBjb25zdCBjciA9IGMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBjb25zdCB4ID0gZS54IC0gY3IubGVmdDtcclxuICAgIGNvbnN0IHkgPSBlLnkgLSBjci50b3A7XHJcbiAgICByZXR1cm4gbmV3IFBvaW50KHgseSk7XHJcbiAgfVxyXG5cclxuICBkaXZpZGVyQ3Vyc29yUG9zaXRpb24oZTogTW91c2VFdmVudCwgc2hvdzogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuZGMpIHtcclxuICAgICAgdGhpcy5jYW52YXNNb3VzZVBvcyh0aGlzLmRjLCBlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGRpdmlkZXJEcmFnKGU6IE1vdXNlRXZlbnQpIHtcclxuICAgIGlmICh0aGlzLmRjICYmIHRoaXMuZHJhZ1N0YXJ0TW91c2VZICYmIHRoaXMuZHJhZ1N0YXJ0WSkge1xyXG5cclxuICAgICAgY29uc3QgZHJhZ09mZnNldCA9IGUuY2xpZW50WSAtIHRoaXMuZHJhZ1N0YXJ0TW91c2VZO1xyXG4gICAgICBjb25zdCBjZUhlaWdodCA9IHRoaXMuY2Uub2Zmc2V0SGVpZ2h0O1xyXG5cclxuICAgICAgbGV0IG5ld1RvcCA9ICh0aGlzLmRyYWdTdGFydFkgKyBkcmFnT2Zmc2V0KTtcclxuICAgICAgaWYgKG5ld1RvcCA8IDApIHtcclxuICAgICAgICBuZXdUb3AgPSAwO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChuZXdUb3AgPiBjZUhlaWdodCAtIEF1ZGlvQ2xpcFVJQ29udGFpbmVyLkRJVklERVJfUElYRUxfU0laRSkge1xyXG4gICAgICAgIG5ld1RvcCA9IGNlSGVpZ2h0IC0gQXVkaW9DbGlwVUlDb250YWluZXIuRElWSURFUl9QSVhFTF9TSVpFO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZGMuc3R5bGUudG9wID0gbmV3VG9wLnRvU3RyaW5nKCkgKyAncHgnO1xyXG4gICAgICB0aGlzLmRpdmlkZXJQb3NpdGlvbiA9ICh0aGlzLmRjLm9mZnNldFRvcCArIEF1ZGlvQ2xpcFVJQ29udGFpbmVyLkRJVklERVJfUElYRUxfU0laRSAvIDIpIC8gY2VIZWlnaHQ7XHJcbiAgICAgIGlmICh0aGlzLmRpdmlkZXJQb3NpdGlvbiA+IDEuMCkge1xyXG4gICAgICAgIHRoaXMuZGl2aWRlclBvc2l0aW9uID0gMS4wO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmRpdmlkZXJQb3NpdGlvbiA8IDAuMCkge1xyXG4gICAgICAgIHRoaXMuZGl2aWRlclBvc2l0aW9uID0gMC4wO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZHJhd0RpdmlkZXIoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBkcmF3RGl2aWRlcigpIHtcclxuICAgIGNvbnN0IHcgPSB0aGlzLmRjLndpZHRoO1xyXG4gICAgY29uc3QgaCA9IHRoaXMuZGMuaGVpZ2h0O1xyXG4gICAgY29uc3QgZyA9IHRoaXMuZGMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgIGlmIChnICYmIHc+MTAgJiYgaD49MSkge1xyXG4gICAgICBnLmZpbGxTdHlsZSA9ICd3aGl0ZSc7XHJcbiAgICAgIGcuZmlsbFJlY3QoMCwgMCwgdywgaCk7XHJcbiAgICAgIGcuZmlsbFN0eWxlID0gJ2JsYWNrJztcclxuICAgICAgZy5maWxsUmVjdCg1LCA1LCB3IC0gMTAsIDEpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY2xpcEJvdW5kcyhjbGlwQm91bmRzOiBSZWN0YW5nbGUpIHtcclxuICAgIHRoaXMuYm91bmRzID0gY2xpcEJvdW5kcztcclxuICAgIHRoaXMubGF5b3V0KCk7XHJcbiAgfVxyXG5cclxuICBjdXJyZW50WFpvb20oKTogbnVtYmVyIHwgbnVsbCB7XHJcbiAgICBsZXQgeHogPSB0aGlzLl94Wm9vbTtcclxuICAgIGlmICh4ej09bnVsbCAmJiB0aGlzLl9hdWRpb0RhdGFIb2xkZXIpIHtcclxuICAgICAgbGV0IG93ID0gdGhpcy5jZS5vZmZzZXRXaWR0aDtcclxuICAgICAgaWYgKG93IDwgMSkge1xyXG4gICAgICAgIC8vIGF0IGxlYXN0IG9uZSBwaXhlbCB3aWR0aCB0byBhdm9pZCB4LXpvb20gemVybyB2YWx1ZXNcclxuICAgICAgICBvdyA9IDE7XHJcbiAgICAgIH1cclxuICAgICAgeHogPSBvdyAvIHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5kdXJhdGlvbjtcclxuICAgIH1cclxuICAgIHJldHVybiB4ejtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2xheW91dChjbGVhcjogYm9vbGVhbiwgcmVkcmF3OiBib29sZWFuKSB7XHJcbiAgICBsZXQgY2VCY3IgPSB0aGlzLmNlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cclxuICAgIGNvbnN0IGNlQmNySW50VyA9IE1hdGguZmxvb3IoY2VCY3Iud2lkdGgpO1xyXG4gICAgY29uc3QgY2VCY3JJbnRIID0gTWF0aC5mbG9vcihjZUJjci5oZWlnaHQpO1xyXG5cclxuICAgIC8vIGhlaWdodCBhdmFpbGFibGUgZm9yIHBsdWdpbnMgKGF1ZGlvc2lnbmFsIGFuZCBzb25hZ3JhbSlcclxuICAgIGxldCBwc0ggPSBjZUJjckludEggLSBBdWRpb0NsaXBVSUNvbnRhaW5lci5ESVZJREVSX1BJWEVMX1NJWkU7XHJcbiAgICBpZiAocHNIIDwgMCkge1xyXG4gICAgICBwc0ggPSAwO1xyXG4gICAgfVxyXG4gICAgLy8gYXVkaW8gc2lnbmFsIGhlaWdodFxyXG4gICAgY29uc3QgYXNIID0gTWF0aC5yb3VuZChwc0ggKiB0aGlzLmRpdmlkZXJQb3NpdGlvbik7XHJcblxyXG4gICAgLy8gc29uYWdyYW0gaGVpZ2h0IChyZXN0OiBhdmFpbGFibGUgaGVpZ2h0IG1pbnVzIGRpdmlkZXIgaGVpZ2h0IG1pbnVzIGF1ZGlvc2lnbmFsIGhlaWdodClcclxuICAgIGxldCBzb0ggPSBjZUJjckludEggLSBBdWRpb0NsaXBVSUNvbnRhaW5lci5ESVZJREVSX1BJWEVMX1NJWkUgLSBhc0g7XHJcbiAgICBpZiAoc29IIDwgMCkge1xyXG4gICAgICBzb0ggPSAwO1xyXG4gICAgfVxyXG5cclxuICAvLyBzb25hZ3JhbSB0b3AgcG9zaXRpb25cclxuICAgIGNvbnN0IHNvVG9wID0gYXNIICsgQXVkaW9DbGlwVUlDb250YWluZXIuRElWSURFUl9QSVhFTF9TSVpFO1xyXG5cclxuICAgIC8vIFZpc2libGUgYm91bmRzXHJcbiAgICAvLyBsZWZ0IHBvc2l0aW9uXHJcbiAgICBsZXQgdmJMZWZ0ID0gMDtcclxuICAgIC8vIHdpZHRoXHJcbiAgICBsZXQgdmJXaWR0aCA9IGNlQmNySW50VztcclxuICAgIGlmICghdGhpcy5fZml4Rml0VG9QYW5lbCAmJiB0aGlzLmJvdW5kcykge1xyXG4gICAgICB2YkxlZnQgPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLnBvc2l0aW9uLmxlZnQpO1xyXG4gICAgICB2YldpZHRoID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIERpdmlkZXJcclxuICAgIC8vIGxlZnQgcG9zaXRpb25cclxuICAgIGxldCB2YkxlZnRTdHlsID0gdmJMZWZ0ICsgJ3B4JztcclxuICAgIGlmICh0aGlzLmRjLnN0eWxlLmxlZnQgIT0gdmJMZWZ0U3R5bCkge1xyXG4gICAgICB0aGlzLmRjLnN0eWxlLmxlZnQgPSB2YkxlZnRTdHlsO1xyXG4gICAgfVxyXG4gICAgLy8gdG9wIHBvc2l0aW9uXHJcbiAgICAvL2NvbnN0IGRUb3AgPSBhc0g7XHJcbiAgICBjb25zdCBkVG9wU3RyID0gYXNIICsgJ3B4JztcclxuICAgIGlmICh0aGlzLmRjLnN0eWxlLnRvcCAhPSBkVG9wU3RyKSB7XHJcbiAgICAgIHRoaXMuZGMuc3R5bGUudG9wID0gZFRvcFN0cjtcclxuICAgIH1cclxuICAgIC8vIHdpZHRoXHJcbiAgICBsZXQgdmJXaWR0aFN0eWxlID0gdmJXaWR0aCArICdweCc7XHJcbiAgICBpZiAodGhpcy5kYy5zdHlsZS53aWR0aCAhPSB2YldpZHRoU3R5bGUpIHtcclxuICAgICAgdGhpcy5kYy5zdHlsZS53aWR0aCA9IHZiV2lkdGhTdHlsZTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmRjLndpZHRoICE9IHZiV2lkdGgpIHtcclxuICAgICAgdGhpcy5kYy53aWR0aCA9IHZiV2lkdGg7XHJcbiAgICB9XHJcbiAgICAvLyBoZWlnaHRcclxuICAgIGlmKHRoaXMuZGMuaGVpZ2h0IT1BdWRpb0NsaXBVSUNvbnRhaW5lci5ESVZJREVSX1BJWEVMX1NJWkUpIHtcclxuICAgICAgdGhpcy5kYy5oZWlnaHQgPSBBdWRpb0NsaXBVSUNvbnRhaW5lci5ESVZJREVSX1BJWEVMX1NJWkU7XHJcblxyXG4gICAgfVxyXG4gICAgbGV0IGRpdlBpeGVsU2l6ZVN0eWxlPUF1ZGlvQ2xpcFVJQ29udGFpbmVyLkRJVklERVJfUElYRUxfU0laRS50b1N0cmluZygpICsgJ3B4JztcclxuICAgIGlmKHRoaXMuZGMuc3R5bGUuaGVpZ2h0IT1kaXZQaXhlbFNpemVTdHlsZSkge1xyXG4gICAgICB0aGlzLmRjLnN0eWxlLmhlaWdodCA9IGRpdlBpeGVsU2l6ZVN0eWxlO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZHJhd0RpdmlkZXIoKTtcclxuXHJcblxyXG4gICAgLy8gVmlydHVhbCBkaW1lbnNpb24sIG9ubHkgd2lkdGggaXMgdXNlZFxyXG4gICAgbGV0IHZpcnR1YWxEaW0gPSBuZXcgRGltZW5zaW9uKGNlQmNySW50VywgMClcclxuXHJcbiAgICAvLyBWaXNpYmxlIGJvdW5kcyBvZiBjb250YWluZXJcclxuICAgIGxldCBiciA9IG5ldyBSZWN0YW5nbGUobmV3IFBvc2l0aW9uKHZiTGVmdCwgMCksIG5ldyBEaW1lbnNpb24odmJXaWR0aCwgY2VCY3JJbnRIKSk7XHJcblxyXG4gICAgLy8gU2V0IGNvbnRhaW5lciBib3VuZHNcclxuICAgIHRoaXMubGF5b3V0Qm91bmRzKGJyLCB2aXJ0dWFsRGltLCBmYWxzZSk7XHJcblxyXG4gICAgLy8gVmlzaWJsZSBib3VuZHMgb2YgYXVkaW9zaWduYWxcclxuICAgIGxldCBhc1IgPSBuZXcgUmVjdGFuZ2xlKG5ldyBQb3NpdGlvbih2YkxlZnQsIDApLCBuZXcgRGltZW5zaW9uKHZiV2lkdGgsIGFzSCkpO1xyXG5cclxuICAgIC8vIFNldCBhdWRpb3NpZ25hbCBib3VuZHNcclxuICAgIHRoaXMuYXMubGF5b3V0Qm91bmRzKGFzUiwgdmlydHVhbERpbSwgcmVkcmF3LCBjbGVhcik7XHJcblxyXG4gICAgLy8gVmlzaWJsZSBib3VuZHMgb2Ygc29uYWdyYW1cclxuICAgIGxldCBzb1IgPSBuZXcgUmVjdGFuZ2xlKG5ldyBQb3NpdGlvbih2YkxlZnQsIHNvVG9wKSwgbmV3IERpbWVuc2lvbih2YldpZHRoLCBzb0gpKTtcclxuXHJcbiAgICAvLyBTZXQgc29uYWdyYW0gYm91bmRzXHJcbiAgICB0aGlzLnNvLmxheW91dEJvdW5kcyhzb1IsIHZpcnR1YWxEaW0sIHJlZHJhdywgY2xlYXIpO1xyXG4gIH1cclxuXHJcbiAgbGF5b3V0U2NhbGVkKCkge1xyXG4gICAgdGhpcy5fbGF5b3V0KGZhbHNlLCBmYWxzZSk7XHJcbiAgfVxyXG5cclxuICBsYXlvdXQoY2xlYXI9dHJ1ZSkge1xyXG5cclxuICAgIGlmKHRoaXMuY2UgJiYgdGhpcy5kYykge1xyXG4gICAgICBjb25zdCBjbGllbnRXPXRoaXMuY2UuY2xpZW50V2lkdGg7XHJcbiAgICAgIGlmKHRoaXMuX2F1ZGlvRGF0YUhvbGRlcil7XHJcbiAgICAgICAgaWYodGhpcy5fZml4Rml0VG9QYW5lbCkge1xyXG4gICAgICAgICAgLy8gU2V0IHRoZSB2aXJ0dWFsIGNhbnZhcyB3aWR0aCB0byB0aGUgdmlzaWJsZSB3aWR0aFxyXG4gICAgICAgICAgaWYodGhpcy5jZS5zdHlsZS53aWR0aCE9JzEwMCUnKSB7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJzZXQgd2lkdGggdG8gMTAwJVwiKTtcclxuICAgICAgICAgICAgdGhpcy5jZS5zdHlsZS53aWR0aCA9ICcxMDAlJztcclxuICAgICAgICAgIH1cclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgIGlmICh0aGlzLl94Wm9vbSkge1xyXG4gICAgICAgICAgICAvLyBTZXQgdGhlIHZpcnR1YWwgY2FudmFzIHdpZHRoIGFjY29yZGluZyB0byB0aGUgdmFsdWUgb2YgdGhlIHVzZXIgc2VsZWN0ZWQgeFpvb20gdmFsdWVcclxuICAgICAgICAgICAgY29uc3QgbmV3Q2xXID0gTWF0aC5yb3VuZCggdGhpcy5feFpvb20qdGhpcy5fYXVkaW9EYXRhSG9sZGVyPy5kdXJhdGlvbiApO1xyXG4gICAgICAgICAgICB0aGlzLmNlLnN0eWxlLndpZHRoID0gbmV3Q2xXICsgJ3B4JztcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFNldCB0aGUgdmlydHVhbCBjYW52YXMgd2lkdGggdG8gdGhlIHZpc2libGUgd2lkdGggb25seVxyXG4gICAgICAgICAgICB0aGlzLmNlLnN0eWxlLndpZHRoID0gY2xpZW50VyArICdweCc7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuX2xheW91dChjbGVhcix0cnVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGF1ZGlvRGF0YShhdWRpb0RhdGFIb2xkZXI6IEF1ZGlvRGF0YUhvbGRlciB8IG51bGwpIHtcclxuICAgIHRoaXMuX2F1ZGlvQ2xpcD1udWxsXHJcbiAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXI9YXVkaW9EYXRhSG9sZGVyO1xyXG4gICAgdGhpcy5hcy5zZXREYXRhKGF1ZGlvRGF0YUhvbGRlcik7XHJcbiAgICB0aGlzLnNvLnNldERhdGEoYXVkaW9EYXRhSG9sZGVyKTtcclxuICAgIHRoaXMubGF5b3V0KCk7XHJcbiAgfVxyXG5cclxuICBnZXQgYXVkaW9EYXRhKCk6QXVkaW9EYXRhSG9sZGVyfG51bGx7XHJcbiAgICByZXR1cm4gdGhpcy5fYXVkaW9EYXRhSG9sZGVyXHJcbiAgfVxyXG5cclxuXHJcbiAgQElucHV0KClcclxuICBzZXQgYXVkaW9DbGlwKGF1ZGlvQ2xpcDogQXVkaW9DbGlwIHwgbnVsbCkge1xyXG4gICAgdGhpcy5fYXVkaW9DbGlwPWF1ZGlvQ2xpcFxyXG4gICAgICBsZXQgYXVkaW9EYXRhOkF1ZGlvRGF0YUhvbGRlcnxudWxsPW51bGw7XHJcbiAgICBsZXQgc2VsOlNlbGVjdGlvbnxudWxsPW51bGw7XHJcbiAgICAgIGlmKGF1ZGlvQ2xpcCkge1xyXG4gICAgICAgIGF1ZGlvRGF0YSA9IGF1ZGlvQ2xpcC5hdWRpb0RhdGFIb2xkZXI7XHJcbiAgICAgICAgaWYgKHRoaXMuX2F1ZGlvQ2xpcCkge1xyXG4gICAgICAgICAgdGhpcy5fYXVkaW9DbGlwLmFkZFNlbGVjdGlvbk9ic2VydmVyKChjbGlwKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gY2xpcC5zZWxlY3Rpb25cclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzZWw9YXVkaW9DbGlwLnNlbGVjdGlvbjtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBhdWRpb0RhdGE7XHJcbiAgICAgIHRoaXMuYXMuc2V0RGF0YSh0aGlzLl9hdWRpb0RhdGFIb2xkZXIpO1xyXG4gICAgICB0aGlzLnNvLnNldERhdGEodGhpcy5fYXVkaW9EYXRhSG9sZGVyKTtcclxuICAgICAgdGhpcy5zZWxlY3Rpbmc9bnVsbFxyXG4gICAgICB0aGlzLnNlbGVjdGlvbj1zZWxcclxuICAgIHRoaXMubGF5b3V0KCk7XHJcbiAgfVxyXG5cclxuICBnZXQgcGxheUZyYW1lUG9zaXRpb24oKTogbnVtYmVyIHxudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl9wbGF5RnJhbWVQb3NpdGlvbjtcclxuICB9XHJcblxyXG4gIHNldCBwbGF5RnJhbWVQb3NpdGlvbihwbGF5RnJhbWVQb3NpdGlvbjogbnVtYmVyfG51bGwpIHtcclxuICAgIHRoaXMuX3BsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgICB0aGlzLmFzLnBsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgICB0aGlzLnNvLnBsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgfVxyXG59XHJcblxyXG4iXX0=