@quantiya/codevibe-claude-plugin 1.0.11 → 1.0.13

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 (473) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/server.js +16 -1162
  3. package/package.json +5 -5
  4. package/dist/appsync-client.js +0 -858
  5. package/dist/auth-cli.js +0 -472
  6. package/dist/command-executor.js +0 -127
  7. package/dist/config.js +0 -106
  8. package/dist/crypto-service.js +0 -278
  9. package/dist/http-api.js +0 -334
  10. package/dist/key-manager.js +0 -287
  11. package/dist/logger.js +0 -18
  12. package/dist/prompt-responder.js +0 -132
  13. package/dist/token-storage.js +0 -169
  14. package/dist/types.js +0 -17
  15. package/node_modules/@quantiya/codevibe-core/README.md +0 -170
  16. package/node_modules/@quantiya/codevibe-core/bin/codevibe.js +0 -7
  17. package/node_modules/@quantiya/codevibe-core/dist/appsync/appsync-client.d.ts +0 -132
  18. package/node_modules/@quantiya/codevibe-core/dist/appsync/appsync-client.js +0 -576
  19. package/node_modules/@quantiya/codevibe-core/dist/appsync/index.d.ts +0 -2
  20. package/node_modules/@quantiya/codevibe-core/dist/appsync/index.js +0 -10
  21. package/node_modules/@quantiya/codevibe-core/dist/appsync/queries.d.ts +0 -16
  22. package/node_modules/@quantiya/codevibe-core/dist/appsync/queries.js +0 -189
  23. package/node_modules/@quantiya/codevibe-core/dist/auth/auth-cli.d.ts +0 -5
  24. package/node_modules/@quantiya/codevibe-core/dist/auth/auth-cli.js +0 -217
  25. package/node_modules/@quantiya/codevibe-core/dist/auth/auth-service.d.ts +0 -87
  26. package/node_modules/@quantiya/codevibe-core/dist/auth/auth-service.js +0 -464
  27. package/node_modules/@quantiya/codevibe-core/dist/auth/fetch-helpers.d.ts +0 -11
  28. package/node_modules/@quantiya/codevibe-core/dist/auth/fetch-helpers.js +0 -165
  29. package/node_modules/@quantiya/codevibe-core/dist/auth/index.d.ts +0 -2
  30. package/node_modules/@quantiya/codevibe-core/dist/auth/index.js +0 -9
  31. package/node_modules/@quantiya/codevibe-core/dist/config/config.d.ts +0 -53
  32. package/node_modules/@quantiya/codevibe-core/dist/config/config.js +0 -123
  33. package/node_modules/@quantiya/codevibe-core/dist/config/index.d.ts +0 -2
  34. package/node_modules/@quantiya/codevibe-core/dist/config/index.js +0 -8
  35. package/node_modules/@quantiya/codevibe-core/dist/crypto/crypto-service.d.ts +0 -118
  36. package/node_modules/@quantiya/codevibe-core/dist/crypto/crypto-service.js +0 -284
  37. package/node_modules/@quantiya/codevibe-core/dist/crypto/index.d.ts +0 -1
  38. package/node_modules/@quantiya/codevibe-core/dist/crypto/index.js +0 -9
  39. package/node_modules/@quantiya/codevibe-core/dist/index.d.ts +0 -14
  40. package/node_modules/@quantiya/codevibe-core/dist/index.js +0 -68
  41. package/node_modules/@quantiya/codevibe-core/dist/keychain/index.d.ts +0 -1
  42. package/node_modules/@quantiya/codevibe-core/dist/keychain/index.js +0 -8
  43. package/node_modules/@quantiya/codevibe-core/dist/keychain/keychain-manager.d.ts +0 -125
  44. package/node_modules/@quantiya/codevibe-core/dist/keychain/keychain-manager.js +0 -375
  45. package/node_modules/@quantiya/codevibe-core/dist/logger/index.d.ts +0 -1
  46. package/node_modules/@quantiya/codevibe-core/dist/logger/index.js +0 -8
  47. package/node_modules/@quantiya/codevibe-core/dist/logger/logger.d.ts +0 -35
  48. package/node_modules/@quantiya/codevibe-core/dist/logger/logger.js +0 -142
  49. package/node_modules/@quantiya/codevibe-core/dist/prompt-parser.d.ts +0 -39
  50. package/node_modules/@quantiya/codevibe-core/dist/prompt-parser.js +0 -236
  51. package/node_modules/@quantiya/codevibe-core/dist/session/index.d.ts +0 -2
  52. package/node_modules/@quantiya/codevibe-core/dist/session/index.js +0 -7
  53. package/node_modules/@quantiya/codevibe-core/dist/session/session-resume.d.ts +0 -55
  54. package/node_modules/@quantiya/codevibe-core/dist/session/session-resume.js +0 -151
  55. package/node_modules/@quantiya/codevibe-core/dist/types/auth.d.ts +0 -15
  56. package/node_modules/@quantiya/codevibe-core/dist/types/auth.js +0 -3
  57. package/node_modules/@quantiya/codevibe-core/dist/types/encryption.d.ts +0 -54
  58. package/node_modules/@quantiya/codevibe-core/dist/types/encryption.js +0 -3
  59. package/node_modules/@quantiya/codevibe-core/dist/types/events.d.ts +0 -74
  60. package/node_modules/@quantiya/codevibe-core/dist/types/events.js +0 -28
  61. package/node_modules/@quantiya/codevibe-core/dist/types/index.d.ts +0 -4
  62. package/node_modules/@quantiya/codevibe-core/dist/types/index.js +0 -22
  63. package/node_modules/@quantiya/codevibe-core/dist/types/session.d.ts +0 -59
  64. package/node_modules/@quantiya/codevibe-core/dist/types/session.js +0 -22
  65. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/CHANGELOG.md +0 -274
  66. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/CONTRIBUTING.md +0 -18
  67. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/LICENSE.md +0 -9
  68. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/README.md +0 -466
  69. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/bin/uuid +0 -2
  70. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/index.js +0 -79
  71. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/md5.js +0 -223
  72. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/native.js +0 -11
  73. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/nil.js +0 -8
  74. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/parse.js +0 -45
  75. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/regex.js +0 -8
  76. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/rng.js +0 -25
  77. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/sha1.js +0 -104
  78. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/stringify.js +0 -44
  79. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/v1.js +0 -107
  80. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/v3.js +0 -16
  81. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/v35.js +0 -80
  82. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/v4.js +0 -43
  83. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/v5.js +0 -16
  84. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/validate.js +0 -17
  85. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/commonjs-browser/version.js +0 -21
  86. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/index.js +0 -9
  87. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/md5.js +0 -215
  88. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/native.js +0 -4
  89. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/nil.js +0 -1
  90. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/parse.js +0 -35
  91. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/regex.js +0 -1
  92. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/rng.js +0 -18
  93. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/sha1.js +0 -96
  94. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/stringify.js +0 -33
  95. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/v1.js +0 -95
  96. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/v3.js +0 -4
  97. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/v35.js +0 -66
  98. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/v4.js +0 -29
  99. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/v5.js +0 -4
  100. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/validate.js +0 -7
  101. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-browser/version.js +0 -11
  102. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/index.js +0 -9
  103. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/md5.js +0 -13
  104. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/native.js +0 -4
  105. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/nil.js +0 -1
  106. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/parse.js +0 -35
  107. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/regex.js +0 -1
  108. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/rng.js +0 -12
  109. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/sha1.js +0 -13
  110. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/stringify.js +0 -33
  111. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/v1.js +0 -95
  112. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/v3.js +0 -4
  113. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/v35.js +0 -66
  114. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/v4.js +0 -29
  115. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/v5.js +0 -4
  116. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/validate.js +0 -7
  117. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/esm-node/version.js +0 -11
  118. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/index.js +0 -79
  119. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/md5-browser.js +0 -223
  120. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/md5.js +0 -23
  121. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/native-browser.js +0 -11
  122. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/native.js +0 -15
  123. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/nil.js +0 -8
  124. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/parse.js +0 -45
  125. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/regex.js +0 -8
  126. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/rng-browser.js +0 -25
  127. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/rng.js +0 -24
  128. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/sha1-browser.js +0 -104
  129. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/sha1.js +0 -23
  130. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/stringify.js +0 -44
  131. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/uuid-bin.js +0 -85
  132. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/v1.js +0 -107
  133. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/v3.js +0 -16
  134. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/v35.js +0 -80
  135. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/v4.js +0 -43
  136. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/v5.js +0 -16
  137. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/validate.js +0 -17
  138. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/dist/version.js +0 -21
  139. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/package.json +0 -135
  140. package/node_modules/@quantiya/codevibe-core/node_modules/uuid/wrapper.mjs +0 -10
  141. package/node_modules/@quantiya/codevibe-core/package.json +0 -51
  142. package/node_modules/base64-js/LICENSE +0 -21
  143. package/node_modules/base64-js/README.md +0 -34
  144. package/node_modules/base64-js/base64js.min.js +0 -1
  145. package/node_modules/base64-js/index.d.ts +0 -3
  146. package/node_modules/base64-js/index.js +0 -150
  147. package/node_modules/base64-js/package.json +0 -47
  148. package/node_modules/bl/.travis.yml +0 -17
  149. package/node_modules/bl/BufferList.js +0 -396
  150. package/node_modules/bl/LICENSE.md +0 -13
  151. package/node_modules/bl/README.md +0 -247
  152. package/node_modules/bl/bl.js +0 -84
  153. package/node_modules/bl/package.json +0 -37
  154. package/node_modules/bl/test/convert.js +0 -21
  155. package/node_modules/bl/test/indexOf.js +0 -492
  156. package/node_modules/bl/test/isBufferList.js +0 -32
  157. package/node_modules/bl/test/test.js +0 -869
  158. package/node_modules/buffer/AUTHORS.md +0 -70
  159. package/node_modules/buffer/LICENSE +0 -21
  160. package/node_modules/buffer/README.md +0 -410
  161. package/node_modules/buffer/index.d.ts +0 -186
  162. package/node_modules/buffer/index.js +0 -1817
  163. package/node_modules/buffer/package.json +0 -96
  164. package/node_modules/chownr/LICENSE +0 -15
  165. package/node_modules/chownr/README.md +0 -3
  166. package/node_modules/chownr/chownr.js +0 -167
  167. package/node_modules/chownr/package.json +0 -29
  168. package/node_modules/decompress-response/index.d.ts +0 -22
  169. package/node_modules/decompress-response/index.js +0 -58
  170. package/node_modules/decompress-response/license +0 -9
  171. package/node_modules/decompress-response/package.json +0 -56
  172. package/node_modules/decompress-response/readme.md +0 -48
  173. package/node_modules/deep-extend/CHANGELOG.md +0 -46
  174. package/node_modules/deep-extend/LICENSE +0 -20
  175. package/node_modules/deep-extend/README.md +0 -91
  176. package/node_modules/deep-extend/index.js +0 -1
  177. package/node_modules/deep-extend/lib/deep-extend.js +0 -150
  178. package/node_modules/deep-extend/package.json +0 -62
  179. package/node_modules/detect-libc/LICENSE +0 -201
  180. package/node_modules/detect-libc/README.md +0 -163
  181. package/node_modules/detect-libc/index.d.ts +0 -14
  182. package/node_modules/detect-libc/lib/detect-libc.js +0 -313
  183. package/node_modules/detect-libc/lib/elf.js +0 -39
  184. package/node_modules/detect-libc/lib/filesystem.js +0 -51
  185. package/node_modules/detect-libc/lib/process.js +0 -24
  186. package/node_modules/detect-libc/package.json +0 -44
  187. package/node_modules/end-of-stream/LICENSE +0 -21
  188. package/node_modules/end-of-stream/README.md +0 -54
  189. package/node_modules/end-of-stream/index.js +0 -96
  190. package/node_modules/end-of-stream/package.json +0 -37
  191. package/node_modules/expand-template/.travis.yml +0 -6
  192. package/node_modules/expand-template/LICENSE +0 -21
  193. package/node_modules/expand-template/README.md +0 -43
  194. package/node_modules/expand-template/index.js +0 -26
  195. package/node_modules/expand-template/package.json +0 -29
  196. package/node_modules/expand-template/test.js +0 -67
  197. package/node_modules/fs-constants/LICENSE +0 -21
  198. package/node_modules/fs-constants/README.md +0 -26
  199. package/node_modules/fs-constants/browser.js +0 -1
  200. package/node_modules/fs-constants/index.js +0 -1
  201. package/node_modules/fs-constants/package.json +0 -19
  202. package/node_modules/github-from-package/.travis.yml +0 -4
  203. package/node_modules/github-from-package/LICENSE +0 -18
  204. package/node_modules/github-from-package/example/package.json +0 -8
  205. package/node_modules/github-from-package/example/url.js +0 -3
  206. package/node_modules/github-from-package/index.js +0 -17
  207. package/node_modules/github-from-package/package.json +0 -30
  208. package/node_modules/github-from-package/readme.markdown +0 -53
  209. package/node_modules/github-from-package/test/a.json +0 -8
  210. package/node_modules/github-from-package/test/b.json +0 -5
  211. package/node_modules/github-from-package/test/c.json +0 -5
  212. package/node_modules/github-from-package/test/d.json +0 -7
  213. package/node_modules/github-from-package/test/e.json +0 -5
  214. package/node_modules/github-from-package/test/url.js +0 -19
  215. package/node_modules/ieee754/LICENSE +0 -11
  216. package/node_modules/ieee754/README.md +0 -51
  217. package/node_modules/ieee754/index.d.ts +0 -10
  218. package/node_modules/ieee754/index.js +0 -85
  219. package/node_modules/ieee754/package.json +0 -52
  220. package/node_modules/ini/LICENSE +0 -15
  221. package/node_modules/ini/README.md +0 -102
  222. package/node_modules/ini/ini.js +0 -206
  223. package/node_modules/ini/package.json +0 -33
  224. package/node_modules/keytar/LICENSE.md +0 -20
  225. package/node_modules/keytar/README.md +0 -94
  226. package/node_modules/keytar/binding.gyp +0 -66
  227. package/node_modules/keytar/build/Release/keytar.node +0 -0
  228. package/node_modules/keytar/keytar.d.ts +0 -51
  229. package/node_modules/keytar/lib/keytar.js +0 -43
  230. package/node_modules/keytar/package.json +0 -66
  231. package/node_modules/keytar/src/async.cc +0 -242
  232. package/node_modules/keytar/src/async.h +0 -103
  233. package/node_modules/keytar/src/credentials.h +0 -13
  234. package/node_modules/keytar/src/keytar.h +0 -41
  235. package/node_modules/keytar/src/keytar_mac.cc +0 -296
  236. package/node_modules/keytar/src/keytar_posix.cc +0 -184
  237. package/node_modules/keytar/src/keytar_win.cc +0 -272
  238. package/node_modules/keytar/src/main.cc +0 -139
  239. package/node_modules/mimic-response/index.d.ts +0 -17
  240. package/node_modules/mimic-response/index.js +0 -77
  241. package/node_modules/mimic-response/license +0 -9
  242. package/node_modules/mimic-response/package.json +0 -42
  243. package/node_modules/mimic-response/readme.md +0 -78
  244. package/node_modules/minimist/.eslintrc +0 -29
  245. package/node_modules/minimist/.github/FUNDING.yml +0 -12
  246. package/node_modules/minimist/.nycrc +0 -14
  247. package/node_modules/minimist/CHANGELOG.md +0 -298
  248. package/node_modules/minimist/LICENSE +0 -18
  249. package/node_modules/minimist/README.md +0 -121
  250. package/node_modules/minimist/example/parse.js +0 -4
  251. package/node_modules/minimist/index.js +0 -263
  252. package/node_modules/minimist/package.json +0 -75
  253. package/node_modules/minimist/test/all_bool.js +0 -34
  254. package/node_modules/minimist/test/bool.js +0 -177
  255. package/node_modules/minimist/test/dash.js +0 -43
  256. package/node_modules/minimist/test/default_bool.js +0 -37
  257. package/node_modules/minimist/test/dotted.js +0 -24
  258. package/node_modules/minimist/test/kv_short.js +0 -32
  259. package/node_modules/minimist/test/long.js +0 -33
  260. package/node_modules/minimist/test/num.js +0 -38
  261. package/node_modules/minimist/test/parse.js +0 -209
  262. package/node_modules/minimist/test/parse_modified.js +0 -11
  263. package/node_modules/minimist/test/proto.js +0 -64
  264. package/node_modules/minimist/test/short.js +0 -69
  265. package/node_modules/minimist/test/stop_early.js +0 -17
  266. package/node_modules/minimist/test/unknown.js +0 -104
  267. package/node_modules/minimist/test/whitespace.js +0 -10
  268. package/node_modules/mkdirp-classic/LICENSE +0 -21
  269. package/node_modules/mkdirp-classic/README.md +0 -18
  270. package/node_modules/mkdirp-classic/index.js +0 -98
  271. package/node_modules/mkdirp-classic/package.json +0 -18
  272. package/node_modules/napi-build-utils/.github/workflows/run-npm-tests.yml +0 -31
  273. package/node_modules/napi-build-utils/LICENSE +0 -21
  274. package/node_modules/napi-build-utils/README.md +0 -52
  275. package/node_modules/napi-build-utils/index.js +0 -214
  276. package/node_modules/napi-build-utils/index.md +0 -0
  277. package/node_modules/napi-build-utils/package.json +0 -42
  278. package/node_modules/node-abi/LICENSE +0 -21
  279. package/node_modules/node-abi/README.md +0 -54
  280. package/node_modules/node-abi/abi_registry.json +0 -432
  281. package/node_modules/node-abi/index.js +0 -179
  282. package/node_modules/node-abi/package.json +0 -45
  283. package/node_modules/node-addon-api/LICENSE.md +0 -13
  284. package/node_modules/node-addon-api/README.md +0 -293
  285. package/node_modules/node-addon-api/common.gypi +0 -21
  286. package/node_modules/node-addon-api/except.gypi +0 -25
  287. package/node_modules/node-addon-api/index.js +0 -11
  288. package/node_modules/node-addon-api/napi-inl.deprecated.h +0 -192
  289. package/node_modules/node-addon-api/napi-inl.h +0 -6209
  290. package/node_modules/node-addon-api/napi.h +0 -2983
  291. package/node_modules/node-addon-api/node_api.gyp +0 -9
  292. package/node_modules/node-addon-api/noexcept.gypi +0 -26
  293. package/node_modules/node-addon-api/nothing.c +0 -0
  294. package/node_modules/node-addon-api/package-support.json +0 -21
  295. package/node_modules/node-addon-api/package.json +0 -399
  296. package/node_modules/node-addon-api/tools/README.md +0 -73
  297. package/node_modules/node-addon-api/tools/check-napi.js +0 -100
  298. package/node_modules/node-addon-api/tools/clang-format.js +0 -68
  299. package/node_modules/node-addon-api/tools/conversion.js +0 -309
  300. package/node_modules/node-addon-api/tools/eslint-format.js +0 -71
  301. package/node_modules/prebuild-install/CHANGELOG.md +0 -131
  302. package/node_modules/prebuild-install/CONTRIBUTING.md +0 -6
  303. package/node_modules/prebuild-install/LICENSE +0 -21
  304. package/node_modules/prebuild-install/README.md +0 -163
  305. package/node_modules/prebuild-install/asset.js +0 -44
  306. package/node_modules/prebuild-install/bin.js +0 -78
  307. package/node_modules/prebuild-install/download.js +0 -142
  308. package/node_modules/prebuild-install/error.js +0 -14
  309. package/node_modules/prebuild-install/help.txt +0 -16
  310. package/node_modules/prebuild-install/index.js +0 -1
  311. package/node_modules/prebuild-install/log.js +0 -33
  312. package/node_modules/prebuild-install/package.json +0 -67
  313. package/node_modules/prebuild-install/proxy.js +0 -35
  314. package/node_modules/prebuild-install/rc.js +0 -64
  315. package/node_modules/prebuild-install/util.js +0 -143
  316. package/node_modules/pump/.github/FUNDING.yml +0 -2
  317. package/node_modules/pump/.travis.yml +0 -5
  318. package/node_modules/pump/LICENSE +0 -21
  319. package/node_modules/pump/README.md +0 -74
  320. package/node_modules/pump/SECURITY.md +0 -5
  321. package/node_modules/pump/empty.js +0 -1
  322. package/node_modules/pump/index.js +0 -86
  323. package/node_modules/pump/package.json +0 -30
  324. package/node_modules/pump/test-browser.js +0 -66
  325. package/node_modules/pump/test-node.js +0 -53
  326. package/node_modules/rc/LICENSE.APACHE2 +0 -15
  327. package/node_modules/rc/LICENSE.BSD +0 -26
  328. package/node_modules/rc/LICENSE.MIT +0 -24
  329. package/node_modules/rc/README.md +0 -227
  330. package/node_modules/rc/browser.js +0 -7
  331. package/node_modules/rc/cli.js +0 -4
  332. package/node_modules/rc/index.js +0 -53
  333. package/node_modules/rc/lib/utils.js +0 -104
  334. package/node_modules/rc/package.json +0 -29
  335. package/node_modules/rc/test/ini.js +0 -16
  336. package/node_modules/rc/test/nested-env-vars.js +0 -50
  337. package/node_modules/rc/test/test.js +0 -59
  338. package/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  339. package/node_modules/readable-stream/GOVERNANCE.md +0 -136
  340. package/node_modules/readable-stream/LICENSE +0 -47
  341. package/node_modules/readable-stream/README.md +0 -106
  342. package/node_modules/readable-stream/errors-browser.js +0 -127
  343. package/node_modules/readable-stream/errors.js +0 -116
  344. package/node_modules/readable-stream/experimentalWarning.js +0 -17
  345. package/node_modules/readable-stream/lib/_stream_duplex.js +0 -126
  346. package/node_modules/readable-stream/lib/_stream_passthrough.js +0 -37
  347. package/node_modules/readable-stream/lib/_stream_readable.js +0 -1027
  348. package/node_modules/readable-stream/lib/_stream_transform.js +0 -190
  349. package/node_modules/readable-stream/lib/_stream_writable.js +0 -641
  350. package/node_modules/readable-stream/lib/internal/streams/async_iterator.js +0 -180
  351. package/node_modules/readable-stream/lib/internal/streams/buffer_list.js +0 -183
  352. package/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -96
  353. package/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +0 -86
  354. package/node_modules/readable-stream/lib/internal/streams/from-browser.js +0 -3
  355. package/node_modules/readable-stream/lib/internal/streams/from.js +0 -52
  356. package/node_modules/readable-stream/lib/internal/streams/pipeline.js +0 -86
  357. package/node_modules/readable-stream/lib/internal/streams/state.js +0 -22
  358. package/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  359. package/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  360. package/node_modules/readable-stream/package.json +0 -68
  361. package/node_modules/readable-stream/readable-browser.js +0 -9
  362. package/node_modules/readable-stream/readable.js +0 -16
  363. package/node_modules/safe-buffer/LICENSE +0 -21
  364. package/node_modules/safe-buffer/README.md +0 -584
  365. package/node_modules/safe-buffer/index.d.ts +0 -187
  366. package/node_modules/safe-buffer/index.js +0 -65
  367. package/node_modules/safe-buffer/package.json +0 -51
  368. package/node_modules/semver/LICENSE +0 -15
  369. package/node_modules/semver/README.md +0 -665
  370. package/node_modules/semver/bin/semver.js +0 -191
  371. package/node_modules/semver/classes/comparator.js +0 -143
  372. package/node_modules/semver/classes/index.js +0 -7
  373. package/node_modules/semver/classes/range.js +0 -557
  374. package/node_modules/semver/classes/semver.js +0 -333
  375. package/node_modules/semver/functions/clean.js +0 -8
  376. package/node_modules/semver/functions/cmp.js +0 -54
  377. package/node_modules/semver/functions/coerce.js +0 -62
  378. package/node_modules/semver/functions/compare-build.js +0 -9
  379. package/node_modules/semver/functions/compare-loose.js +0 -5
  380. package/node_modules/semver/functions/compare.js +0 -7
  381. package/node_modules/semver/functions/diff.js +0 -60
  382. package/node_modules/semver/functions/eq.js +0 -5
  383. package/node_modules/semver/functions/gt.js +0 -5
  384. package/node_modules/semver/functions/gte.js +0 -5
  385. package/node_modules/semver/functions/inc.js +0 -21
  386. package/node_modules/semver/functions/lt.js +0 -5
  387. package/node_modules/semver/functions/lte.js +0 -5
  388. package/node_modules/semver/functions/major.js +0 -5
  389. package/node_modules/semver/functions/minor.js +0 -5
  390. package/node_modules/semver/functions/neq.js +0 -5
  391. package/node_modules/semver/functions/parse.js +0 -18
  392. package/node_modules/semver/functions/patch.js +0 -5
  393. package/node_modules/semver/functions/prerelease.js +0 -8
  394. package/node_modules/semver/functions/rcompare.js +0 -5
  395. package/node_modules/semver/functions/rsort.js +0 -5
  396. package/node_modules/semver/functions/satisfies.js +0 -12
  397. package/node_modules/semver/functions/sort.js +0 -5
  398. package/node_modules/semver/functions/valid.js +0 -8
  399. package/node_modules/semver/index.js +0 -91
  400. package/node_modules/semver/internal/constants.js +0 -37
  401. package/node_modules/semver/internal/debug.js +0 -11
  402. package/node_modules/semver/internal/identifiers.js +0 -29
  403. package/node_modules/semver/internal/lrucache.js +0 -42
  404. package/node_modules/semver/internal/parse-options.js +0 -17
  405. package/node_modules/semver/internal/re.js +0 -223
  406. package/node_modules/semver/package.json +0 -78
  407. package/node_modules/semver/preload.js +0 -4
  408. package/node_modules/semver/range.bnf +0 -16
  409. package/node_modules/semver/ranges/gtr.js +0 -6
  410. package/node_modules/semver/ranges/intersects.js +0 -9
  411. package/node_modules/semver/ranges/ltr.js +0 -6
  412. package/node_modules/semver/ranges/max-satisfying.js +0 -27
  413. package/node_modules/semver/ranges/min-satisfying.js +0 -26
  414. package/node_modules/semver/ranges/min-version.js +0 -63
  415. package/node_modules/semver/ranges/outside.js +0 -82
  416. package/node_modules/semver/ranges/simplify.js +0 -49
  417. package/node_modules/semver/ranges/subset.js +0 -249
  418. package/node_modules/semver/ranges/to-comparators.js +0 -10
  419. package/node_modules/semver/ranges/valid.js +0 -13
  420. package/node_modules/simple-concat/.travis.yml +0 -3
  421. package/node_modules/simple-concat/LICENSE +0 -20
  422. package/node_modules/simple-concat/README.md +0 -44
  423. package/node_modules/simple-concat/index.js +0 -15
  424. package/node_modules/simple-concat/package.json +0 -47
  425. package/node_modules/simple-concat/test/basic.js +0 -41
  426. package/node_modules/simple-get/.github/dependabot.yml +0 -15
  427. package/node_modules/simple-get/.github/workflows/ci.yml +0 -23
  428. package/node_modules/simple-get/LICENSE +0 -20
  429. package/node_modules/simple-get/README.md +0 -333
  430. package/node_modules/simple-get/index.js +0 -108
  431. package/node_modules/simple-get/package.json +0 -67
  432. package/node_modules/string_decoder/LICENSE +0 -48
  433. package/node_modules/string_decoder/README.md +0 -47
  434. package/node_modules/string_decoder/lib/string_decoder.js +0 -296
  435. package/node_modules/string_decoder/package.json +0 -34
  436. package/node_modules/strip-json-comments/index.js +0 -70
  437. package/node_modules/strip-json-comments/license +0 -21
  438. package/node_modules/strip-json-comments/package.json +0 -42
  439. package/node_modules/strip-json-comments/readme.md +0 -64
  440. package/node_modules/tar-fs/.travis.yml +0 -6
  441. package/node_modules/tar-fs/LICENSE +0 -21
  442. package/node_modules/tar-fs/README.md +0 -165
  443. package/node_modules/tar-fs/index.js +0 -363
  444. package/node_modules/tar-fs/package.json +0 -41
  445. package/node_modules/tar-fs/test/fixtures/a/hello.txt +0 -1
  446. package/node_modules/tar-fs/test/fixtures/b/a/test.txt +0 -1
  447. package/node_modules/tar-fs/test/fixtures/d/file1 +0 -0
  448. package/node_modules/tar-fs/test/fixtures/d/file2 +0 -0
  449. package/node_modules/tar-fs/test/fixtures/d/sub-dir/file5 +0 -0
  450. package/node_modules/tar-fs/test/fixtures/d/sub-files/file3 +0 -0
  451. package/node_modules/tar-fs/test/fixtures/d/sub-files/file4 +0 -0
  452. package/node_modules/tar-fs/test/fixtures/e/directory/.ignore +0 -0
  453. package/node_modules/tar-fs/test/fixtures/e/file +0 -0
  454. package/node_modules/tar-fs/test/fixtures/invalid.tar +0 -0
  455. package/node_modules/tar-fs/test/index.js +0 -346
  456. package/node_modules/tar-stream/LICENSE +0 -21
  457. package/node_modules/tar-stream/README.md +0 -168
  458. package/node_modules/tar-stream/extract.js +0 -257
  459. package/node_modules/tar-stream/headers.js +0 -295
  460. package/node_modules/tar-stream/index.js +0 -2
  461. package/node_modules/tar-stream/pack.js +0 -255
  462. package/node_modules/tar-stream/package.json +0 -58
  463. package/node_modules/tar-stream/sandbox.js +0 -11
  464. package/node_modules/tunnel-agent/LICENSE +0 -55
  465. package/node_modules/tunnel-agent/README.md +0 -4
  466. package/node_modules/tunnel-agent/index.js +0 -244
  467. package/node_modules/tunnel-agent/package.json +0 -22
  468. package/node_modules/util-deprecate/History.md +0 -16
  469. package/node_modules/util-deprecate/LICENSE +0 -24
  470. package/node_modules/util-deprecate/README.md +0 -53
  471. package/node_modules/util-deprecate/browser.js +0 -67
  472. package/node_modules/util-deprecate/node.js +0 -6
  473. package/node_modules/util-deprecate/package.json +0 -27
@@ -1,576 +0,0 @@
1
- "use strict";
2
- //
3
- // appsync-client.ts
4
- // CodeVibe Core
5
- //
6
- // GraphQL client for AWS AppSync with WebSocket subscriptions
7
- //
8
- var __importDefault = (this && this.__importDefault) || function (mod) {
9
- return (mod && mod.__esModule) ? mod : { "default": mod };
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.AppSyncClient = void 0;
13
- const ws_1 = __importDefault(require("ws"));
14
- const uuid_1 = require("uuid");
15
- const config_1 = require("../config");
16
- const logger_1 = require("../logger");
17
- const keychain_1 = require("../keychain");
18
- const fetch_helpers_1 = require("../auth/fetch-helpers");
19
- const queries_1 = require("./queries");
20
- const types_1 = require("../types");
21
- /**
22
- * Reconnection configuration — two-phase strategy:
23
- * Phase 1 (urgent): Exponential backoff 1s → 60s for first 10 attempts
24
- * Phase 2 (persistent): Retry every 5 minutes indefinitely
25
- */
26
- const RECONNECT_CONFIG = {
27
- urgentMaxAttempts: 10,
28
- baseDelayMs: 1000,
29
- maxDelayMs: 60000,
30
- backoffMultiplier: 2,
31
- persistentDelayMs: 5 * 60 * 1000, // 5 minutes
32
- };
33
- /**
34
- * AppSync GraphQL client with WebSocket subscriptions
35
- */
36
- class AppSyncClient {
37
- constructor() {
38
- this.authenticated = false;
39
- this.currentUserId = null;
40
- this.currentEmail = null;
41
- this.tokens = null;
42
- this.activeSubscriptions = new Map();
43
- // MARK: - Heartbeat
44
- this.heartbeatTimers = new Map();
45
- // Get environment from centralized config (reads process.env.ENVIRONMENT)
46
- this.environment = (0, config_1.getEnvironment)();
47
- logger_1.logger.info('[AppSyncClient] Initialized', { environment: this.environment });
48
- }
49
- /**
50
- * Get the current authenticated user ID
51
- */
52
- getCurrentUserId() {
53
- if (!this.currentUserId) {
54
- throw new Error('Not authenticated. Call authenticateWithStoredTokens() first.');
55
- }
56
- return this.currentUserId;
57
- }
58
- /**
59
- * Get the current authenticated user email
60
- */
61
- getCurrentUserEmail() {
62
- return this.currentEmail;
63
- }
64
- /**
65
- * Authenticate using stored OAuth tokens from keychain
66
- */
67
- async authenticateWithStoredTokens() {
68
- try {
69
- const tokens = await keychain_1.keychainManager.getTokens(this.environment);
70
- if (!tokens) {
71
- logger_1.logger.debug('[AppSyncClient] No stored tokens found');
72
- return false;
73
- }
74
- logger_1.logger.info('[AppSyncClient] Found stored OAuth tokens', {
75
- userId: tokens.userId,
76
- email: tokens.email,
77
- expired: keychain_1.keychainManager.isTokenExpired(tokens),
78
- });
79
- // If tokens are expired, try to refresh them
80
- if (keychain_1.keychainManager.isTokenExpired(tokens)) {
81
- logger_1.logger.info('[AppSyncClient] Tokens expired, attempting refresh...');
82
- const refreshed = await this.refreshTokens(tokens);
83
- if (!refreshed) {
84
- logger_1.logger.warn('[AppSyncClient] Token refresh failed');
85
- return false;
86
- }
87
- }
88
- else {
89
- this.tokens = tokens;
90
- }
91
- this.currentUserId = this.tokens.userId;
92
- this.currentEmail = this.tokens.email;
93
- this.authenticated = true;
94
- logger_1.logger.info('[AppSyncClient] Authenticated successfully', {
95
- userId: this.currentUserId,
96
- email: this.currentEmail,
97
- });
98
- return true;
99
- }
100
- catch (error) {
101
- logger_1.logger.error('[AppSyncClient] Authentication failed:', error);
102
- return false;
103
- }
104
- }
105
- /**
106
- * Refresh expired tokens
107
- */
108
- async refreshTokens(tokens) {
109
- try {
110
- const config = (0, config_1.getConfig)();
111
- const tokenUrl = `https://${config.aws.cognitoDomain}/oauth2/token`;
112
- const params = new URLSearchParams({
113
- grant_type: 'refresh_token',
114
- client_id: config.aws.cognitoClientId,
115
- refresh_token: tokens.refreshToken,
116
- });
117
- const response = await (0, fetch_helpers_1.fetchWithDiagnostics)(tokenUrl, {
118
- method: 'POST',
119
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
120
- body: params.toString(),
121
- }, 'Token refresh');
122
- if (!response.ok) {
123
- logger_1.logger.error('[AppSyncClient] Token refresh failed', { status: response.status });
124
- return false;
125
- }
126
- const data = await response.json();
127
- const updatedTokens = {
128
- ...tokens,
129
- accessToken: data.access_token,
130
- idToken: data.id_token,
131
- expiresAt: Date.now() + (data.expires_in * 1000),
132
- };
133
- await keychain_1.keychainManager.setTokens(updatedTokens, this.environment);
134
- this.tokens = updatedTokens;
135
- logger_1.logger.info('[AppSyncClient] Tokens refreshed', {
136
- expiresAt: new Date(updatedTokens.expiresAt).toISOString(),
137
- });
138
- return true;
139
- }
140
- catch (error) {
141
- logger_1.logger.error('[AppSyncClient] Token refresh error:', error);
142
- return false;
143
- }
144
- }
145
- /**
146
- * Check if authenticated
147
- */
148
- isAuthenticated() {
149
- return this.authenticated;
150
- }
151
- /**
152
- * Sign out
153
- */
154
- signOut() {
155
- this.authenticated = false;
156
- this.tokens = null;
157
- this.currentUserId = null;
158
- this.currentEmail = null;
159
- this.cleanupSubscriptions();
160
- logger_1.logger.info('[AppSyncClient] Signed out');
161
- }
162
- /**
163
- * Make a GraphQL request
164
- */
165
- async graphqlRequest(query, variables, isRetry = false) {
166
- const config = (0, config_1.getConfig)();
167
- if (!this.tokens?.idToken) {
168
- throw new Error('Not authenticated. Run "codevibe login" first.');
169
- }
170
- const headers = {
171
- 'Content-Type': 'application/json',
172
- 'Authorization': this.tokens.idToken,
173
- };
174
- const response = await (0, fetch_helpers_1.fetchWithDiagnostics)(config.aws.appsyncUrl, {
175
- method: 'POST',
176
- headers,
177
- body: JSON.stringify({ query, variables }),
178
- }, 'AppSync GraphQL request');
179
- const result = await response.json();
180
- // Handle 401 with token refresh
181
- if (response.status === 401 && !isRetry && this.tokens) {
182
- logger_1.logger.info('[AppSyncClient] 401 Unauthorized, refreshing token...');
183
- const refreshed = await this.refreshTokens(this.tokens);
184
- if (refreshed) {
185
- return this.graphqlRequest(query, variables, true);
186
- }
187
- throw new Error('Token expired and refresh failed');
188
- }
189
- if (!response.ok) {
190
- throw new Error(`GraphQL request failed: ${response.status}`);
191
- }
192
- if (result.errors?.length) {
193
- throw new Error(`GraphQL error: ${result.errors[0].message}`);
194
- }
195
- return result;
196
- }
197
- // MARK: - Session Operations
198
- /**
199
- * Create a session
200
- */
201
- async createSession(input) {
202
- const preparedInput = {
203
- ...input,
204
- metadata: input.metadata ? JSON.stringify(input.metadata) : undefined,
205
- };
206
- const response = await this.graphqlRequest(queries_1.mutations.createSession, { input: preparedInput });
207
- logger_1.logger.info('[AppSyncClient] Session created', { sessionId: response.data.createSession.sessionId });
208
- return response.data.createSession;
209
- }
210
- /**
211
- * Update a session
212
- */
213
- async updateSession(input) {
214
- const preparedInput = {
215
- ...input,
216
- metadata: input.metadata ? JSON.stringify(input.metadata) : undefined,
217
- };
218
- const response = await this.graphqlRequest(queries_1.mutations.updateSession, { input: preparedInput });
219
- logger_1.logger.debug('[AppSyncClient] Session updated', { sessionId: response.data.updateSession.sessionId });
220
- return response.data.updateSession;
221
- }
222
- /**
223
- * Get a session
224
- */
225
- async getSession(sessionId) {
226
- const response = await this.graphqlRequest(queries_1.queries.getSession, { sessionId });
227
- return response.data.getSession;
228
- }
229
- // MARK: - Event Operations
230
- /**
231
- * Create an event
232
- */
233
- async createEvent(input) {
234
- const preparedInput = {
235
- ...input,
236
- metadata: input.metadata ? JSON.stringify(input.metadata) : undefined,
237
- };
238
- const response = await this.graphqlRequest(queries_1.mutations.createEvent, { input: preparedInput });
239
- logger_1.logger.debug('[AppSyncClient] Event created', {
240
- eventId: response.data.createEvent.eventId,
241
- type: response.data.createEvent.type,
242
- });
243
- return response.data.createEvent;
244
- }
245
- /**
246
- * Update event status
247
- */
248
- async updateEventStatus(input) {
249
- const response = await this.graphqlRequest(queries_1.mutations.updateEventStatus, { input });
250
- return response.data.updateEventStatus;
251
- }
252
- /**
253
- * List events for a session
254
- */
255
- async listEvents(sessionId, source, limit) {
256
- const response = await this.graphqlRequest(queries_1.queries.listEvents, { sessionId, source, limit });
257
- return response.data.listEvents.items;
258
- }
259
- // MARK: - Device Key Operations
260
- /**
261
- * List user device keys
262
- */
263
- async listUserDeviceKeys() {
264
- const response = await this.graphqlRequest(queries_1.queries.listUserDeviceKeys, {});
265
- return response.data.listUserDeviceKeys || [];
266
- }
267
- /**
268
- * Register device key
269
- */
270
- async registerDeviceKey(deviceId, publicKey, platform, deviceName) {
271
- const input = { deviceId, publicKey, platform, deviceName };
272
- await this.graphqlRequest(queries_1.mutations.registerDeviceKey, { input });
273
- logger_1.logger.info('[AppSyncClient] Device key registered', { deviceId, platform });
274
- }
275
- // MARK: - Attachment Operations
276
- /**
277
- * Get attachment download URL
278
- */
279
- async getAttachmentDownloadUrl(s3Key) {
280
- const response = await this.graphqlRequest(queries_1.mutations.getAttachmentDownloadUrl, { s3Key });
281
- return response.data.getAttachmentDownloadUrl;
282
- }
283
- // MARK: - Subscriptions
284
- /**
285
- * Subscribe to events for a session
286
- */
287
- subscribeToEvents(sessionId, onEvent, onError) {
288
- logger_1.logger.info('[AppSyncClient] Subscribing to events', { sessionId });
289
- // Cleanup existing subscription
290
- const existing = this.activeSubscriptions.get(sessionId);
291
- if (existing) {
292
- this.cleanupSubscriptionState(existing);
293
- this.activeSubscriptions.delete(sessionId);
294
- }
295
- const state = {
296
- ws: null,
297
- subscriptionId: (0, uuid_1.v4)(),
298
- sessionId,
299
- onEvent,
300
- onError,
301
- reconnectAttempts: 0,
302
- isReconnecting: false,
303
- };
304
- this.activeSubscriptions.set(sessionId, state);
305
- this.createSubscription(state);
306
- return () => {
307
- this.cleanupSubscriptionState(state);
308
- this.activeSubscriptions.delete(sessionId);
309
- };
310
- }
311
- /**
312
- * Build WebSocket URL
313
- */
314
- buildRealtimeUrl() {
315
- const config = (0, config_1.getConfig)();
316
- const realtimeUrl = config.aws.appsyncUrl
317
- .replace('https://', 'wss://')
318
- .replace('appsync-api', 'appsync-realtime-api');
319
- const authHeader = {
320
- host: new URL(config.aws.appsyncUrl).host,
321
- };
322
- if (this.tokens?.idToken) {
323
- authHeader['Authorization'] = this.tokens.idToken;
324
- }
325
- const headerBase64 = Buffer.from(JSON.stringify(authHeader)).toString('base64');
326
- const payloadBase64 = Buffer.from(JSON.stringify({})).toString('base64');
327
- return `${realtimeUrl}?header=${headerBase64}&payload=${payloadBase64}`;
328
- }
329
- /**
330
- * Create WebSocket subscription
331
- */
332
- createSubscription(state) {
333
- const { sessionId, subscriptionId, onEvent, onError } = state;
334
- try {
335
- const wsUrl = this.buildRealtimeUrl();
336
- const ws = new ws_1.default(wsUrl, ['graphql-ws']);
337
- ws.on('open', () => {
338
- logger_1.logger.info('[AppSyncClient] WebSocket connected', { sessionId });
339
- ws.send(JSON.stringify({ type: 'connection_init' }));
340
- });
341
- ws.on('message', (data) => {
342
- try {
343
- const message = JSON.parse(data.toString());
344
- switch (message.type) {
345
- case 'connection_ack':
346
- this.sendSubscriptionStart(ws, state);
347
- break;
348
- case 'start_ack':
349
- logger_1.logger.info('[AppSyncClient] Subscription started', { sessionId });
350
- state.isReconnecting = false;
351
- state.reconnectAttempts = 0;
352
- // Resume heartbeat — subscription is alive and can receive mobile events
353
- this.startHeartbeat(sessionId);
354
- break;
355
- case 'data':
356
- this.resetKeepAliveTimer(state);
357
- const event = message.payload?.data?.onEventCreated;
358
- if (event && event.source === types_1.EventSource.MOBILE) {
359
- onEvent(event);
360
- }
361
- break;
362
- case 'ka':
363
- this.resetKeepAliveTimer(state);
364
- break;
365
- case 'error':
366
- const errorMsg = message.payload?.errors?.[0]?.message || 'Unknown error';
367
- this.handleSubscriptionError(state, new Error(errorMsg));
368
- break;
369
- }
370
- }
371
- catch (e) {
372
- logger_1.logger.error('[AppSyncClient] Failed to parse message', { error: e });
373
- }
374
- });
375
- ws.on('error', (error) => {
376
- logger_1.logger.error('[AppSyncClient] WebSocket error', { sessionId, error: error.message });
377
- this.handleSubscriptionError(state, error);
378
- });
379
- ws.on('close', (code, reason) => {
380
- logger_1.logger.info('[AppSyncClient] WebSocket closed', { sessionId, code });
381
- if (state.keepAliveTimer) {
382
- clearTimeout(state.keepAliveTimer);
383
- }
384
- // Reconnect if subscription is still active (not intentionally stopped).
385
- // Includes code 1000 — AppSync closes WebSockets after 24 hours with
386
- // code 1000, which is NOT an intentional stop by the plugin.
387
- if (this.activeSubscriptions.has(sessionId)) {
388
- this.handleSubscriptionError(state, new Error(`WebSocket closed: ${code}`));
389
- }
390
- });
391
- state.ws = ws;
392
- this.resetKeepAliveTimer(state);
393
- }
394
- catch (error) {
395
- this.handleSubscriptionError(state, error);
396
- }
397
- }
398
- /**
399
- * Send subscription start message
400
- */
401
- sendSubscriptionStart(ws, state) {
402
- const config = (0, config_1.getConfig)();
403
- const { sessionId, subscriptionId } = state;
404
- const authHeader = {
405
- host: new URL(config.aws.appsyncUrl).host,
406
- };
407
- if (this.tokens?.idToken) {
408
- authHeader['Authorization'] = this.tokens.idToken;
409
- }
410
- ws.send(JSON.stringify({
411
- id: subscriptionId,
412
- type: 'start',
413
- payload: {
414
- data: JSON.stringify({
415
- query: queries_1.subscriptions.onEventCreated,
416
- variables: { sessionId },
417
- }),
418
- extensions: { authorization: authHeader },
419
- },
420
- }));
421
- }
422
- /**
423
- * Reset keep-alive timer
424
- */
425
- resetKeepAliveTimer(state) {
426
- if (state.keepAliveTimer) {
427
- clearTimeout(state.keepAliveTimer);
428
- }
429
- state.keepAliveTimer = setTimeout(() => {
430
- this.handleSubscriptionError(state, new Error('Keep-alive timeout'));
431
- }, 5 * 60 * 1000);
432
- }
433
- /**
434
- * Handle subscription error with two-phase reconnection:
435
- * Phase 1 (urgent): Exponential backoff for first N attempts
436
- * Phase 2 (persistent): Fixed interval retry indefinitely
437
- */
438
- handleSubscriptionError(state, error) {
439
- const { sessionId, onError } = state;
440
- if (state.isReconnecting || !this.activeSubscriptions.has(sessionId)) {
441
- return;
442
- }
443
- state.isReconnecting = true;
444
- state.reconnectAttempts++;
445
- // Pause heartbeat — subscription is down, iOS should not show "Desktop connected"
446
- this.stopHeartbeat(sessionId);
447
- const isUrgentPhase = state.reconnectAttempts <= RECONNECT_CONFIG.urgentMaxAttempts;
448
- let delay;
449
- if (isUrgentPhase) {
450
- delay = Math.min(RECONNECT_CONFIG.baseDelayMs * Math.pow(RECONNECT_CONFIG.backoffMultiplier, state.reconnectAttempts - 1), RECONNECT_CONFIG.maxDelayMs);
451
- }
452
- else {
453
- delay = RECONNECT_CONFIG.persistentDelayMs;
454
- if (state.reconnectAttempts === RECONNECT_CONFIG.urgentMaxAttempts + 1) {
455
- logger_1.logger.info('[AppSyncClient] Switching to persistent reconnect (every 5min)', { sessionId });
456
- }
457
- }
458
- logger_1.logger.info('[AppSyncClient] Scheduling reconnect', {
459
- sessionId,
460
- attempt: state.reconnectAttempts,
461
- phase: isUrgentPhase ? 'urgent' : 'persistent',
462
- delayMs: delay,
463
- });
464
- if (state.ws) {
465
- try {
466
- state.ws.close(1000);
467
- }
468
- catch (e) { /* ignore */ }
469
- state.ws = null;
470
- }
471
- if (state.keepAliveTimer) {
472
- clearTimeout(state.keepAliveTimer);
473
- }
474
- state.reconnectTimer = setTimeout(async () => {
475
- // Reset flag so next failure can trigger another reconnect
476
- state.isReconnecting = false;
477
- if (!this.activeSubscriptions.has(sessionId)) {
478
- return;
479
- }
480
- // Refresh tokens before reconnecting — they may have expired
481
- try {
482
- const freshTokens = await keychain_1.keychainManager.getTokens(this.environment);
483
- if (freshTokens) {
484
- if (keychain_1.keychainManager.isTokenExpired(freshTokens)) {
485
- const refreshed = await this.refreshTokens(freshTokens);
486
- if (refreshed) {
487
- logger_1.logger.info('[AppSyncClient] Tokens refreshed before reconnect', { sessionId });
488
- }
489
- }
490
- else {
491
- this.tokens = freshTokens;
492
- }
493
- }
494
- }
495
- catch (e) {
496
- logger_1.logger.warn('[AppSyncClient] Token refresh failed before reconnect, using existing tokens', { sessionId });
497
- }
498
- state.subscriptionId = (0, uuid_1.v4)();
499
- this.createSubscription(state);
500
- }, delay);
501
- }
502
- /**
503
- * Cleanup subscription state
504
- */
505
- cleanupSubscriptionState(state) {
506
- if (state.reconnectTimer) {
507
- clearTimeout(state.reconnectTimer);
508
- }
509
- if (state.keepAliveTimer) {
510
- clearTimeout(state.keepAliveTimer);
511
- }
512
- if (state.ws) {
513
- try {
514
- if (state.ws.readyState === ws_1.default.OPEN) {
515
- state.ws.send(JSON.stringify({ id: state.subscriptionId, type: 'stop' }));
516
- state.ws.close(1000);
517
- }
518
- }
519
- catch (e) { /* ignore */ }
520
- state.ws = null;
521
- }
522
- }
523
- /**
524
- * Start periodic heartbeat for a session.
525
- * Updates lastHeartbeatAt on the session every intervalMs (default 2 minutes).
526
- */
527
- startHeartbeat(sessionId, intervalMs = 2 * 60 * 1000) {
528
- this.stopHeartbeat(sessionId);
529
- // Send initial heartbeat immediately
530
- this.sendHeartbeat(sessionId);
531
- const timer = setInterval(() => {
532
- this.sendHeartbeat(sessionId);
533
- }, intervalMs);
534
- this.heartbeatTimers.set(sessionId, timer);
535
- logger_1.logger.info('[AppSyncClient] Heartbeat started', { sessionId, intervalMs });
536
- }
537
- /**
538
- * Stop heartbeat for a session.
539
- */
540
- stopHeartbeat(sessionId) {
541
- const timer = this.heartbeatTimers.get(sessionId);
542
- if (timer) {
543
- clearInterval(timer);
544
- this.heartbeatTimers.delete(sessionId);
545
- logger_1.logger.info('[AppSyncClient] Heartbeat stopped', { sessionId });
546
- }
547
- }
548
- /**
549
- * Send a single heartbeat update.
550
- */
551
- async sendHeartbeat(sessionId) {
552
- try {
553
- await this.updateSession({
554
- sessionId,
555
- lastHeartbeatAt: new Date().toISOString(),
556
- });
557
- logger_1.logger.debug('[AppSyncClient] Heartbeat sent', { sessionId });
558
- }
559
- catch (error) {
560
- logger_1.logger.warn('[AppSyncClient] Heartbeat failed', { sessionId, error });
561
- }
562
- }
563
- /**
564
- * Cleanup all subscriptions and heartbeats
565
- */
566
- cleanupSubscriptions() {
567
- this.activeSubscriptions.forEach((state) => {
568
- this.cleanupSubscriptionState(state);
569
- });
570
- this.activeSubscriptions.clear();
571
- this.heartbeatTimers.forEach((timer) => clearInterval(timer));
572
- this.heartbeatTimers.clear();
573
- }
574
- }
575
- exports.AppSyncClient = AppSyncClient;
576
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwc3luYy1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBwc3luYy9hcHBzeW5jLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLG9CQUFvQjtBQUNwQixnQkFBZ0I7QUFDaEIsRUFBRTtBQUNGLDhEQUE4RDtBQUM5RCxFQUFFOzs7Ozs7QUFFRiw0Q0FBMkI7QUFDM0IsK0JBQW9DO0FBQ3BDLHNDQUFzRDtBQUN0RCxzQ0FBbUM7QUFDbkMsMENBQThDO0FBQzlDLHlEQUE2RDtBQUM3RCx1Q0FBOEQ7QUFDOUQsb0NBVWtCO0FBeUJsQjs7OztHQUlHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRztJQUN2QixpQkFBaUIsRUFBRSxFQUFFO0lBQ3JCLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLFVBQVUsRUFBRSxLQUFLO0lBQ2pCLGlCQUFpQixFQUFFLENBQUM7SUFDcEIsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLEVBQUUsWUFBWTtDQUMvQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFhLGFBQWE7SUFReEI7UUFQUSxrQkFBYSxHQUFZLEtBQUssQ0FBQztRQUMvQixrQkFBYSxHQUFrQixJQUFJLENBQUM7UUFDcEMsaUJBQVksR0FBa0IsSUFBSSxDQUFDO1FBQ25DLFdBQU0sR0FBcUIsSUFBSSxDQUFDO1FBQ2hDLHdCQUFtQixHQUFtQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBcWtCeEUsb0JBQW9CO1FBRVosb0JBQWUsR0FBZ0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQW5rQi9ELDBFQUEwRTtRQUMxRSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUEsdUJBQWMsR0FBRSxDQUFDO1FBQ3BDLGVBQU0sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUVEOztPQUVHO0lBQ0ks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O1lBQ0gsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDO2dCQUN2QixTQUFTO2dCQUNULGVBQWUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTthQUMxQyxDQUFDLENBQUM7WUFDSCxlQUFNLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxFQUFFLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLGVBQU0sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLEVBQUUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN4RSxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ksb0JBQW9CO1FBQ3pCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUN6QyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFakMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzlELElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDL0IsQ0FBQztDQUNGO0FBdm9CRCxzQ0F1b0JDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIGFwcHN5bmMtY2xpZW50LnRzXG4vLyBDb2RlVmliZSBDb3JlXG4vL1xuLy8gR3JhcGhRTCBjbGllbnQgZm9yIEFXUyBBcHBTeW5jIHdpdGggV2ViU29ja2V0IHN1YnNjcmlwdGlvbnNcbi8vXG5cbmltcG9ydCBXZWJTb2NrZXQgZnJvbSAnd3MnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgeyBnZXRDb25maWcsIGdldEVudmlyb25tZW50IH0gZnJvbSAnLi4vY29uZmlnJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBrZXljaGFpbk1hbmFnZXIgfSBmcm9tICcuLi9rZXljaGFpbic7XG5pbXBvcnQgeyBmZXRjaFdpdGhEaWFnbm9zdGljcyB9IGZyb20gJy4uL2F1dGgvZmV0Y2gtaGVscGVycyc7XG5pbXBvcnQgeyBxdWVyaWVzLCBtdXRhdGlvbnMsIHN1YnNjcmlwdGlvbnMgfSBmcm9tICcuL3F1ZXJpZXMnO1xuaW1wb3J0IHtcbiAgQ3JlYXRlRXZlbnRJbnB1dCxcbiAgQ3JlYXRlU2Vzc2lvbklucHV0LFxuICBVcGRhdGVTZXNzaW9uSW5wdXQsXG4gIFVwZGF0ZUV2ZW50U3RhdHVzSW5wdXQsXG4gIEV2ZW50LFxuICBTZXNzaW9uLFxuICBFdmVudFNvdXJjZSxcbiAgRGV2aWNlS2V5LFxuICBUb2tlbkRhdGEsXG59IGZyb20gJy4uL3R5cGVzJztcblxuLyoqXG4gKiBEb3dubG9hZCBVUkwgcmVzcG9uc2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEb3dubG9hZFVybFJlc3BvbnNlIHtcbiAgZG93bmxvYWRVcmw6IHN0cmluZztcbiAgZXhwaXJlc0F0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU3Vic2NyaXB0aW9uIHN0YXRlIGZvciByZWNvbm5lY3Rpb25cbiAqL1xuaW50ZXJmYWNlIFN1YnNjcmlwdGlvblN0YXRlIHtcbiAgd3M6IFdlYlNvY2tldCB8IG51bGw7XG4gIHN1YnNjcmlwdGlvbklkOiBzdHJpbmc7XG4gIHNlc3Npb25JZDogc3RyaW5nO1xuICBvbkV2ZW50OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuICBvbkVycm9yPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZDtcbiAgcmVjb25uZWN0QXR0ZW1wdHM6IG51bWJlcjtcbiAgcmVjb25uZWN0VGltZXI/OiBOb2RlSlMuVGltZW91dDtcbiAgaXNSZWNvbm5lY3Rpbmc6IGJvb2xlYW47XG4gIGtlZXBBbGl2ZVRpbWVyPzogTm9kZUpTLlRpbWVvdXQ7XG59XG5cbi8qKlxuICogUmVjb25uZWN0aW9uIGNvbmZpZ3VyYXRpb24g4oCUIHR3by1waGFzZSBzdHJhdGVneTpcbiAqIFBoYXNlIDEgKHVyZ2VudCk6IEV4cG9uZW50aWFsIGJhY2tvZmYgMXMg4oaSIDYwcyBmb3IgZmlyc3QgMTAgYXR0ZW1wdHNcbiAqIFBoYXNlIDIgKHBlcnNpc3RlbnQpOiBSZXRyeSBldmVyeSA1IG1pbnV0ZXMgaW5kZWZpbml0ZWx5XG4gKi9cbmNvbnN0IFJFQ09OTkVDVF9DT05GSUcgPSB7XG4gIHVyZ2VudE1heEF0dGVtcHRzOiAxMCxcbiAgYmFzZURlbGF5TXM6IDEwMDAsXG4gIG1heERlbGF5TXM6IDYwMDAwLFxuICBiYWNrb2ZmTXVsdGlwbGllcjogMixcbiAgcGVyc2lzdGVudERlbGF5TXM6IDUgKiA2MCAqIDEwMDAsIC8vIDUgbWludXRlc1xufTtcblxuLyoqXG4gKiBBcHBTeW5jIEdyYXBoUUwgY2xpZW50IHdpdGggV2ViU29ja2V0IHN1YnNjcmlwdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIEFwcFN5bmNDbGllbnQge1xuICBwcml2YXRlIGF1dGhlbnRpY2F0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBjdXJyZW50VXNlcklkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjdXJyZW50RW1haWw6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHRva2VuczogVG9rZW5EYXRhIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgYWN0aXZlU3Vic2NyaXB0aW9uczogTWFwPHN0cmluZywgU3Vic2NyaXB0aW9uU3RhdGU+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIGVudmlyb25tZW50OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgLy8gR2V0IGVudmlyb25tZW50IGZyb20gY2VudHJhbGl6ZWQgY29uZmlnIChyZWFkcyBwcm9jZXNzLmVudi5FTlZJUk9OTUVOVClcbiAgICB0aGlzLmVudmlyb25tZW50ID0gZ2V0RW52aXJvbm1lbnQoKTtcbiAgICBsb2dnZXIuaW5mbygnW0FwcFN5bmNDbGllbnRdIEluaXRpYWxpemVkJywgeyBlbnZpcm9ubWVudDogdGhpcy5lbnZpcm9ubWVudCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgYXV0aGVudGljYXRlZCB1c2VyIElEXG4gICAqL1xuICBwdWJsaWMgZ2V0Q3VycmVudFVzZXJJZCgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jdXJyZW50VXNlcklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBhdXRoZW50aWNhdGVkLiBDYWxsIGF1dGhlbnRpY2F0ZVdpdGhTdG9yZWRUb2tlbnMoKSBmaXJzdC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY3VycmVudFVzZXJJZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgYXV0aGVudGljYXRlZCB1c2VyIGVtYWlsXG4gICAqL1xuICBwdWJsaWMgZ2V0Q3VycmVudFVzZXJFbWFpbCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50RW1haWw7XG4gIH1cblxuICAvKipcbiAgICogQXV0aGVudGljYXRlIHVzaW5nIHN0b3JlZCBPQXV0aCB0b2tlbnMgZnJvbSBrZXljaGFpblxuICAgKi9cbiAgcHVibGljIGFzeW5jIGF1dGhlbnRpY2F0ZVdpdGhTdG9yZWRUb2tlbnMoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VucyA9IGF3YWl0IGtleWNoYWluTWFuYWdlci5nZXRUb2tlbnModGhpcy5lbnZpcm9ubWVudCk7XG4gICAgICBpZiAoIXRva2Vucykge1xuICAgICAgICBsb2dnZXIuZGVidWcoJ1tBcHBTeW5jQ2xpZW50XSBObyBzdG9yZWQgdG9rZW5zIGZvdW5kJyk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmluZm8oJ1tBcHBTeW5jQ2xpZW50XSBGb3VuZCBzdG9yZWQgT0F1dGggdG9rZW5zJywge1xuICAgICAgICB1c2VySWQ6IHRva2Vucy51c2VySWQsXG4gICAgICAgIGVtYWlsOiB0b2tlbnMuZW1haWwsXG4gICAgICAgIGV4cGlyZWQ6IGtleWNoYWluTWFuYWdlci5pc1Rva2VuRXhwaXJlZCh0b2tlbnMpLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIElmIHRva2VucyBhcmUgZXhwaXJlZCwgdHJ5IHRvIHJlZnJlc2ggdGhlbVxuICAgICAgaWYgKGtleWNoYWluTWFuYWdlci5pc1Rva2VuRXhwaXJlZCh0b2tlbnMpKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdbQXBwU3luY0NsaWVudF0gVG9rZW5zIGV4cGlyZWQsIGF0dGVtcHRpbmcgcmVmcmVzaC4uLicpO1xuICAgICAgICBjb25zdCByZWZyZXNoZWQgPSBhd2FpdCB0aGlzLnJlZnJlc2hUb2tlbnModG9rZW5zKTtcbiAgICAgICAgaWYgKCFyZWZyZXNoZWQpIHtcbiAgICAgICAgICBsb2dnZXIud2FybignW0FwcFN5bmNDbGllbnRdIFRva2VuIHJlZnJlc2ggZmFpbGVkJyk7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnRva2VucyA9IHRva2VucztcbiAgICAgIH1cblxuICAgICAgdGhpcy5jdXJyZW50VXNlcklkID0gdGhpcy50b2tlbnMhLnVzZXJJZDtcbiAgICAgIHRoaXMuY3VycmVudEVtYWlsID0gdGhpcy50b2tlbnMhLmVtYWlsO1xuICAgICAgdGhpcy5hdXRoZW50aWNhdGVkID0gdHJ1ZTtcblxuICAgICAgbG9nZ2VyLmluZm8oJ1tBcHBTeW5jQ2xpZW50XSBBdXRoZW50aWNhdGVkIHN1Y2Nlc3NmdWxseScsIHtcbiAgICAgICAgdXNlcklkOiB0aGlzLmN1cnJlbnRVc2VySWQsXG4gICAgICAgIGVtYWlsOiB0aGlzLmN1cnJlbnRFbWFpbCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdbQXBwU3luY0NsaWVudF0gQXV0aGVudGljYXRpb24gZmFpbGVkOicsIGVycm9yKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVmcmVzaCBleHBpcmVkIHRva2Vuc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWZyZXNoVG9rZW5zKHRva2VuczogVG9rZW5EYXRhKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgICAgY29uc3QgdG9rZW5VcmwgPSBgaHR0cHM6Ly8ke2NvbmZpZy5hd3MuY29nbml0b0RvbWFpbn0vb2F1dGgyL3Rva2VuYDtcblxuICAgICAgY29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICAgIGdyYW50X3R5cGU6ICdyZWZyZXNoX3Rva2VuJyxcbiAgICAgICAgY2xpZW50X2lkOiBjb25maWcuYXdzLmNvZ25pdG9DbGllbnRJZCxcbiAgICAgICAgcmVmcmVzaF90b2tlbjogdG9rZW5zLnJlZnJlc2hUb2tlbixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoV2l0aERpYWdub3N0aWNzKFxuICAgICAgICB0b2tlblVybCxcbiAgICAgICAge1xuICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnIH0sXG4gICAgICAgICAgYm9keTogcGFyYW1zLnRvU3RyaW5nKCksXG4gICAgICAgIH0sXG4gICAgICAgICdUb2tlbiByZWZyZXNoJ1xuICAgICAgKTtcblxuICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ1tBcHBTeW5jQ2xpZW50XSBUb2tlbiByZWZyZXNoIGZhaWxlZCcsIHsgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKSBhcyB7XG4gICAgICAgIGFjY2Vzc190b2tlbjogc3RyaW5nO1xuICAgICAgICBpZF90b2tlbjogc3RyaW5nO1xuICAgICAgICBleHBpcmVzX2luOiBudW1iZXI7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCB1cGRhdGVkVG9rZW5zOiBUb2tlbkRhdGEgPSB7XG4gICAgICAgIC4uLnRva2VucyxcbiAgICAgICAgYWNjZXNzVG9rZW46IGRhdGEuYWNjZXNzX3Rva2VuLFxuICAgICAgICBpZFRva2VuOiBkYXRhLmlkX3Rva2VuLFxuICAgICAgICBleHBpcmVzQXQ6IERhdGUubm93KCkgKyAoZGF0YS5leHBpcmVzX2luICogMTAwMCksXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBrZXljaGFpbk1hbmFnZXIuc2V0VG9rZW5zKHVwZGF0ZWRUb2tlbnMsIHRoaXMuZW52aXJvbm1lbnQpO1xuICAgICAgdGhpcy50b2tlbnMgPSB1cGRhdGVkVG9rZW5zO1xuXG4gICAgICBsb2dnZXIuaW5mbygnW0FwcFN5bmNDbGllbnRdIFRva2VucyByZWZyZXNoZWQnLCB7XG4gICAgICAgIGV4cGlyZXNBdDogbmV3IERhdGUodXBkYXRlZFRva2Vucy5leHBpcmVzQXQpLnRvSVNPU3RyaW5nKCksXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignW0FwcFN5bmNDbGllbnRdIFRva2VuIHJlZnJlc2ggZXJyb3I6JywgZXJyb3IpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhdXRoZW50aWNhdGVkXG4gICAqL1xuICBwdWJsaWMgaXNBdXRoZW50aWNhdGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmF1dGhlbnRpY2F0ZWQ7XG4gIH1cblxuICAvKipcbiAgICogU2lnbiBvdXRcbiAgICovXG4gIHB1YmxpYyBzaWduT3V0KCk6IHZvaWQge1xuICAgIHRoaXMuYXV0aGVudGljYXRlZCA9IGZhbHNlO1xuICAgIHRoaXMudG9rZW5zID0gbnVsbDtcbiAgICB0aGlzLmN1cnJlbnRVc2VySWQgPSBudWxsO1xuICAgIHRoaXMuY3VycmVudEVtYWlsID0gbnVsbDtcbiAgICB0aGlzLmNsZWFudXBTdWJzY3JpcHRpb25zKCk7XG4gICAgbG9nZ2VyLmluZm8oJ1tBcHBTeW5jQ2xpZW50XSBTaWduZWQgb3V0Jyk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIEdyYXBoUUwgcmVxdWVzdFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBncmFwaHFsUmVxdWVzdChxdWVyeTogc3RyaW5nLCB2YXJpYWJsZXM6IGFueSwgaXNSZXRyeTogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBjb25maWcgPSBnZXRDb25maWcoKTtcblxuICAgIGlmICghdGhpcy50b2tlbnM/LmlkVG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGF1dGhlbnRpY2F0ZWQuIFJ1biBcImNvZGV2aWJlIGxvZ2luXCIgZmlyc3QuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAnQXV0aG9yaXphdGlvbic6IHRoaXMudG9rZW5zLmlkVG9rZW4sXG4gICAgfTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hXaXRoRGlhZ25vc3RpY3MoXG4gICAgICBjb25maWcuYXdzLmFwcHN5bmNVcmwsXG4gICAgICB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7IHF1ZXJ5LCB2YXJpYWJsZXMgfSksXG4gICAgICB9LFxuICAgICAgJ0FwcFN5bmMgR3JhcGhRTCByZXF1ZXN0J1xuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCkgYXMgeyBkYXRhPzogYW55OyBlcnJvcnM/OiBBcnJheTx7IG1lc3NhZ2U6IHN0cmluZyB9PiB9O1xuXG4gICAgLy8gSGFuZGxlIDQwMSB3aXRoIHRva2VuIHJlZnJlc2hcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDEgJiYgIWlzUmV0cnkgJiYgdGhpcy50b2tlbnMpIHtcbiAgICAgIGxvZ2dlci5pbmZvKCdbQXBwU3luY0NsaWVudF0gNDAxIFVuYXV0aG9yaXplZCwgcmVmcmVzaGluZyB0b2tlbi4uLicpO1xuICAgICAgY29uc3QgcmVmcmVzaGVkID0gYXdhaXQgdGhpcy5yZWZyZXNoVG9rZW5zKHRoaXMudG9rZW5zKTtcbiAgICAgIGlmIChyZWZyZXNoZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JhcGhxbFJlcXVlc3QocXVlcnksIHZhcmlhYmxlcywgdHJ1ZSk7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Rva2VuIGV4cGlyZWQgYW5kIHJlZnJlc2ggZmFpbGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBHcmFwaFFMIHJlcXVlc3QgZmFpbGVkOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcbiAgICB9XG5cbiAgICBpZiAocmVzdWx0LmVycm9ycz8ubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEdyYXBoUUwgZXJyb3I6ICR7cmVzdWx0LmVycm9yc1swXS5tZXNzYWdlfWApO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBNQVJLOiAtIFNlc3Npb24gT3BlcmF0aW9uc1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzZXNzaW9uXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgY3JlYXRlU2Vzc2lvbihpbnB1dDogQ3JlYXRlU2Vzc2lvbklucHV0KTogUHJvbWlzZTxTZXNzaW9uPiB7XG4gICAgY29uc3QgcHJlcGFyZWRJbnB1dCA9IHtcbiAgICAgIC4uLmlucHV0LFxuICAgICAgbWV0YWRhdGE6IGlucHV0Lm1ldGFkYXRhID8gSlNPTi5zdHJpbmdpZnkoaW5wdXQubWV0YWRhdGEpIDogdW5kZWZpbmVkLFxuICAgIH07XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ3JhcGhxbFJlcXVlc3QobXV0YXRpb25zLmNyZWF0ZVNlc3Npb24sIHsgaW5wdXQ6IHByZXBhcmVkSW5wdXQgfSk7XG4gICAgbG9nZ2VyLmluZm8oJ1tBcHBTeW5jQ2xpZW50XSBTZXNzaW9uIGNyZWF0ZWQnLCB7IHNlc3Npb25JZDogcmVzcG9uc2UuZGF0YS5jcmVhdGVTZXNzaW9uLnNlc3Npb25JZCB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS5jcmVhdGVTZXNzaW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBhIHNlc3Npb25cbiAgICovXG4gIHB1YmxpYyBhc3luYyB1cGRhdGVTZXNzaW9uKGlucHV0OiBVcGRhdGVTZXNzaW9uSW5wdXQpOiBQcm9taXNlPFNlc3Npb24+IHtcbiAgICBjb25zdCBwcmVwYXJlZElucHV0ID0ge1xuICAgICAgLi4uaW5wdXQsXG4gICAgICBtZXRhZGF0YTogaW5wdXQubWV0YWRhdGEgPyBKU09OLnN0cmluZ2lmeShpbnB1dC5tZXRhZGF0YSkgOiB1bmRlZmluZWQsXG4gICAgfTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5ncmFwaHFsUmVxdWVzdChtdXRhdGlvbnMudXBkYXRlU2Vzc2lvbiwgeyBpbnB1dDogcHJlcGFyZWRJbnB1dCB9KTtcbiAgICBsb2dnZXIuZGVidWcoJ1tBcHBTeW5jQ2xpZW50XSBTZXNzaW9uIHVwZGF0ZWQnLCB7IHNlc3Npb25JZDogcmVzcG9uc2UuZGF0YS51cGRhdGVTZXNzaW9uLnNlc3Npb25JZCB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS51cGRhdGVTZXNzaW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHNlc3Npb25cbiAgICovXG4gIHB1YmxpYyBhc3luYyBnZXRTZXNzaW9uKHNlc3Npb25JZDogc3RyaW5nKTogUHJvbWlzZTxTZXNzaW9uIHwgbnVsbD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5ncmFwaHFsUmVxdWVzdChxdWVyaWVzLmdldFNlc3Npb24sIHsgc2Vzc2lvbklkIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5kYXRhLmdldFNlc3Npb247XG4gIH1cblxuICAvLyBNQVJLOiAtIEV2ZW50IE9wZXJhdGlvbnNcblxuICAvKipcbiAgICogQ3JlYXRlIGFuIGV2ZW50XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgY3JlYXRlRXZlbnQoaW5wdXQ6IENyZWF0ZUV2ZW50SW5wdXQpOiBQcm9taXNlPEV2ZW50PiB7XG4gICAgY29uc3QgcHJlcGFyZWRJbnB1dCA9IHtcbiAgICAgIC4uLmlucHV0LFxuICAgICAgbWV0YWRhdGE6IGlucHV0Lm1ldGFkYXRhID8gSlNPTi5zdHJpbmdpZnkoaW5wdXQubWV0YWRhdGEpIDogdW5kZWZpbmVkLFxuICAgIH07XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ3JhcGhxbFJlcXVlc3QobXV0YXRpb25zLmNyZWF0ZUV2ZW50LCB7IGlucHV0OiBwcmVwYXJlZElucHV0IH0pO1xuICAgIGxvZ2dlci5kZWJ1ZygnW0FwcFN5bmNDbGllbnRdIEV2ZW50IGNyZWF0ZWQnLCB7XG4gICAgICBldmVudElkOiByZXNwb25zZS5kYXRhLmNyZWF0ZUV2ZW50LmV2ZW50SWQsXG4gICAgICB0eXBlOiByZXNwb25zZS5kYXRhLmNyZWF0ZUV2ZW50LnR5cGUsXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEuY3JlYXRlRXZlbnQ7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGV2ZW50IHN0YXR1c1xuICAgKi9cbiAgcHVibGljIGFzeW5jIHVwZGF0ZUV2ZW50U3RhdHVzKGlucHV0OiBVcGRhdGVFdmVudFN0YXR1c0lucHV0KTogUHJvbWlzZTxFdmVudD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5ncmFwaHFsUmVxdWVzdChtdXRhdGlvbnMudXBkYXRlRXZlbnRTdGF0dXMsIHsgaW5wdXQgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEudXBkYXRlRXZlbnRTdGF0dXM7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCBldmVudHMgZm9yIGEgc2Vzc2lvblxuICAgKi9cbiAgcHVibGljIGFzeW5jIGxpc3RFdmVudHMoc2Vzc2lvbklkOiBzdHJpbmcsIHNvdXJjZT86IEV2ZW50U291cmNlLCBsaW1pdD86IG51bWJlcik6IFByb21pc2U8RXZlbnRbXT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5ncmFwaHFsUmVxdWVzdChxdWVyaWVzLmxpc3RFdmVudHMsIHsgc2Vzc2lvbklkLCBzb3VyY2UsIGxpbWl0IH0pO1xuICAgIHJldHVybiByZXNwb25zZS5kYXRhLmxpc3RFdmVudHMuaXRlbXM7XG4gIH1cblxuICAvLyBNQVJLOiAtIERldmljZSBLZXkgT3BlcmF0aW9uc1xuXG4gIC8qKlxuICAgKiBMaXN0IHVzZXIgZGV2aWNlIGtleXNcbiAgICovXG4gIHB1YmxpYyBhc3luYyBsaXN0VXNlckRldmljZUtleXMoKTogUHJvbWlzZTxEZXZpY2VLZXlbXT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5ncmFwaHFsUmVxdWVzdChxdWVyaWVzLmxpc3RVc2VyRGV2aWNlS2V5cywge30pO1xuICAgIHJldHVybiByZXNwb25zZS5kYXRhLmxpc3RVc2VyRGV2aWNlS2V5cyB8fCBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBkZXZpY2Uga2V5XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVnaXN0ZXJEZXZpY2VLZXkoXG4gICAgZGV2aWNlSWQ6IHN0cmluZyxcbiAgICBwdWJsaWNLZXk6IHN0cmluZyxcbiAgICBwbGF0Zm9ybTogc3RyaW5nLFxuICAgIGRldmljZU5hbWU6IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpbnB1dCA9IHsgZGV2aWNlSWQsIHB1YmxpY0tleSwgcGxhdGZvcm0sIGRldmljZU5hbWUgfTtcbiAgICBhd2FpdCB0aGlzLmdyYXBocWxSZXF1ZXN0KG11dGF0aW9ucy5yZWdpc3RlckRldmljZUtleSwgeyBpbnB1dCB9KTtcbiAgICBsb2dnZXIuaW5mbygnW0FwcFN5bmNDbGllbnRdIERldmljZSBrZXkgcmVnaXN0ZXJlZCcsIHsgZGV2aWNlSWQsIHBsYXRmb3JtIH0pO1xuICB9XG5cbiAgLy8gTUFSSzogLSBBdHRhY2htZW50IE9wZXJhdGlvbnNcblxuICAvKipcbiAgICogR2V0IGF0dGFjaG1lbnQgZG93bmxvYWQgVVJMXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0QXR0YWNobWVudERvd25sb2FkVXJsKHMzS2V5OiBzdHJpbmcpOiBQcm9taXNlPERvd25sb2FkVXJsUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ3JhcGhxbFJlcXVlc3QobXV0YXRpb25zLmdldEF0dGFjaG1lbnREb3dubG9hZFVybCwgeyBzM0tleSB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS5nZXRBdHRhY2htZW50RG93bmxvYWRVcmw7XG4gIH1cblxuICAvLyBNQVJLOiAtIFN1YnNjcmlwdGlvbnNcblxuICAvKipcbiAgICogU3Vic2NyaWJlIHRvIGV2ZW50cyBmb3IgYSBzZXNzaW9uXG4gICAqL1xuICBwdWJsaWMgc3Vic2NyaWJlVG9FdmVudHMoXG4gICAgc2Vzc2lvbklkOiBzdHJpbmcsXG4gICAgb25FdmVudDogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCxcbiAgICBvbkVycm9yPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZFxuICApOiAoKSA9PiB2b2lkIHtcbiAgICBsb2dnZXIuaW5mbygnW0FwcFN5bmNDbGllbnRdIFN1YnNjcmliaW5nIHRvIGV2ZW50cycsIHsgc2Vzc2lvbklkIH0pO1xuXG4gICAgLy8gQ2xlYW51cCBleGlzdGluZyBzdWJzY3JpcHRpb25cbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuYWN0aXZlU3Vic2NyaXB0aW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIHRoaXMuY2xlYW51cFN1YnNjcmlwdGlvblN0YXRlKGV4aXN0aW5nKTtcbiAgICAgIHRoaXMuYWN0aXZlU3Vic2NyaXB0aW9ucy5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGF0ZTogU3Vic2NyaXB0aW9uU3RhdGUgPSB7XG4gICAgICB3czogbnVsbCxcbiAgICAgIHN1YnNjcmlwdGlvbklkOiB1dWlkdjQoKSxcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIG9uRXZlbnQsXG4gICAgICBvbkVycm9yLFxuICAgICAgcmVjb25uZWN0QXR0ZW1wdHM6IDAsXG4gICAgICBpc1JlY29ubmVjdGluZzogZmFsc2UsXG4gICAgfTtcblxuICAgIHRoaXMuYWN0aXZlU3Vic2NyaXB0aW9ucy5zZXQoc2Vzc2lvbklkLCBzdGF0ZSk7XG4gICAgdGhpcy5jcmVhdGVTdWJzY3JpcHRpb24oc3RhdGUpO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHRoaXMuY2xlYW51cFN1YnNjcmlwdGlvblN0YXRlKHN0YXRlKTtcbiAgICAgIHRoaXMuYWN0aXZlU3Vic2NyaXB0aW9ucy5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIFdlYlNvY2tldCBVUkxcbiAgICovXG4gIHByaXZhdGUgYnVpbGRSZWFsdGltZVVybCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIGNvbnN0IHJlYWx0aW1lVXJsID0gY29uZmlnLmF3cy5hcHBzeW5jVXJsXG4gICAgICAucmVwbGFjZSgnaHR0cHM6Ly8nLCAnd3NzOi8vJylcbiAgICAgIC5yZXBsYWNlKCdhcHBzeW5jLWFwaScsICdhcHBzeW5jLXJlYWx0aW1lLWFwaScpO1xuXG4gICAgY29uc3QgYXV0aEhlYWRlcjogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIGhvc3Q6IG5ldyBVUkwoY29uZmlnLmF3cy5hcHBzeW5jVXJsKS5ob3N0LFxuICAgIH07XG5cbiAgICBpZiAodGhpcy50b2tlbnM/LmlkVG9rZW4pIHtcbiAgICAgIGF1dGhIZWFkZXJbJ0F1dGhvcml6YXRpb24nXSA9IHRoaXMudG9rZW5zLmlkVG9rZW47XG4gICAgfVxuXG4gICAgY29uc3QgaGVhZGVyQmFzZTY0ID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoYXV0aEhlYWRlcikpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBjb25zdCBwYXlsb2FkQmFzZTY0ID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoe30pKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cbiAgICByZXR1cm4gYCR7cmVhbHRpbWVVcmx9P2hlYWRlcj0ke2hlYWRlckJhc2U2NH0mcGF5bG9hZD0ke3BheWxvYWRCYXNlNjR9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgV2ViU29ja2V0IHN1YnNjcmlwdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVTdWJzY3JpcHRpb24oc3RhdGU6IFN1YnNjcmlwdGlvblN0YXRlKTogdm9pZCB7XG4gICAgY29uc3QgeyBzZXNzaW9uSWQsIHN1YnNjcmlwdGlvbklkLCBvbkV2ZW50LCBvbkVycm9yIH0gPSBzdGF0ZTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB3c1VybCA9IHRoaXMuYnVpbGRSZWFsdGltZVVybCgpO1xuICAgICAgY29uc3Qgd3MgPSBuZXcgV2ViU29ja2V0KHdzVXJsLCBbJ2dyYXBocWwtd3MnXSk7XG5cbiAgICAgIHdzLm9uKCdvcGVuJywgKCkgPT4ge1xuICAgICAgICBsb2dnZXIuaW5mbygnW0FwcFN5bmNDbGllbnRdIFdlYlNvY2tldCBjb25uZWN0ZWQnLCB7IHNlc3Npb25JZCB9KTtcbiAgICAgICAgd3Muc2VuZChKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdjb25uZWN0aW9uX2luaXQnIH0pKTtcbiAgICAgIH0pO1xuXG4gICAgICB3cy5vbignbWVzc2FnZScsIChkYXRhOiBXZWJTb2NrZXQuRGF0YSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBKU09OLnBhcnNlKGRhdGEudG9TdHJpbmcoKSk7XG5cbiAgICAgICAgICBzd2l0Y2ggKG1lc3NhZ2UudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnY29ubmVjdGlvbl9hY2snOlxuICAgICAgICAgICAgICB0aGlzLnNlbmRTdWJzY3JpcHRpb25TdGFydCh3cywgc3RhdGUpO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnc3RhcnRfYWNrJzpcbiAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1tBcHBTeW5jQ2xpZW50XSBTdWJzY3JpcHRpb24gc3RhcnRlZCcsIHsgc2Vzc2lvbklkIH0pO1xuICAgICAgICAgICAgICBzdGF0ZS5pc1JlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICBzdGF0ZS5yZWNvbm5lY3RBdHRlbXB0cyA9IDA7XG4gICAgICAgICAgICAgIC8vIFJlc3VtZSBoZWFydGJlYXQg4oCUIHN1YnNjcmlwdGlvbiBpcyBhbGl2ZSBhbmQgY2FuIHJlY2VpdmUgbW9iaWxlIGV2ZW50c1xuICAgICAgICAgICAgICB0aGlzLnN0YXJ0SGVhcnRiZWF0KHNlc3Npb25JZCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICdkYXRhJzpcbiAgICAgICAgICAgICAgdGhpcy5yZXNldEtlZXBBbGl2ZVRpbWVyKHN0YXRlKTtcbiAgICAgICAgICAgICAgY29uc3QgZXZlbnQgPSBtZXNzYWdlLnBheWxvYWQ/LmRhdGE/Lm9uRXZlbnRDcmVhdGVkO1xuICAgICAgICAgICAgICBpZiAoZXZlbnQgJiYgZXZlbnQuc291cmNlID09PSBFdmVudFNvdXJjZS5NT0JJTEUpIHtcbiAgICAgICAgICAgICAgICBvbkV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAna2EnOlxuICAgICAgICAgICAgICB0aGlzLnJlc2V0S2VlcEFsaXZlVGltZXIoc3RhdGUpO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IG1lc3NhZ2UucGF5bG9hZD8uZXJyb3JzPy5bMF0/Lm1lc3NhZ2UgfHwgJ1Vua25vd24gZXJyb3InO1xuICAgICAgICAgICAgICB0aGlzLmhhbmRsZVN1YnNjcmlwdGlvbkVycm9yKHN0YXRlLCBuZXcgRXJyb3IoZXJyb3JNc2cpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdbQXBwU3luY0NsaWVudF0gRmFpbGVkIHRvIHBhcnNlIG1lc3NhZ2UnLCB7IGVycm9yOiBlIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgd3Mub24oJ2Vycm9yJywgKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ1tBcHBTeW5jQ2xpZW50XSBXZWJTb2NrZXQgZXJyb3InLCB7IHNlc3Npb25JZCwgZXJyb3I6IGVycm9yLm1lc3NhZ2UgfSk7XG4gICAgICAgIHRoaXMuaGFuZGxlU3Vic2NyaXB0aW9uRXJyb3Ioc3RhdGUsIGVycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgICB3cy5vbignY2xvc2UnLCAoY29kZTogbnVtYmVyLCByZWFzb246IEJ1ZmZlcikgPT4ge1xuICAgICAgICBsb2dnZXIuaW5mbygnW0FwcFN5bmNDbGllbnRdIFdlYlNvY2tldCBjbG9zZWQnLCB7IHNlc3Npb25JZCwgY29kZSB9KTtcbiAgICAgICAgaWYgKHN0YXRlLmtlZXBBbGl2ZVRpbWVyKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHN0YXRlLmtlZXBBbGl2ZVRpbWVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWNvbm5lY3QgaWYgc3Vic2NyaXB0aW9uIGlzIHN0aWxsIGFjdGl2ZSAobm90IGludGVudGlvbmFsbHkgc3RvcHBlZCkuXG4gICAgICAgIC8vIEluY2x1ZGVzIGNvZGUgMTAwMCDigJQgQXBwU3luYyBjbG9zZXMgV2ViU29ja2V0cyBhZnRlciAyNCBob3VycyB3aXRoXG4gICAgICAgIC8vIGNvZGUgMTAwMCwgd2hpY2ggaXMgTk9UIGFuIGludGVudGlvbmFsIHN0b3AgYnkgdGhlIHBsdWdpbi5cbiAgICAgICAgaWYgKHRoaXMuYWN0aXZlU3Vic2NyaXB0aW9ucy5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgICAgIHRoaXMuaGFuZGxlU3Vic2NyaXB0aW9uRXJyb3Ioc3RhdGUsIG5ldyBFcnJvcihgV2ViU29ja2V0IGNsb3NlZDogJHtjb2RlfWApKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHN0YXRlLndzID0gd3M7XG4gICAgICB0aGlzLnJlc2V0S2VlcEFsaXZlVGltZXIoc3RhdGUpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmhhbmRsZVN1YnNjcmlwdGlvbkVycm9yKHN0YXRlLCBlcnJvciBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgc3Vic2NyaXB0aW9uIHN0YXJ0IG1lc3NhZ2VcbiAgICovXG4gIHByaXZhdGUgc2VuZFN1YnNjcmlwdGlvblN0YXJ0KHdzOiBXZWJTb2NrZXQsIHN0YXRlOiBTdWJzY3JpcHRpb25TdGF0ZSk6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldENvbmZpZygpO1xuICAgIGNvbnN0IHsgc2Vzc2lvbklkLCBzdWJzY3JpcHRpb25JZCB9ID0gc3RhdGU7XG5cbiAgICBjb25zdCBhdXRoSGVhZGVyOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgaG9zdDogbmV3IFVSTChjb25maWcuYXdzLmFwcHN5bmNVcmwpLmhvc3QsXG4gICAgfTtcblxuICAgIGlmICh0aGlzLnRva2Vucz8uaWRUb2tlbikge1xuICAgICAgYXV0aEhlYWRlclsnQXV0aG9yaXphdGlvbiddID0gdGhpcy50b2tlbnMuaWRUb2tlbjtcbiAgICB9XG5cbiAgICB3cy5zZW5kKEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGlkOiBzdWJzY3JpcHRpb25JZCxcbiAgICAgIHR5cGU6ICdzdGFydCcsXG4gICAgICBwYXlsb2FkOiB7XG4gICAgICAgIGRhdGE6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBxdWVyeTogc3Vic2NyaXB0aW9ucy5vbkV2ZW50Q3JlYXRlZCxcbiAgICAgICAgICB2YXJpYWJsZXM6IHsgc2Vzc2lvbklkIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBleHRlbnNpb25zOiB7IGF1dGhvcml6YXRpb246IGF1dGhIZWFkZXIgfSxcbiAgICAgIH0sXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IGtlZXAtYWxpdmUgdGltZXJcbiAgICovXG4gIHByaXZhdGUgcmVzZXRLZWVwQWxpdmVUaW1lcihzdGF0ZTogU3Vic2NyaXB0aW9uU3RhdGUpOiB2b2lkIHtcbiAgICBpZiAoc3RhdGUua2VlcEFsaXZlVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dChzdGF0ZS5rZWVwQWxpdmVUaW1lcik7XG4gICAgfVxuICAgIHN0YXRlLmtlZXBBbGl2ZVRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmhhbmRsZVN1YnNjcmlwdGlvbkVycm9yKHN0YXRlLCBuZXcgRXJyb3IoJ0tlZXAtYWxpdmUgdGltZW91dCcpKTtcbiAgICB9LCA1ICogNjAgKiAxMDAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgc3Vic2NyaXB0aW9uIGVycm9yIHdpdGggdHdvLXBoYXNlIHJlY29ubmVjdGlvbjpcbiAgICogUGhhc2UgMSAodXJnZW50KTogRXhwb25lbnRpYWwgYmFja29mZiBmb3IgZmlyc3QgTiBhdHRlbXB0c1xuICAgKiBQaGFzZSAyIChwZXJzaXN0ZW50KTogRml4ZWQgaW50ZXJ2YWwgcmV0cnkgaW5kZWZpbml0ZWx5XG4gICAqL1xuICBwcml2YXRlIGhhbmRsZVN1YnNjcmlwdGlvbkVycm9yKHN0YXRlOiBTdWJzY3JpcHRpb25TdGF0ZSwgZXJyb3I6IEVycm9yKTogdm9pZCB7XG4gICAgY29uc3QgeyBzZXNzaW9uSWQsIG9uRXJyb3IgfSA9IHN0YXRlO1xuXG4gICAgaWYgKHN0YXRlLmlzUmVjb25uZWN0aW5nIHx8ICF0aGlzLmFjdGl2ZVN1YnNjcmlwdGlvbnMuaGFzKHNlc3Npb25JZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzdGF0ZS5pc1JlY29ubmVjdGluZyA9IHRydWU7XG4gICAgc3RhdGUucmVjb25uZWN0QXR0ZW1wdHMrKztcblxuICAgIC8vIFBhdXNlIGhlYXJ0YmVhdCDigJQgc3Vic2NyaXB0aW9uIGlzIGRvd24sIGlPUyBzaG91bGQgbm90IHNob3cgXCJEZXNrdG9wIGNvbm5lY3RlZFwiXG4gICAgdGhpcy5zdG9wSGVhcnRiZWF0KHNlc3Npb25JZCk7XG5cbiAgICBjb25zdCBpc1VyZ2VudFBoYXNlID0gc3RhdGUucmVjb25uZWN0QXR0ZW1wdHMgPD0gUkVDT05ORUNUX0NPTkZJRy51cmdlbnRNYXhBdHRlbXB0cztcblxuICAgIGxldCBkZWxheTogbnVtYmVyO1xuICAgIGlmIChpc1VyZ2VudFBoYXNlKSB7XG4gICAgICBkZWxheSA9IE1hdGgubWluKFxuICAgICAgICBSRUNPTk5FQ1RfQ09ORklHLmJhc2VEZWxheU1zICogTWF0aC5wb3coUkVDT05ORUNUX0NPTkZJRy5iYWNrb2ZmTXVsdGlwbGllciwgc3RhdGUucmVjb25uZWN0QXR0ZW1wdHMgLSAxKSxcbiAgICAgICAgUkVDT05ORUNUX0NPTkZJRy5tYXhEZWxheU1zXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxheSA9IFJFQ09OTkVDVF9DT05GSUcucGVyc2lzdGVudERlbGF5TXM7XG4gICAgICBpZiAoc3RhdGUucmVjb25uZWN0QXR0ZW1wdHMgPT09IFJFQ09OTkVDVF9DT05GSUcudXJnZW50TWF4QXR0ZW1wdHMgKyAxKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdbQXBwU3luY0NsaWVudF0gU3dpdGNoaW5nIHRvIHBlcnNpc3RlbnQgcmVjb25uZWN0IChldmVyeSA1bWluKScsIHsgc2Vzc2lvbklkIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxvZ2dlci5pbmZvKCdbQXBwU3luY0NsaWVudF0gU2NoZWR1bGluZyByZWNvbm5lY3QnLCB7XG4gICAgICBzZXNzaW9uSWQsXG4gICAgICBhdHRlbXB0OiBzdGF0ZS5yZWNvbm5lY3RBdHRlbXB0cyxcbiAgICAgIHBoYXNlOiBpc1VyZ2VudFBoYXNlID8gJ3VyZ2VudCcgOiAncGVyc2lzdGVudCcsXG4gICAgICBkZWxheU1zOiBkZWxheSxcbiAgICB9KTtcblxuICAgIGlmIChzdGF0ZS53cykge1xuICAgICAgdHJ5IHsgc3RhdGUud3MuY2xvc2UoMTAwMCk7IH0gY2F0Y2ggKGUpIHsgLyogaWdub3JlICovIH1cbiAgICAgIHN0YXRlLndzID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUua2VlcEFsaXZlVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dChzdGF0ZS5rZWVwQWxpdmVUaW1lcik7XG4gICAgfVxuXG4gICAgc3RhdGUucmVjb25uZWN0VGltZXIgPSBzZXRUaW1lb3V0KGFzeW5jICgpID0+IHtcbiAgICAgIC8vIFJlc2V0IGZsYWcgc28gbmV4dCBmYWlsdXJlIGNhbiB0cmlnZ2VyIGFub3RoZXIgcmVjb25uZWN0XG4gICAgICBzdGF0ZS5pc1JlY29ubmVjdGluZyA9IGZhbHNlO1xuXG4gICAgICBpZiAoIXRoaXMuYWN0aXZlU3Vic2NyaXB0aW9ucy5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFJlZnJlc2ggdG9rZW5zIGJlZm9yZSByZWNvbm5lY3Rpbmcg4oCUIHRoZXkgbWF5IGhhdmUgZXhwaXJlZFxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZnJlc2hUb2tlbnMgPSBhd2FpdCBrZXljaGFpbk1hbmFnZXIuZ2V0VG9rZW5zKHRoaXMuZW52aXJvbm1lbnQpO1xuICAgICAgICBpZiAoZnJlc2hUb2tlbnMpIHtcbiAgICAgICAgICBpZiAoa2V5Y2hhaW5NYW5hZ2VyLmlzVG9rZW5FeHBpcmVkKGZyZXNoVG9rZW5zKSkge1xuICAgICAgICAgICAgY29uc3QgcmVmcmVzaGVkID0gYXdhaXQgdGhpcy5yZWZyZXNoVG9rZW5zKGZyZXNoVG9rZW5zKTtcbiAgICAgICAgICAgIGlmIChyZWZyZXNoZWQpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1tBcHBTeW5jQ2xpZW50XSBUb2tlbnMgcmVmcmVzaGVkIGJlZm9yZSByZWNvbm5lY3QnLCB7IHNlc3Npb25JZCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy50b2tlbnMgPSBmcmVzaFRva2VucztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1tBcHBTeW5jQ2xpZW50XSBUb2tlbiByZWZyZXNoIGZhaWxlZCBiZWZvcmUgcmVjb25uZWN0LCB1c2luZyBleGlzdGluZyB0b2tlbnMnLCB7IHNlc3Npb25JZCB9KTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUuc3Vic2NyaXB0aW9uSWQgPSB1dWlkdjQoKTtcbiAgICAgIHRoaXMuY3JlYXRlU3Vic2NyaXB0aW9uKHN0YXRlKTtcbiAgICB9LCBkZWxheSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW51cCBzdWJzY3JpcHRpb24gc3RhdGVcbiAgICovXG4gIHByaXZhdGUgY2xlYW51cFN1YnNjcmlwdGlvblN0YXRlKHN0YXRlOiBTdWJzY3JpcHRpb25TdGF0ZSk6IHZvaWQge1xuICAgIGlmIChzdGF0ZS5yZWNvbm5lY3RUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHN0YXRlLnJlY29ubmVjdFRpbWVyKTtcbiAgICB9XG4gICAgaWYgKHN0YXRlLmtlZXBBbGl2ZVRpbWVyKSB7XG4gICAgICBjbGVhclRpbWVvdXQoc3RhdGUua2VlcEFsaXZlVGltZXIpO1xuICAgIH1cbiAgICBpZiAoc3RhdGUud3MpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChzdGF0ZS53cy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgICAgIHN0YXRlLndzLnNlbmQoSlNPTi5zdHJpbmdpZnkoeyBpZDogc3RhdGUuc3Vic2NyaXB0aW9uSWQsIHR5cGU6ICdzdG9wJyB9KSk7XG4gICAgICAgICAgc3RhdGUud3MuY2xvc2UoMTAwMCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHsgLyogaWdub3JlICovIH1cbiAgICAgIHN0YXRlLndzID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvLyBNQVJLOiAtIEhlYXJ0YmVhdFxuXG4gIHByaXZhdGUgaGVhcnRiZWF0VGltZXJzOiBNYXA8c3RyaW5nLCBOb2RlSlMuVGltZW91dD4gPSBuZXcgTWFwKCk7XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHBlcmlvZGljIGhlYXJ0YmVhdCBmb3IgYSBzZXNzaW9uLlxuICAgKiBVcGRhdGVzIGxhc3RIZWFydGJlYXRBdCBvbiB0aGUgc2Vzc2lvbiBldmVyeSBpbnRlcnZhbE1zIChkZWZhdWx0IDIgbWludXRlcykuXG4gICAqL1xuICBwdWJsaWMgc3RhcnRIZWFydGJlYXQoc2Vzc2lvbklkOiBzdHJpbmcsIGludGVydmFsTXM6IG51bWJlciA9IDIgKiA2MCAqIDEwMDApOiB2b2lkIHtcbiAgICB0aGlzLnN0b3BIZWFydGJlYXQoc2Vzc2lvbklkKTtcblxuICAgIC8vIFNlbmQgaW5pdGlhbCBoZWFydGJlYXQgaW1tZWRpYXRlbHlcbiAgICB0aGlzLnNlbmRIZWFydGJlYXQoc2Vzc2lvbklkKTtcblxuICAgIGNvbnN0IHRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdGhpcy5zZW5kSGVhcnRiZWF0KHNlc3Npb25JZCk7XG4gICAgfSwgaW50ZXJ2YWxNcyk7XG5cbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVycy5zZXQoc2Vzc2lvbklkLCB0aW1lcik7XG4gICAgbG9nZ2VyLmluZm8oJ1tBcHBTeW5jQ2xpZW50XSBIZWFydGJlYXQgc3RhcnRlZCcsIHsgc2Vzc2lvbklkLCBpbnRlcnZhbE1zIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0b3AgaGVhcnRiZWF0IGZvciBhIHNlc3Npb24uXG4gICAqL1xuICBwdWJsaWMgc3RvcEhlYXJ0YmVhdChzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHRpbWVyID0gdGhpcy5oZWFydGJlYXRUaW1lcnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgaWYgKHRpbWVyKSB7XG4gICAgICBjbGVhckludGVydmFsKHRpbWVyKTtcbiAgICAgIHRoaXMuaGVhcnRiZWF0VGltZXJzLmRlbGV0ZShzZXNzaW9uSWQpO1xuICAgICAgbG9nZ2VyLmluZm8oJ1tBcHBTeW5jQ2xpZW50XSBIZWFydGJlYXQgc3RvcHBlZCcsIHsgc2Vzc2lvbklkIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kIGEgc2luZ2xlIGhlYXJ0YmVhdCB1cGRhdGUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNlbmRIZWFydGJlYXQoc2Vzc2lvbklkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy51cGRhdGVTZXNzaW9uKHtcbiAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICBsYXN0SGVhcnRiZWF0QXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIH0pO1xuICAgICAgbG9nZ2VyLmRlYnVnKCdbQXBwU3luY0NsaWVudF0gSGVhcnRiZWF0IHNlbnQnLCB7IHNlc3Npb25JZCB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oJ1tBcHBTeW5jQ2xpZW50XSBIZWFydGJlYXQgZmFpbGVkJywgeyBzZXNzaW9uSWQsIGVycm9yIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbnVwIGFsbCBzdWJzY3JpcHRpb25zIGFuZCBoZWFydGJlYXRzXG4gICAqL1xuICBwdWJsaWMgY2xlYW51cFN1YnNjcmlwdGlvbnMoKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmVTdWJzY3JpcHRpb25zLmZvckVhY2goKHN0YXRlKSA9PiB7XG4gICAgICB0aGlzLmNsZWFudXBTdWJzY3JpcHRpb25TdGF0ZShzdGF0ZSk7XG4gICAgfSk7XG4gICAgdGhpcy5hY3RpdmVTdWJzY3JpcHRpb25zLmNsZWFyKCk7XG5cbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVycy5mb3JFYWNoKCh0aW1lcikgPT4gY2xlYXJJbnRlcnZhbCh0aW1lcikpO1xuICAgIHRoaXMuaGVhcnRiZWF0VGltZXJzLmNsZWFyKCk7XG4gIH1cbn1cbiJdfQ==