@hanseltime/template-repo-sync 2.3.0 → 2.4.0-alpha.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 (295) hide show
  1. package/CHANGELOG.md +37 -46
  2. package/dist/cjs/checkout-drivers/git-checkout.js +37 -0
  3. package/dist/cjs/checkout-drivers/git-checkout.spec.js +60 -0
  4. package/dist/cjs/checkout-drivers/index.js +21 -0
  5. package/dist/cjs/checkout-drivers/types.js +11 -0
  6. package/dist/cjs/clone-drivers/git-clone.js +25 -0
  7. package/dist/cjs/clone-drivers/index.js +21 -0
  8. package/dist/cjs/clone-drivers/types.js +8 -0
  9. package/dist/cjs/diff-drivers/git-diff.js +30 -0
  10. package/dist/cjs/diff-drivers/git-diff.spec.js +138 -0
  11. package/dist/cjs/diff-drivers/index.js +21 -0
  12. package/dist/cjs/diff-drivers/types.js +6 -0
  13. package/dist/cjs/formatting/index.js +21 -0
  14. package/dist/cjs/formatting/infer-json-indent.js +26 -0
  15. package/dist/cjs/formatting/infer-json-indent.spec.js +50 -0
  16. package/dist/cjs/formatting/sync-results-to-md.js +62 -0
  17. package/dist/cjs/formatting/sync-results-to-md.spec.js +45 -0
  18. package/dist/cjs/index.js +22 -0
  19. package/dist/cjs/load-plugin.js +44 -0
  20. package/dist/cjs/match.js +51 -0
  21. package/dist/cjs/match.spec.js +75 -0
  22. package/dist/cjs/merge-file.js +91 -0
  23. package/dist/cjs/merge-file.spec.js +508 -0
  24. package/dist/cjs/plugins/index.js +20 -0
  25. package/dist/cjs/plugins/json-merge.js +228 -0
  26. package/dist/cjs/plugins/json-merge.spec.js +514 -0
  27. package/dist/cjs/ref-drivers/git-current-ref.js +18 -0
  28. package/dist/cjs/ref-drivers/git-current-ref.spec.js +15 -0
  29. package/dist/cjs/ref-drivers/index.js +20 -0
  30. package/dist/cjs/ref-drivers/types.js +11 -0
  31. package/dist/cjs/template-sync.js +236 -0
  32. package/dist/cjs/template-sync.spec.js +521 -0
  33. package/dist/cjs/test-utils/index.js +26 -0
  34. package/dist/cjs/types.js +12 -0
  35. package/dist/esm/checkout-drivers/git-checkout.mjs +27 -0
  36. package/dist/esm/checkout-drivers/git-checkout.spec.mjs +56 -0
  37. package/dist/esm/checkout-drivers/index.mjs +4 -0
  38. package/dist/esm/checkout-drivers/types.mjs +8 -0
  39. package/dist/esm/clone-drivers/git-clone.mjs +15 -0
  40. package/dist/esm/clone-drivers/index.mjs +4 -0
  41. package/dist/esm/clone-drivers/types.mjs +8 -0
  42. package/dist/esm/diff-drivers/git-diff.mjs +26 -0
  43. package/dist/esm/diff-drivers/git-diff.spec.mjs +93 -0
  44. package/dist/esm/diff-drivers/index.mjs +4 -0
  45. package/dist/esm/diff-drivers/types.mjs +6 -0
  46. package/dist/esm/formatting/index.mjs +4 -0
  47. package/dist/esm/formatting/infer-json-indent.mjs +16 -0
  48. package/dist/esm/formatting/infer-json-indent.spec.mjs +46 -0
  49. package/dist/esm/formatting/sync-results-to-md.mjs +52 -0
  50. package/dist/esm/formatting/sync-results-to-md.spec.mjs +41 -0
  51. package/dist/esm/index.mjs +5 -0
  52. package/dist/esm/load-plugin.mjs +40 -0
  53. package/dist/esm/match.mjs +40 -0
  54. package/dist/esm/match.spec.mjs +71 -0
  55. package/dist/esm/merge-file.mjs +88 -0
  56. package/dist/esm/merge-file.spec.mjs +504 -0
  57. package/dist/esm/plugins/index.mjs +10 -0
  58. package/dist/esm/plugins/json-merge.mjs +164 -0
  59. package/dist/esm/plugins/json-merge.spec.mjs +469 -0
  60. package/dist/esm/ref-drivers/git-current-ref.mjs +8 -0
  61. package/dist/esm/ref-drivers/git-current-ref.spec.mjs +11 -0
  62. package/dist/esm/ref-drivers/index.mjs +3 -0
  63. package/dist/esm/ref-drivers/types.mjs +8 -0
  64. package/dist/esm/template-sync.mjs +174 -0
  65. package/dist/esm/template-sync.spec.mjs +517 -0
  66. package/dist/esm/test-utils/index.mjs +10 -0
  67. package/dist/esm/types.mjs +9 -0
  68. package/{lib/cjs → dist/types}/checkout-drivers/git-checkout.d.ts +1 -0
  69. package/dist/types/checkout-drivers/git-checkout.d.ts.map +1 -0
  70. package/dist/types/checkout-drivers/git-checkout.spec.d.ts +2 -0
  71. package/dist/types/checkout-drivers/git-checkout.spec.d.ts.map +1 -0
  72. package/{lib/cjs → dist/types}/checkout-drivers/index.d.ts +1 -0
  73. package/dist/types/checkout-drivers/index.d.ts.map +1 -0
  74. package/{lib/cjs → dist/types}/checkout-drivers/types.d.ts +1 -0
  75. package/dist/types/checkout-drivers/types.d.ts.map +1 -0
  76. package/{lib/cjs → dist/types}/clone-drivers/git-clone.d.ts +2 -1
  77. package/dist/types/clone-drivers/git-clone.d.ts.map +1 -0
  78. package/{lib/cjs → dist/types}/clone-drivers/index.d.ts +2 -1
  79. package/dist/types/clone-drivers/index.d.ts.map +1 -0
  80. package/{lib/cjs → dist/types}/clone-drivers/types.d.ts +1 -0
  81. package/dist/types/clone-drivers/types.d.ts.map +1 -0
  82. package/{lib/cjs → dist/types}/diff-drivers/git-diff.d.ts +1 -0
  83. package/dist/types/diff-drivers/git-diff.d.ts.map +1 -0
  84. package/dist/types/diff-drivers/git-diff.spec.d.ts +2 -0
  85. package/dist/types/diff-drivers/git-diff.spec.d.ts.map +1 -0
  86. package/{lib/cjs → dist/types}/diff-drivers/index.d.ts +2 -1
  87. package/dist/types/diff-drivers/index.d.ts.map +1 -0
  88. package/{lib/cjs → dist/types}/diff-drivers/types.d.ts +1 -0
  89. package/dist/types/diff-drivers/types.d.ts.map +1 -0
  90. package/{lib/cjs → dist/types}/formatting/index.d.ts +2 -1
  91. package/dist/types/formatting/index.d.ts.map +1 -0
  92. package/{lib/cjs → dist/types}/formatting/infer-json-indent.d.ts +1 -0
  93. package/dist/types/formatting/infer-json-indent.d.ts.map +1 -0
  94. package/dist/types/formatting/infer-json-indent.spec.d.ts +2 -0
  95. package/dist/types/formatting/infer-json-indent.spec.d.ts.map +1 -0
  96. package/dist/types/formatting/sync-results-to-md.d.ts +3 -0
  97. package/dist/types/formatting/sync-results-to-md.d.ts.map +1 -0
  98. package/dist/types/formatting/sync-results-to-md.spec.d.ts +2 -0
  99. package/dist/types/formatting/sync-results-to-md.spec.d.ts.map +1 -0
  100. package/{lib/cjs → dist/types}/index.d.ts +3 -2
  101. package/dist/types/index.d.ts.map +1 -0
  102. package/{lib/cjs → dist/types}/load-plugin.d.ts +2 -1
  103. package/dist/types/load-plugin.d.ts.map +1 -0
  104. package/{lib/cjs → dist/types}/match.d.ts +1 -0
  105. package/dist/types/match.d.ts.map +1 -0
  106. package/dist/types/match.spec.d.ts +2 -0
  107. package/dist/types/match.spec.d.ts.map +1 -0
  108. package/{lib/cjs → dist/types}/merge-file.d.ts +3 -2
  109. package/dist/types/merge-file.d.ts.map +1 -0
  110. package/dist/types/merge-file.spec.d.ts +2 -0
  111. package/dist/types/merge-file.spec.d.ts.map +1 -0
  112. package/{lib/cjs → dist/types}/plugins/index.d.ts +2 -1
  113. package/dist/types/plugins/index.d.ts.map +1 -0
  114. package/{lib/cjs → dist/types}/plugins/json-merge.d.ts +2 -1
  115. package/dist/types/plugins/json-merge.d.ts.map +1 -0
  116. package/dist/types/plugins/json-merge.spec.d.ts +2 -0
  117. package/dist/types/plugins/json-merge.spec.d.ts.map +1 -0
  118. package/{lib/cjs → dist/types}/ref-drivers/git-current-ref.d.ts +1 -0
  119. package/dist/types/ref-drivers/git-current-ref.d.ts.map +1 -0
  120. package/dist/types/ref-drivers/git-current-ref.spec.d.ts +2 -0
  121. package/dist/types/ref-drivers/git-current-ref.spec.d.ts.map +1 -0
  122. package/{lib/cjs → dist/types}/ref-drivers/index.d.ts +1 -0
  123. package/dist/types/ref-drivers/index.d.ts.map +1 -0
  124. package/{lib/cjs → dist/types}/ref-drivers/types.d.ts +1 -0
  125. package/dist/types/ref-drivers/types.d.ts.map +1 -0
  126. package/{lib/cjs → dist/types}/template-sync.d.ts +6 -5
  127. package/dist/types/template-sync.d.ts.map +1 -0
  128. package/dist/types/template-sync.spec.d.ts +2 -0
  129. package/dist/types/template-sync.spec.d.ts.map +1 -0
  130. package/{lib/cjs → dist/types}/test-utils/index.d.ts +1 -0
  131. package/dist/types/test-utils/index.d.ts.map +1 -0
  132. package/{lib/cjs → dist/types}/types.d.ts +1 -0
  133. package/dist/types/types.d.ts.map +1 -0
  134. package/package.json +26 -23
  135. package/.eslintrc.js +0 -10
  136. package/.github/CODEOWNERS +0 -6
  137. package/.github/workflows/pr-checks.yaml +0 -12
  138. package/.github/workflows/release.yaml +0 -47
  139. package/.github/workflows/test-flow.yaml +0 -63
  140. package/.husky/commit-msg +0 -4
  141. package/.prettierignore +0 -1
  142. package/.prettierrc +0 -1
  143. package/action.yml +0 -13
  144. package/commitlint.config.js +0 -3
  145. package/docs/merge-plugins/CURRENT_PLUGINS.md +0 -168
  146. package/docs/merge-plugins/PLUGIN_DEVELOPMENT.md +0 -122
  147. package/docs/merge-plugins/README.md +0 -75
  148. package/jest.config.js +0 -19
  149. package/lib/cjs/checkout-drivers/git-checkout.js +0 -29
  150. package/lib/cjs/checkout-drivers/index.js +0 -18
  151. package/lib/cjs/checkout-drivers/types.js +0 -2
  152. package/lib/cjs/clone-drivers/git-clone.js +0 -17
  153. package/lib/cjs/clone-drivers/index.js +0 -18
  154. package/lib/cjs/clone-drivers/types.js +0 -2
  155. package/lib/cjs/diff-drivers/git-diff.js +0 -41
  156. package/lib/cjs/diff-drivers/index.js +0 -18
  157. package/lib/cjs/diff-drivers/types.js +0 -2
  158. package/lib/cjs/formatting/index.js +0 -18
  159. package/lib/cjs/formatting/infer-json-indent.js +0 -18
  160. package/lib/cjs/formatting/sync-results-to-md.d.ts +0 -2
  161. package/lib/cjs/formatting/sync-results-to-md.js +0 -57
  162. package/lib/cjs/index.js +0 -19
  163. package/lib/cjs/load-plugin.js +0 -69
  164. package/lib/cjs/match.js +0 -45
  165. package/lib/cjs/merge-file.js +0 -98
  166. package/lib/cjs/plugins/index.js +0 -11
  167. package/lib/cjs/plugins/json-merge.js +0 -208
  168. package/lib/cjs/ref-drivers/git-current-ref.js +0 -12
  169. package/lib/cjs/ref-drivers/index.js +0 -17
  170. package/lib/cjs/ref-drivers/types.js +0 -2
  171. package/lib/cjs/template-sync.js +0 -204
  172. package/lib/cjs/test-utils/index.js +0 -10
  173. package/lib/cjs/types.js +0 -2
  174. package/lib/esm/checkout-drivers/git-checkout.js +0 -29
  175. package/lib/esm/checkout-drivers/index.js +0 -18
  176. package/lib/esm/checkout-drivers/types.js +0 -2
  177. package/lib/esm/clone-drivers/git-clone.js +0 -17
  178. package/lib/esm/clone-drivers/index.js +0 -18
  179. package/lib/esm/clone-drivers/types.js +0 -2
  180. package/lib/esm/diff-drivers/git-diff.js +0 -41
  181. package/lib/esm/diff-drivers/index.js +0 -18
  182. package/lib/esm/diff-drivers/types.js +0 -2
  183. package/lib/esm/formatting/index.js +0 -18
  184. package/lib/esm/formatting/infer-json-indent.js +0 -18
  185. package/lib/esm/formatting/sync-results-to-md.js +0 -57
  186. package/lib/esm/index.js +0 -19
  187. package/lib/esm/load-plugin.js +0 -46
  188. package/lib/esm/match.js +0 -45
  189. package/lib/esm/merge-file.js +0 -98
  190. package/lib/esm/plugins/index.js +0 -11
  191. package/lib/esm/plugins/json-merge.js +0 -208
  192. package/lib/esm/ref-drivers/git-current-ref.js +0 -12
  193. package/lib/esm/ref-drivers/index.js +0 -17
  194. package/lib/esm/ref-drivers/types.js +0 -2
  195. package/lib/esm/template-sync.js +0 -204
  196. package/lib/esm/test-utils/index.js +0 -10
  197. package/lib/esm/types.js +0 -2
  198. package/release.config.js +0 -40
  199. package/src/checkout-drivers/git-checkout.spec.ts +0 -69
  200. package/src/checkout-drivers/git-checkout.ts +0 -38
  201. package/src/checkout-drivers/index.ts +0 -2
  202. package/src/checkout-drivers/types.ts +0 -14
  203. package/src/clone-drivers/git-clone.ts +0 -20
  204. package/src/clone-drivers/index.ts +0 -2
  205. package/src/clone-drivers/types.ts +0 -20
  206. package/src/diff-drivers/git-diff.spec.ts +0 -73
  207. package/src/diff-drivers/git-diff.ts +0 -39
  208. package/src/diff-drivers/index.ts +0 -2
  209. package/src/diff-drivers/types.ts +0 -14
  210. package/src/formatting/__snapshots__/sync-results-to-md.spec.ts.snap +0 -39
  211. package/src/formatting/index.ts +0 -2
  212. package/src/formatting/infer-json-indent.spec.ts +0 -49
  213. package/src/formatting/infer-json-indent.ts +0 -16
  214. package/src/formatting/sync-results-to-md.spec.ts +0 -31
  215. package/src/formatting/sync-results-to-md.ts +0 -63
  216. package/src/index.ts +0 -3
  217. package/src/load-plugin.ts +0 -51
  218. package/src/match.spec.ts +0 -68
  219. package/src/match.ts +0 -52
  220. package/src/merge-file.spec.ts +0 -506
  221. package/src/merge-file.ts +0 -154
  222. package/src/plugins/index.ts +0 -12
  223. package/src/plugins/json-merge.spec.ts +0 -436
  224. package/src/plugins/json-merge.ts +0 -215
  225. package/src/ref-drivers/git-current-ref.spec.ts +0 -12
  226. package/src/ref-drivers/git-current-ref.ts +0 -9
  227. package/src/ref-drivers/index.ts +0 -1
  228. package/src/ref-drivers/types.ts +0 -10
  229. package/src/template-sync.spec.ts +0 -602
  230. package/src/template-sync.ts +0 -304
  231. package/src/test-utils/index.ts +0 -13
  232. package/src/types.ts +0 -129
  233. package/templatesync.local.json +0 -15
  234. package/test-fixtures/downstream/README.md +0 -3
  235. package/test-fixtures/downstream/package.json +0 -18
  236. package/test-fixtures/downstream/plugins/custom-plugin.js +0 -14
  237. package/test-fixtures/downstream/plugins/fail-validate-plugin.js +0 -14
  238. package/test-fixtures/downstream/src/index.js +0 -2
  239. package/test-fixtures/downstream/src/index.ts +0 -1
  240. package/test-fixtures/downstream/src/templated.js +0 -2
  241. package/test-fixtures/downstream/src/templated.ts +0 -1
  242. package/test-fixtures/downstream/templatesync.json +0 -16
  243. package/test-fixtures/downstream/templatesync.local.json +0 -10
  244. package/test-fixtures/dummy-plugin.js +0 -8
  245. package/test-fixtures/glob-test/folder1/something.js +0 -1
  246. package/test-fixtures/glob-test/folder1/something.ts +0 -0
  247. package/test-fixtures/glob-test/toplevel.js +0 -0
  248. package/test-fixtures/glob-test/toplevel.txt +0 -0
  249. package/test-fixtures/template/custom-bin/something.txt +0 -1
  250. package/test-fixtures/template/dummy-fail-plugin.js +0 -8
  251. package/test-fixtures/template/package.json +0 -17
  252. package/test-fixtures/template/src/index.js +0 -2
  253. package/test-fixtures/template/src/index.ts +0 -1
  254. package/test-fixtures/template/src/templated.js +0 -2
  255. package/test-fixtures/template/src/templated.ts +0 -1
  256. package/test-fixtures/template/templatesync.json +0 -16
  257. package/test-fixtures/testGitRepo/README.md +0 -17
  258. package/test-fixtures/testGitRepo/gitDir/COMMIT_EDITMSG +0 -14
  259. package/test-fixtures/testGitRepo/gitDir/HEAD +0 -1
  260. package/test-fixtures/testGitRepo/gitDir/config +0 -7
  261. package/test-fixtures/testGitRepo/gitDir/description +0 -1
  262. package/test-fixtures/testGitRepo/gitDir/hooks/applypatch-msg.sample +0 -15
  263. package/test-fixtures/testGitRepo/gitDir/hooks/commit-msg.sample +0 -24
  264. package/test-fixtures/testGitRepo/gitDir/hooks/fsmonitor-watchman.sample +0 -174
  265. package/test-fixtures/testGitRepo/gitDir/hooks/post-update.sample +0 -8
  266. package/test-fixtures/testGitRepo/gitDir/hooks/pre-applypatch.sample +0 -14
  267. package/test-fixtures/testGitRepo/gitDir/hooks/pre-commit.sample +0 -49
  268. package/test-fixtures/testGitRepo/gitDir/hooks/pre-merge-commit.sample +0 -13
  269. package/test-fixtures/testGitRepo/gitDir/hooks/pre-push.sample +0 -53
  270. package/test-fixtures/testGitRepo/gitDir/hooks/pre-rebase.sample +0 -169
  271. package/test-fixtures/testGitRepo/gitDir/hooks/pre-receive.sample +0 -24
  272. package/test-fixtures/testGitRepo/gitDir/hooks/prepare-commit-msg.sample +0 -42
  273. package/test-fixtures/testGitRepo/gitDir/hooks/push-to-checkout.sample +0 -78
  274. package/test-fixtures/testGitRepo/gitDir/hooks/sendemail-validate.sample +0 -77
  275. package/test-fixtures/testGitRepo/gitDir/hooks/update.sample +0 -128
  276. package/test-fixtures/testGitRepo/gitDir/index +0 -0
  277. package/test-fixtures/testGitRepo/gitDir/info/exclude +0 -6
  278. package/test-fixtures/testGitRepo/gitDir/logs/HEAD +0 -5
  279. package/test-fixtures/testGitRepo/gitDir/logs/refs/heads/master +0 -2
  280. package/test-fixtures/testGitRepo/gitDir/logs/refs/heads/test-branch +0 -2
  281. package/test-fixtures/testGitRepo/gitDir/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  282. package/test-fixtures/testGitRepo/gitDir/objects/6e/187bee8d02f39d0a1be8331dd8fe6a00c9b613 +0 -0
  283. package/test-fixtures/testGitRepo/gitDir/objects/73/185f1f3f5a6345e087d9f46dc4af77cc59449f +0 -2
  284. package/test-fixtures/testGitRepo/gitDir/objects/90/e7ea1089f939840e9649fd617584c1ad117159 +0 -3
  285. package/test-fixtures/testGitRepo/gitDir/objects/ba/99a452b9097047e9bfa8d5a08b3e452fcb364a +0 -0
  286. package/test-fixtures/testGitRepo/gitDir/objects/c5/8d400177cd5180b8566f82a127fafc5bf394b7 +0 -0
  287. package/test-fixtures/testGitRepo/gitDir/objects/e2/e668265db019249a7e8296d85f79000e3d71cf +0 -0
  288. package/test-fixtures/testGitRepo/gitDir/objects/e4/243e430c1ab69f3e344249f5b1859e90abc883 +0 -1
  289. package/test-fixtures/testGitRepo/gitDir/objects/ec/6c1cb72312605282ac61858cf1eaf1ea9f1d02 +0 -0
  290. package/test-fixtures/testGitRepo/gitDir/objects/fc/89cecc4ac0b5b075bd7d0ce9e09b2f50598b82 +0 -0
  291. package/test-fixtures/testGitRepo/gitDir/refs/heads/master +0 -1
  292. package/test-fixtures/testGitRepo/gitDir/refs/heads/test-branch +0 -1
  293. package/tsconfig.cjs.json +0 -12
  294. package/tsconfig.esm.json +0 -10
  295. package/tsconfig.json +0 -22
@@ -0,0 +1,521 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _fs = require("fs");
6
+ const _promises = require("fs/promises");
7
+ const _fsextra = require("fs-extra");
8
+ const _path = require("path");
9
+ const _templatesync = require("./template-sync");
10
+ const _testutils = require("./test-utils");
11
+ const dummyCheckoutDriver = jest.fn();
12
+ const dummyCurrentRefDriver = jest.fn();
13
+ const downstreamDir = (0, _path.resolve)(_testutils.TEST_FIXTURES_DIR, "downstream");
14
+ describe("templateSync", ()=>{
15
+ let tmpDir;
16
+ let templateDir;
17
+ let dummyCloneDriver;
18
+ beforeEach(async ()=>{
19
+ jest.resetAllMocks();
20
+ tmpDir = await (0, _promises.mkdtemp)((0, _testutils.tempDir)());
21
+ templateDir = await (0, _promises.mkdtemp)((0, _testutils.tempDir)());
22
+ await (0, _fsextra.copy)((0, _path.resolve)(_testutils.TEST_FIXTURES_DIR, "template"), templateDir);
23
+ await (0, _fsextra.copy)(downstreamDir, tmpDir);
24
+ dummyCloneDriver = async ()=>{
25
+ return {
26
+ dir: templateDir,
27
+ remoteName: "ourRemote"
28
+ };
29
+ };
30
+ });
31
+ afterEach(async ()=>{
32
+ await (0, _promises.rm)(tmpDir, {
33
+ force: true,
34
+ recursive: true
35
+ });
36
+ });
37
+ // Note: for this test, we expect actions and users to handle misconfigured template syncs
38
+ it.each([
39
+ [
40
+ "local",
41
+ `templatesync.local.json plugin option errors:
42
+ \tPlugin (plugins/fail-validate-plugin.js):
43
+ \t\toh no!
44
+ \t\tnot this one too!
45
+ `
46
+ ],
47
+ [
48
+ "template",
49
+ `templatesync.json plugin option errors:
50
+ \tPlugin (dummy-fail-plugin.js):
51
+ \t\tshucks
52
+ \t\tno good
53
+ `
54
+ ],
55
+ [
56
+ "both",
57
+ `templatesync.json plugin option errors:
58
+ \tPlugin (dummy-fail-plugin.js):
59
+ \t\tshucks
60
+ \t\tno good
61
+ templatesync.local.json plugin option errors:
62
+ \tPlugin (plugins/fail-validate-plugin.js):
63
+ \t\toh no!
64
+ \t\tnot this one too!
65
+ `
66
+ ]
67
+ ])("throws errors from plugin validation", async (mode, expected)=>{
68
+ // Remove the local sync overrides
69
+ await (0, _promises.rm)((0, _path.join)(tmpDir, "templatesync.local.json"));
70
+ if (mode === "local" || mode == "both") {
71
+ (0, _fs.writeFileSync)((0, _path.join)(tmpDir, "templatesync.local.json"), JSON.stringify({
72
+ ignore: [
73
+ // Ignores the templated.ts
74
+ "**/*.ts",
75
+ // We don't have a need for this in here, but it's an example of keeping things cleaner for our custom plugins
76
+ "plugins/**"
77
+ ],
78
+ merge: [
79
+ {
80
+ glob: "package.json",
81
+ plugin: "plugins/fail-validate-plugin.js",
82
+ options: {}
83
+ }
84
+ ]
85
+ }));
86
+ }
87
+ if (mode === "template" || mode === "both") {
88
+ (0, _fs.writeFileSync)((0, _path.join)(templateDir, "templatesync.json"), JSON.stringify({
89
+ ignore: [
90
+ // Ignores the templated.ts
91
+ "**/*.ts",
92
+ // We don't have a need for this in here, but it's an example of keeping things cleaner for our custom plugins
93
+ "plugins/**"
94
+ ],
95
+ merge: [
96
+ {
97
+ glob: "package.json",
98
+ plugin: "dummy-fail-plugin.js",
99
+ options: {}
100
+ }
101
+ ]
102
+ }));
103
+ }
104
+ await expect(async ()=>await (0, _templatesync.templateSync)({
105
+ tmpCloneDir: "stubbed-by-driver",
106
+ cloneDriver: dummyCloneDriver,
107
+ repoUrl: "not-important",
108
+ repoDir: tmpDir,
109
+ checkoutDriver: dummyCheckoutDriver,
110
+ currentRefDriver: dummyCurrentRefDriver
111
+ })).rejects.toThrow(expected);
112
+ });
113
+ it("appropriately merges according to just the templatesync config file into an empty dir", async ()=>{
114
+ const emptyTmpDir = await (0, _promises.mkdtemp)((0, _testutils.tempDir)());
115
+ expect(await (0, _templatesync.templateSync)({
116
+ tmpCloneDir: "stubbed-by-driver",
117
+ cloneDriver: dummyCloneDriver,
118
+ repoUrl: "not-important",
119
+ repoDir: emptyTmpDir,
120
+ checkoutDriver: dummyCheckoutDriver,
121
+ currentRefDriver: dummyCurrentRefDriver
122
+ })).toEqual({
123
+ // Expect no changes since there was no local sync file
124
+ localSkipFiles: [],
125
+ localFileChanges: {},
126
+ modifiedFiles: {
127
+ added: [
128
+ "package.json",
129
+ "src/index.js",
130
+ "src/templated.js",
131
+ "src/templated.ts",
132
+ "templatesync.json"
133
+ ],
134
+ deleted: [],
135
+ modified: [],
136
+ total: 5
137
+ }
138
+ });
139
+ // Verify the files
140
+ await fileMatchTemplate(emptyTmpDir, "templatesync.json");
141
+ await fileMatchTemplate(emptyTmpDir, "package.json");
142
+ await fileMatchTemplate(emptyTmpDir, "src/templated.ts");
143
+ // Expect the ignores to not be a problem
144
+ expect((0, _fs.existsSync)((0, _path.resolve)(emptyTmpDir, "src/index.ts"))).toBeFalsy();
145
+ expect((0, _fs.existsSync)((0, _path.resolve)(emptyTmpDir, "src/custom-bin"))).toBeFalsy();
146
+ expect(dummyCheckoutDriver).not.toHaveBeenCalled();
147
+ });
148
+ it("Checks out the branch and then appropriately merges", async ()=>{
149
+ const emptyTmpDir = await (0, _promises.mkdtemp)((0, _testutils.tempDir)());
150
+ expect(await (0, _templatesync.templateSync)({
151
+ tmpCloneDir: "stubbed-by-driver",
152
+ cloneDriver: dummyCloneDriver,
153
+ repoUrl: "not-important",
154
+ repoDir: emptyTmpDir,
155
+ branch: "new-template-test",
156
+ checkoutDriver: dummyCheckoutDriver,
157
+ currentRefDriver: dummyCurrentRefDriver
158
+ })).toEqual({
159
+ // Expect no changes since there was no local sync file
160
+ localSkipFiles: [],
161
+ localFileChanges: {},
162
+ modifiedFiles: {
163
+ added: [
164
+ "package.json",
165
+ "src/index.js",
166
+ "src/templated.js",
167
+ "src/templated.ts",
168
+ "templatesync.json"
169
+ ],
170
+ deleted: [],
171
+ modified: [],
172
+ total: 5
173
+ }
174
+ });
175
+ // Verify the files
176
+ await fileMatchTemplate(emptyTmpDir, "templatesync.json");
177
+ await fileMatchTemplate(emptyTmpDir, "package.json");
178
+ await fileMatchTemplate(emptyTmpDir, "src/templated.ts");
179
+ // Expect the ignores to not be a problem
180
+ expect((0, _fs.existsSync)((0, _path.resolve)(emptyTmpDir, "src/index.ts"))).toBeFalsy();
181
+ expect((0, _fs.existsSync)((0, _path.resolve)(emptyTmpDir, "src/custom-bin"))).toBeFalsy();
182
+ const cloneInfo = await dummyCloneDriver();
183
+ expect(dummyCheckoutDriver).toHaveBeenCalledWith({
184
+ tmpDir: cloneInfo.dir,
185
+ remoteName: cloneInfo.remoteName,
186
+ branch: "new-template-test"
187
+ });
188
+ });
189
+ it("appropriately merges according to just the templatesync config file in an existing repo", async ()=>{
190
+ // Remove the local sync overrides
191
+ await (0, _promises.rm)((0, _path.join)(tmpDir, "templatesync.local.json"));
192
+ const result = await (0, _templatesync.templateSync)({
193
+ tmpCloneDir: "stubbed-by-driver",
194
+ cloneDriver: dummyCloneDriver,
195
+ repoUrl: "not-important",
196
+ repoDir: tmpDir,
197
+ checkoutDriver: dummyCheckoutDriver,
198
+ currentRefDriver: dummyCurrentRefDriver
199
+ });
200
+ expect(result.localSkipFiles).toEqual([]);
201
+ expect(result.localFileChanges).toEqual({});
202
+ // Verify the files
203
+ await fileMatchTemplate(tmpDir, "templatesync.json");
204
+ await fileMatchTemplate(tmpDir, "src/templated.ts");
205
+ const packageJson = JSON.parse((0, _fs.readFileSync)((0, _path.resolve)(tmpDir, "package.json")).toString());
206
+ expect(packageJson).toEqual({
207
+ name: "mypkg",
208
+ description: "my description",
209
+ dependencies: {
210
+ mypackage: "^1.2.0",
211
+ newpacakge: "^22.2.2",
212
+ package2: "3.22.1",
213
+ huh: "~1.0.0"
214
+ },
215
+ engines: {
216
+ node: ">=15"
217
+ },
218
+ scripts: {
219
+ build: "build",
220
+ test: "jest",
221
+ myscript: "somescript"
222
+ },
223
+ // By default we add new top-level fields
224
+ version: "new-version"
225
+ });
226
+ // Expect the ignores to not be a problem
227
+ await fileMatchDownstream(tmpDir, "src/index.ts");
228
+ await fileMatchDownstream(tmpDir, "plugins/custom-plugin.js");
229
+ expect(dummyCheckoutDriver).not.toHaveBeenCalled();
230
+ });
231
+ it("appropriately merges according to the templatesync config file and the local config in an existing repo", async ()=>{
232
+ // Remove the local sync overrides
233
+ await (0, _promises.rm)((0, _path.join)(tmpDir, "templatesync.local.json"));
234
+ (0, _fs.writeFileSync)((0, _path.join)(tmpDir, "templatesync.local.json"), JSON.stringify({
235
+ ignore: [
236
+ // Ignores the templated.ts
237
+ "**/*.ts",
238
+ // We don't have a need for this in here, but it's an example of keeping things cleaner for our custom plugins
239
+ "plugins/**"
240
+ ],
241
+ merge: [
242
+ {
243
+ glob: "package.json",
244
+ plugin: "plugins/custom-plugin.js",
245
+ options: {}
246
+ }
247
+ ]
248
+ }));
249
+ const result = await (0, _templatesync.templateSync)({
250
+ tmpCloneDir: "stubbed-by-driver",
251
+ cloneDriver: dummyCloneDriver,
252
+ repoUrl: "not-important",
253
+ repoDir: tmpDir,
254
+ checkoutDriver: dummyCheckoutDriver,
255
+ currentRefDriver: dummyCurrentRefDriver
256
+ });
257
+ expect(result.localSkipFiles).toEqual([
258
+ "src/templated.ts"
259
+ ]);
260
+ // TODO: more rigorous testing around diff changes
261
+ expect(result.localFileChanges).toEqual(expect.objectContaining({
262
+ "package.json": expect.arrayContaining([])
263
+ }));
264
+ // Make sure the result captures the changes
265
+ expect(result.modifiedFiles).toEqual({
266
+ added: [
267
+ "package.json",
268
+ "src/index.js",
269
+ "src/templated.js",
270
+ "templatesync.json"
271
+ ],
272
+ deleted: [],
273
+ modified: [],
274
+ total: 4
275
+ });
276
+ // Verify the files
277
+ await fileMatchTemplate(tmpDir, "templatesync.json");
278
+ await fileMatchDownstream(tmpDir, "src/templated.ts");
279
+ const packageJson = JSON.parse((0, _fs.readFileSync)((0, _path.resolve)(tmpDir, "package.json")).toString());
280
+ // The plugin nuked this
281
+ expect(packageJson).toEqual({
282
+ downstream: true
283
+ });
284
+ // Expect the ignores to not be a problem
285
+ await fileMatchDownstream(tmpDir, "src/index.ts");
286
+ await fileMatchDownstream(tmpDir, "plugins/custom-plugin.js");
287
+ expect(dummyCheckoutDriver).not.toHaveBeenCalled();
288
+ });
289
+ it("appropriately merges according to the templatesync config file and the local config in an existing repo with afterRef", async ()=>{
290
+ // Remove the local sync overrides
291
+ await (0, _promises.rm)((0, _path.join)(tmpDir, "templatesync.local.json"));
292
+ (0, _fs.writeFileSync)((0, _path.join)(tmpDir, "templatesync.local.json"), JSON.stringify({
293
+ afterRef: "dummySha",
294
+ ignore: [
295
+ // We don't have a need for this in here, but it's an example of keeping things cleaner for our custom plugins
296
+ "plugins/**"
297
+ ]
298
+ }));
299
+ // We will only update the templated.ts
300
+ const mockDiffDriver = jest.fn().mockImplementation(async ()=>({
301
+ added: [
302
+ "src/templated.ts"
303
+ ],
304
+ modified: [],
305
+ deleted: []
306
+ }));
307
+ const result = await (0, _templatesync.templateSync)({
308
+ tmpCloneDir: "stubbed-by-driver",
309
+ cloneDriver: dummyCloneDriver,
310
+ repoUrl: "not-important",
311
+ repoDir: tmpDir,
312
+ diffDriver: mockDiffDriver,
313
+ currentRefDriver: dummyCurrentRefDriver,
314
+ checkoutDriver: dummyCheckoutDriver
315
+ });
316
+ // since there was no override for this file, not changes from the local file
317
+ expect(result.localFileChanges).toEqual(expect.objectContaining({}));
318
+ // Verify the files
319
+ await fileMatchTemplate(tmpDir, "templatesync.json");
320
+ await fileMatchTemplate(tmpDir, "src/templated.ts");
321
+ // Expect the none of the diff files to work
322
+ await fileMatchDownstream(tmpDir, "src/index.ts");
323
+ await fileMatchDownstream(tmpDir, "plugins/custom-plugin.js");
324
+ await fileMatchDownstream(tmpDir, "package.json");
325
+ expect(dummyCheckoutDriver).not.toHaveBeenCalled();
326
+ });
327
+ it("updates the local templatesync with the current ref if updateAfterRef is true", async ()=>{
328
+ // Remove the local sync overrides
329
+ await (0, _promises.rm)((0, _path.join)(tmpDir, "templatesync.local.json"));
330
+ const mockLocalConfig = {
331
+ afterRef: "dummySha",
332
+ ignore: [
333
+ // We don't have a need for this in here, but it's an example of keeping things cleaner for our custom plugins
334
+ "plugins/**"
335
+ ]
336
+ };
337
+ (0, _fs.writeFileSync)((0, _path.join)(tmpDir, "templatesync.local.json"), JSON.stringify(mockLocalConfig));
338
+ // We will only update the templated.ts
339
+ const mockDiffDriver = jest.fn().mockImplementation(async ()=>({
340
+ added: [
341
+ "src/templated.ts"
342
+ ],
343
+ modified: [
344
+ "src/index.ts"
345
+ ],
346
+ deleted: []
347
+ }));
348
+ const mockCurrentRefDriver = jest.fn().mockImplementation(async ()=>"newestSha");
349
+ const result = await (0, _templatesync.templateSync)({
350
+ tmpCloneDir: "stubbed-by-driver",
351
+ cloneDriver: dummyCloneDriver,
352
+ repoUrl: "not-important",
353
+ repoDir: tmpDir,
354
+ updateAfterRef: true,
355
+ diffDriver: mockDiffDriver,
356
+ currentRefDriver: mockCurrentRefDriver,
357
+ checkoutDriver: dummyCheckoutDriver
358
+ });
359
+ // since there was no override for this file, no changes from the local file
360
+ expect(result.localFileChanges).toEqual(expect.objectContaining({}));
361
+ expect(result.modifiedFiles).toEqual({
362
+ added: [
363
+ "src/templated.ts"
364
+ ],
365
+ modified: [
366
+ "templatesync.local.json"
367
+ ],
368
+ deleted: [],
369
+ total: 2
370
+ });
371
+ // Verify the files
372
+ await fileMatchTemplate(tmpDir, "templatesync.json");
373
+ await fileMatchTemplate(tmpDir, "src/templated.ts");
374
+ // Expect the none of the diff files to work
375
+ await fileMatchDownstream(tmpDir, "src/index.ts");
376
+ await fileMatchDownstream(tmpDir, "plugins/custom-plugin.js");
377
+ await fileMatchDownstream(tmpDir, "package.json");
378
+ // Ensure we have updated the local template field
379
+ expect(JSON.parse((await (0, _promises.readFile)((0, _path.join)(tmpDir, "templatesync.local.json"))).toString())).toEqual({
380
+ ...mockLocalConfig,
381
+ afterRef: "newestSha"
382
+ });
383
+ expect(dummyCheckoutDriver).not.toHaveBeenCalled();
384
+ });
385
+ it("Does not update the local templatesync if updateAfterRef is true and the ref is the same", async ()=>{
386
+ // Remove the local sync overrides
387
+ await (0, _promises.rm)((0, _path.join)(tmpDir, "templatesync.local.json"));
388
+ const mockLocalConfig = {
389
+ afterRef: "dummySha",
390
+ ignore: [
391
+ // We don't have a need for this in here, but it's an example of keeping things cleaner for our custom plugins
392
+ "plugins/**"
393
+ ]
394
+ };
395
+ (0, _fs.writeFileSync)((0, _path.join)(tmpDir, "templatesync.local.json"), JSON.stringify(mockLocalConfig));
396
+ // We will only update the templated.ts
397
+ const mockDiffDriver = jest.fn().mockImplementation(async ()=>({
398
+ added: [
399
+ "src/templated.ts"
400
+ ],
401
+ modified: [
402
+ "src/index.ts"
403
+ ],
404
+ deleted: []
405
+ }));
406
+ const mockCurrentRefDriver = jest.fn().mockImplementation(async ()=>"dummySha");
407
+ const result = await (0, _templatesync.templateSync)({
408
+ tmpCloneDir: "stubbed-by-driver",
409
+ cloneDriver: dummyCloneDriver,
410
+ repoUrl: "not-important",
411
+ repoDir: tmpDir,
412
+ updateAfterRef: true,
413
+ diffDriver: mockDiffDriver,
414
+ currentRefDriver: mockCurrentRefDriver,
415
+ checkoutDriver: dummyCheckoutDriver
416
+ });
417
+ // Nothing shoudl be reported as changing
418
+ expect(result).toEqual({
419
+ localFileChanges: {},
420
+ localSkipFiles: [],
421
+ modifiedFiles: {
422
+ added: [],
423
+ modified: [],
424
+ deleted: [],
425
+ total: 0
426
+ }
427
+ });
428
+ // Verify the files
429
+ await fileMatchDownstream(tmpDir, "templatesync.json");
430
+ await fileMatchDownstream(tmpDir, "src/templated.ts");
431
+ // Expect the none of the diff files to work
432
+ await fileMatchDownstream(tmpDir, "src/index.ts");
433
+ await fileMatchDownstream(tmpDir, "plugins/custom-plugin.js");
434
+ await fileMatchDownstream(tmpDir, "package.json");
435
+ // Ensure we have updated the local template field
436
+ expect(JSON.parse((await (0, _promises.readFile)((0, _path.join)(tmpDir, "templatesync.local.json"))).toString())).toEqual({
437
+ ...mockLocalConfig
438
+ });
439
+ expect(dummyCheckoutDriver).not.toHaveBeenCalled();
440
+ });
441
+ it("creates the local templatesync with the current ref if updateAfterRef is true and no local template exists", async ()=>{
442
+ // Remove the local sync overrides
443
+ await (0, _promises.rm)((0, _path.join)(tmpDir, "templatesync.local.json"));
444
+ // We will only update the templated.ts
445
+ const mockDiffDriver = jest.fn().mockImplementation(async ()=>({
446
+ added: [
447
+ "src/templated.ts"
448
+ ]
449
+ }));
450
+ const mockCurrentRefDriver = jest.fn().mockImplementation(async ()=>"newestSha");
451
+ const result = await (0, _templatesync.templateSync)({
452
+ tmpCloneDir: "stubbed-by-driver",
453
+ cloneDriver: dummyCloneDriver,
454
+ repoUrl: "not-important",
455
+ repoDir: tmpDir,
456
+ updateAfterRef: true,
457
+ diffDriver: mockDiffDriver,
458
+ currentRefDriver: mockCurrentRefDriver,
459
+ checkoutDriver: dummyCheckoutDriver
460
+ });
461
+ // since there was no override for this file, no changes from the local file
462
+ expect(result.localFileChanges).toEqual(expect.objectContaining({}));
463
+ expect(result.modifiedFiles).toEqual({
464
+ added: [
465
+ "package.json",
466
+ "src/index.js",
467
+ "src/templated.js",
468
+ "src/templated.ts",
469
+ "templatesync.json",
470
+ "templatesync.local.json"
471
+ ],
472
+ deleted: [],
473
+ modified: [],
474
+ total: 6
475
+ });
476
+ // Verify the files
477
+ await fileMatchTemplate(tmpDir, "templatesync.json");
478
+ await fileMatchTemplate(tmpDir, "src/templated.ts");
479
+ const packageJson = JSON.parse((0, _fs.readFileSync)((0, _path.resolve)(tmpDir, "package.json")).toString());
480
+ expect(packageJson).toEqual({
481
+ name: "mypkg",
482
+ description: "my description",
483
+ dependencies: {
484
+ mypackage: "^1.2.0",
485
+ newpacakge: "^22.2.2",
486
+ package2: "3.22.1",
487
+ huh: "~1.0.0"
488
+ },
489
+ engines: {
490
+ node: ">=15"
491
+ },
492
+ scripts: {
493
+ build: "build",
494
+ test: "jest",
495
+ myscript: "somescript"
496
+ },
497
+ // By default we add new top-level fields
498
+ version: "new-version"
499
+ });
500
+ // Expect the none of the diff files to work
501
+ await fileMatchDownstream(tmpDir, "src/index.ts");
502
+ await fileMatchDownstream(tmpDir, "plugins/custom-plugin.js");
503
+ // Ensure we have updated the local template field
504
+ expect(JSON.parse((await (0, _promises.readFile)((0, _path.join)(tmpDir, "templatesync.local.json"))).toString())).toEqual({
505
+ afterRef: "newestSha"
506
+ });
507
+ });
508
+ // helper
509
+ async function fileMatchTemplate(_tmpDir, relPath) {
510
+ return fileMatch(_tmpDir, relPath, "template");
511
+ }
512
+ async function fileMatchDownstream(_tmpDir, relPath) {
513
+ return fileMatch(_tmpDir, relPath, "downstream");
514
+ }
515
+ async function fileMatch(_tmpDir, relPath, source) {
516
+ const dir = source === "downstream" ? downstreamDir : (await dummyCloneDriver()).dir;
517
+ expect((await (0, _promises.readFile)((0, _path.resolve)(_tmpDir, relPath))).toString()).toEqual((await (0, _promises.readFile)((0, _path.resolve)(dir, relPath))).toString());
518
+ }
519
+ });
520
+
521
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZW1wbGF0ZS1zeW5jLnNwZWMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jLCB3cml0ZUZpbGVTeW5jIH0gZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBta2R0ZW1wLCByZWFkRmlsZSwgcm0gfSBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGNvcHkgfSBmcm9tIFwiZnMtZXh0cmFcIjtcbmltcG9ydCB7IGpvaW4sIHJlc29sdmUgfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgdGVtcGxhdGVTeW5jIH0gZnJvbSBcIi4vdGVtcGxhdGUtc3luY1wiO1xuaW1wb3J0IHsgVEVTVF9GSVhUVVJFU19ESVIsIHRlbXBEaXIgfSBmcm9tIFwiLi90ZXN0LXV0aWxzXCI7XG5cbmNvbnN0IGR1bW15Q2hlY2tvdXREcml2ZXIgPSBqZXN0LmZuKCk7XG5jb25zdCBkdW1teUN1cnJlbnRSZWZEcml2ZXIgPSBqZXN0LmZuKCk7XG5cbmNvbnN0IGRvd25zdHJlYW1EaXIgPSByZXNvbHZlKFRFU1RfRklYVFVSRVNfRElSLCBcImRvd25zdHJlYW1cIik7XG5cbmRlc2NyaWJlKFwidGVtcGxhdGVTeW5jXCIsICgpID0+IHtcblx0bGV0IHRtcERpcjogc3RyaW5nO1xuXHRsZXQgdGVtcGxhdGVEaXI6IHN0cmluZztcblx0bGV0IGR1bW15Q2xvbmVEcml2ZXI6ICgpID0+IFByb21pc2U8eyBkaXI6IHN0cmluZzsgcmVtb3RlTmFtZTogc3RyaW5nIH0+O1xuXHRiZWZvcmVFYWNoKGFzeW5jICgpID0+IHtcblx0XHRqZXN0LnJlc2V0QWxsTW9ja3MoKTtcblx0XHR0bXBEaXIgPSBhd2FpdCBta2R0ZW1wKHRlbXBEaXIoKSk7XG5cdFx0dGVtcGxhdGVEaXIgPSBhd2FpdCBta2R0ZW1wKHRlbXBEaXIoKSk7XG5cdFx0YXdhaXQgY29weShyZXNvbHZlKFRFU1RfRklYVFVSRVNfRElSLCBcInRlbXBsYXRlXCIpLCB0ZW1wbGF0ZURpcik7XG5cdFx0YXdhaXQgY29weShkb3duc3RyZWFtRGlyLCB0bXBEaXIpO1xuXHRcdGR1bW15Q2xvbmVEcml2ZXIgPSBhc3luYyAoKSA9PiB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRkaXI6IHRlbXBsYXRlRGlyLFxuXHRcdFx0XHRyZW1vdGVOYW1lOiBcIm91clJlbW90ZVwiLFxuXHRcdFx0fTtcblx0XHR9O1xuXHR9KTtcblx0YWZ0ZXJFYWNoKGFzeW5jICgpID0+IHtcblx0XHRhd2FpdCBybSh0bXBEaXIsIHtcblx0XHRcdGZvcmNlOiB0cnVlLFxuXHRcdFx0cmVjdXJzaXZlOiB0cnVlLFxuXHRcdH0pO1xuXHR9KTtcblx0Ly8gTm90ZTogZm9yIHRoaXMgdGVzdCwgd2UgZXhwZWN0IGFjdGlvbnMgYW5kIHVzZXJzIHRvIGhhbmRsZSBtaXNjb25maWd1cmVkIHRlbXBsYXRlIHN5bmNzXG5cdGl0LmVhY2goW1xuXHRcdFtcblx0XHRcdFwibG9jYWxcIixcblx0XHRcdGB0ZW1wbGF0ZXN5bmMubG9jYWwuanNvbiBwbHVnaW4gb3B0aW9uIGVycm9yczpcblxcdFBsdWdpbiAocGx1Z2lucy9mYWlsLXZhbGlkYXRlLXBsdWdpbi5qcyk6XG5cXHRcXHRvaCBubyFcblxcdFxcdG5vdCB0aGlzIG9uZSB0b28hXG5gLFxuXHRcdF0sXG5cdFx0W1xuXHRcdFx0XCJ0ZW1wbGF0ZVwiLFxuXHRcdFx0YHRlbXBsYXRlc3luYy5qc29uIHBsdWdpbiBvcHRpb24gZXJyb3JzOlxuXFx0UGx1Z2luIChkdW1teS1mYWlsLXBsdWdpbi5qcyk6XG5cXHRcXHRzaHVja3NcblxcdFxcdG5vIGdvb2RcbmAsXG5cdFx0XSxcblx0XHRbXG5cdFx0XHRcImJvdGhcIixcblx0XHRcdGB0ZW1wbGF0ZXN5bmMuanNvbiBwbHVnaW4gb3B0aW9uIGVycm9yczpcblxcdFBsdWdpbiAoZHVtbXktZmFpbC1wbHVnaW4uanMpOlxuXFx0XFx0c2h1Y2tzXG5cXHRcXHRubyBnb29kXG50ZW1wbGF0ZXN5bmMubG9jYWwuanNvbiBwbHVnaW4gb3B0aW9uIGVycm9yczpcblxcdFBsdWdpbiAocGx1Z2lucy9mYWlsLXZhbGlkYXRlLXBsdWdpbi5qcyk6XG5cXHRcXHRvaCBubyFcblxcdFxcdG5vdCB0aGlzIG9uZSB0b28hXG5gLFxuXHRcdF0sXG5cdF0pKFwidGhyb3dzIGVycm9ycyBmcm9tIHBsdWdpbiB2YWxpZGF0aW9uXCIsIGFzeW5jIChtb2RlLCBleHBlY3RlZCkgPT4ge1xuXHRcdC8vIFJlbW92ZSB0aGUgbG9jYWwgc3luYyBvdmVycmlkZXNcblx0XHRhd2FpdCBybShqb2luKHRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMubG9jYWwuanNvblwiKSk7XG5cblx0XHRpZiAobW9kZSA9PT0gXCJsb2NhbFwiIHx8IG1vZGUgPT0gXCJib3RoXCIpIHtcblx0XHRcdHdyaXRlRmlsZVN5bmMoXG5cdFx0XHRcdGpvaW4odG1wRGlyLCBcInRlbXBsYXRlc3luYy5sb2NhbC5qc29uXCIpLFxuXHRcdFx0XHRKU09OLnN0cmluZ2lmeSh7XG5cdFx0XHRcdFx0aWdub3JlOiBbXG5cdFx0XHRcdFx0XHQvLyBJZ25vcmVzIHRoZSB0ZW1wbGF0ZWQudHNcblx0XHRcdFx0XHRcdFwiKiovKi50c1wiLFxuXHRcdFx0XHRcdFx0Ly8gV2UgZG9uJ3QgaGF2ZSBhIG5lZWQgZm9yIHRoaXMgaW4gaGVyZSwgYnV0IGl0J3MgYW4gZXhhbXBsZSBvZiBrZWVwaW5nIHRoaW5ncyBjbGVhbmVyIGZvciBvdXIgY3VzdG9tIHBsdWdpbnNcblx0XHRcdFx0XHRcdFwicGx1Z2lucy8qKlwiLFxuXHRcdFx0XHRcdF0sXG5cdFx0XHRcdFx0bWVyZ2U6IFtcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0Z2xvYjogXCJwYWNrYWdlLmpzb25cIixcblx0XHRcdFx0XHRcdFx0cGx1Z2luOiBcInBsdWdpbnMvZmFpbC12YWxpZGF0ZS1wbHVnaW4uanNcIixcblx0XHRcdFx0XHRcdFx0b3B0aW9uczoge30sXG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdF0sXG5cdFx0XHRcdH0pLFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0aWYgKG1vZGUgPT09IFwidGVtcGxhdGVcIiB8fCBtb2RlID09PSBcImJvdGhcIikge1xuXHRcdFx0d3JpdGVGaWxlU3luYyhcblx0XHRcdFx0am9pbih0ZW1wbGF0ZURpciwgXCJ0ZW1wbGF0ZXN5bmMuanNvblwiKSxcblx0XHRcdFx0SlNPTi5zdHJpbmdpZnkoe1xuXHRcdFx0XHRcdGlnbm9yZTogW1xuXHRcdFx0XHRcdFx0Ly8gSWdub3JlcyB0aGUgdGVtcGxhdGVkLnRzXG5cdFx0XHRcdFx0XHRcIioqLyoudHNcIixcblx0XHRcdFx0XHRcdC8vIFdlIGRvbid0IGhhdmUgYSBuZWVkIGZvciB0aGlzIGluIGhlcmUsIGJ1dCBpdCdzIGFuIGV4YW1wbGUgb2Yga2VlcGluZyB0aGluZ3MgY2xlYW5lciBmb3Igb3VyIGN1c3RvbSBwbHVnaW5zXG5cdFx0XHRcdFx0XHRcInBsdWdpbnMvKipcIixcblx0XHRcdFx0XHRdLFxuXHRcdFx0XHRcdG1lcmdlOiBbXG5cdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdGdsb2I6IFwicGFja2FnZS5qc29uXCIsXG5cdFx0XHRcdFx0XHRcdHBsdWdpbjogXCJkdW1teS1mYWlsLXBsdWdpbi5qc1wiLFxuXHRcdFx0XHRcdFx0XHRvcHRpb25zOiB7fSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XSxcblx0XHRcdFx0fSksXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdGF3YWl0IGV4cGVjdChcblx0XHRcdGFzeW5jICgpID0+XG5cdFx0XHRcdGF3YWl0IHRlbXBsYXRlU3luYyh7XG5cdFx0XHRcdFx0dG1wQ2xvbmVEaXI6IFwic3R1YmJlZC1ieS1kcml2ZXJcIixcblx0XHRcdFx0XHRjbG9uZURyaXZlcjogZHVtbXlDbG9uZURyaXZlcixcblx0XHRcdFx0XHRyZXBvVXJsOiBcIm5vdC1pbXBvcnRhbnRcIixcblx0XHRcdFx0XHRyZXBvRGlyOiB0bXBEaXIsXG5cdFx0XHRcdFx0Y2hlY2tvdXREcml2ZXI6IGR1bW15Q2hlY2tvdXREcml2ZXIsXG5cdFx0XHRcdFx0Y3VycmVudFJlZkRyaXZlcjogZHVtbXlDdXJyZW50UmVmRHJpdmVyLFxuXHRcdFx0XHR9KSxcblx0XHQpLnJlamVjdHMudG9UaHJvdyhleHBlY3RlZCk7XG5cdH0pO1xuXHRpdChcImFwcHJvcHJpYXRlbHkgbWVyZ2VzIGFjY29yZGluZyB0byBqdXN0IHRoZSB0ZW1wbGF0ZXN5bmMgY29uZmlnIGZpbGUgaW50byBhbiBlbXB0eSBkaXJcIiwgYXN5bmMgKCkgPT4ge1xuXHRcdGNvbnN0IGVtcHR5VG1wRGlyID0gYXdhaXQgbWtkdGVtcCh0ZW1wRGlyKCkpO1xuXHRcdGV4cGVjdChcblx0XHRcdGF3YWl0IHRlbXBsYXRlU3luYyh7XG5cdFx0XHRcdHRtcENsb25lRGlyOiBcInN0dWJiZWQtYnktZHJpdmVyXCIsXG5cdFx0XHRcdGNsb25lRHJpdmVyOiBkdW1teUNsb25lRHJpdmVyLFxuXHRcdFx0XHRyZXBvVXJsOiBcIm5vdC1pbXBvcnRhbnRcIixcblx0XHRcdFx0cmVwb0RpcjogZW1wdHlUbXBEaXIsXG5cdFx0XHRcdGNoZWNrb3V0RHJpdmVyOiBkdW1teUNoZWNrb3V0RHJpdmVyLFxuXHRcdFx0XHRjdXJyZW50UmVmRHJpdmVyOiBkdW1teUN1cnJlbnRSZWZEcml2ZXIsXG5cdFx0XHR9KSxcblx0XHQpLnRvRXF1YWwoe1xuXHRcdFx0Ly8gRXhwZWN0IG5vIGNoYW5nZXMgc2luY2UgdGhlcmUgd2FzIG5vIGxvY2FsIHN5bmMgZmlsZVxuXHRcdFx0bG9jYWxTa2lwRmlsZXM6IFtdLFxuXHRcdFx0bG9jYWxGaWxlQ2hhbmdlczoge30sXG5cdFx0XHRtb2RpZmllZEZpbGVzOiB7XG5cdFx0XHRcdGFkZGVkOiBbXG5cdFx0XHRcdFx0XCJwYWNrYWdlLmpzb25cIixcblx0XHRcdFx0XHRcInNyYy9pbmRleC5qc1wiLFxuXHRcdFx0XHRcdFwic3JjL3RlbXBsYXRlZC5qc1wiLFxuXHRcdFx0XHRcdFwic3JjL3RlbXBsYXRlZC50c1wiLFxuXHRcdFx0XHRcdFwidGVtcGxhdGVzeW5jLmpzb25cIixcblx0XHRcdFx0XSxcblx0XHRcdFx0ZGVsZXRlZDogW10sXG5cdFx0XHRcdG1vZGlmaWVkOiBbXSxcblx0XHRcdFx0dG90YWw6IDUsXG5cdFx0XHR9LFxuXHRcdH0pO1xuXG5cdFx0Ly8gVmVyaWZ5IHRoZSBmaWxlc1xuXHRcdGF3YWl0IGZpbGVNYXRjaFRlbXBsYXRlKGVtcHR5VG1wRGlyLCBcInRlbXBsYXRlc3luYy5qc29uXCIpO1xuXHRcdGF3YWl0IGZpbGVNYXRjaFRlbXBsYXRlKGVtcHR5VG1wRGlyLCBcInBhY2thZ2UuanNvblwiKTtcblx0XHRhd2FpdCBmaWxlTWF0Y2hUZW1wbGF0ZShlbXB0eVRtcERpciwgXCJzcmMvdGVtcGxhdGVkLnRzXCIpO1xuXG5cdFx0Ly8gRXhwZWN0IHRoZSBpZ25vcmVzIHRvIG5vdCBiZSBhIHByb2JsZW1cblx0XHRleHBlY3QoZXhpc3RzU3luYyhyZXNvbHZlKGVtcHR5VG1wRGlyLCBcInNyYy9pbmRleC50c1wiKSkpLnRvQmVGYWxzeSgpO1xuXHRcdGV4cGVjdChleGlzdHNTeW5jKHJlc29sdmUoZW1wdHlUbXBEaXIsIFwic3JjL2N1c3RvbS1iaW5cIikpKS50b0JlRmFsc3koKTtcblxuXHRcdGV4cGVjdChkdW1teUNoZWNrb3V0RHJpdmVyKS5ub3QudG9IYXZlQmVlbkNhbGxlZCgpO1xuXHR9KTtcblx0aXQoXCJDaGVja3Mgb3V0IHRoZSBicmFuY2ggYW5kIHRoZW4gYXBwcm9wcmlhdGVseSBtZXJnZXNcIiwgYXN5bmMgKCkgPT4ge1xuXHRcdGNvbnN0IGVtcHR5VG1wRGlyID0gYXdhaXQgbWtkdGVtcCh0ZW1wRGlyKCkpO1xuXHRcdGV4cGVjdChcblx0XHRcdGF3YWl0IHRlbXBsYXRlU3luYyh7XG5cdFx0XHRcdHRtcENsb25lRGlyOiBcInN0dWJiZWQtYnktZHJpdmVyXCIsXG5cdFx0XHRcdGNsb25lRHJpdmVyOiBkdW1teUNsb25lRHJpdmVyLFxuXHRcdFx0XHRyZXBvVXJsOiBcIm5vdC1pbXBvcnRhbnRcIixcblx0XHRcdFx0cmVwb0RpcjogZW1wdHlUbXBEaXIsXG5cdFx0XHRcdGJyYW5jaDogXCJuZXctdGVtcGxhdGUtdGVzdFwiLFxuXHRcdFx0XHRjaGVja291dERyaXZlcjogZHVtbXlDaGVja291dERyaXZlcixcblx0XHRcdFx0Y3VycmVudFJlZkRyaXZlcjogZHVtbXlDdXJyZW50UmVmRHJpdmVyLFxuXHRcdFx0fSksXG5cdFx0KS50b0VxdWFsKHtcblx0XHRcdC8vIEV4cGVjdCBubyBjaGFuZ2VzIHNpbmNlIHRoZXJlIHdhcyBubyBsb2NhbCBzeW5jIGZpbGVcblx0XHRcdGxvY2FsU2tpcEZpbGVzOiBbXSxcblx0XHRcdGxvY2FsRmlsZUNoYW5nZXM6IHt9LFxuXHRcdFx0bW9kaWZpZWRGaWxlczoge1xuXHRcdFx0XHRhZGRlZDogW1xuXHRcdFx0XHRcdFwicGFja2FnZS5qc29uXCIsXG5cdFx0XHRcdFx0XCJzcmMvaW5kZXguanNcIixcblx0XHRcdFx0XHRcInNyYy90ZW1wbGF0ZWQuanNcIixcblx0XHRcdFx0XHRcInNyYy90ZW1wbGF0ZWQudHNcIixcblx0XHRcdFx0XHRcInRlbXBsYXRlc3luYy5qc29uXCIsXG5cdFx0XHRcdF0sXG5cdFx0XHRcdGRlbGV0ZWQ6IFtdLFxuXHRcdFx0XHRtb2RpZmllZDogW10sXG5cdFx0XHRcdHRvdGFsOiA1LFxuXHRcdFx0fSxcblx0XHR9KTtcblxuXHRcdC8vIFZlcmlmeSB0aGUgZmlsZXNcblx0XHRhd2FpdCBmaWxlTWF0Y2hUZW1wbGF0ZShlbXB0eVRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMuanNvblwiKTtcblx0XHRhd2FpdCBmaWxlTWF0Y2hUZW1wbGF0ZShlbXB0eVRtcERpciwgXCJwYWNrYWdlLmpzb25cIik7XG5cdFx0YXdhaXQgZmlsZU1hdGNoVGVtcGxhdGUoZW1wdHlUbXBEaXIsIFwic3JjL3RlbXBsYXRlZC50c1wiKTtcblxuXHRcdC8vIEV4cGVjdCB0aGUgaWdub3JlcyB0byBub3QgYmUgYSBwcm9ibGVtXG5cdFx0ZXhwZWN0KGV4aXN0c1N5bmMocmVzb2x2ZShlbXB0eVRtcERpciwgXCJzcmMvaW5kZXgudHNcIikpKS50b0JlRmFsc3koKTtcblx0XHRleHBlY3QoZXhpc3RzU3luYyhyZXNvbHZlKGVtcHR5VG1wRGlyLCBcInNyYy9jdXN0b20tYmluXCIpKSkudG9CZUZhbHN5KCk7XG5cdFx0Y29uc3QgY2xvbmVJbmZvID0gYXdhaXQgZHVtbXlDbG9uZURyaXZlcigpO1xuXHRcdGV4cGVjdChkdW1teUNoZWNrb3V0RHJpdmVyKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7XG5cdFx0XHR0bXBEaXI6IGNsb25lSW5mby5kaXIsXG5cdFx0XHRyZW1vdGVOYW1lOiBjbG9uZUluZm8ucmVtb3RlTmFtZSxcblx0XHRcdGJyYW5jaDogXCJuZXctdGVtcGxhdGUtdGVzdFwiLFxuXHRcdH0pO1xuXHR9KTtcblx0aXQoXCJhcHByb3ByaWF0ZWx5IG1lcmdlcyBhY2NvcmRpbmcgdG8ganVzdCB0aGUgdGVtcGxhdGVzeW5jIGNvbmZpZyBmaWxlIGluIGFuIGV4aXN0aW5nIHJlcG9cIiwgYXN5bmMgKCkgPT4ge1xuXHRcdC8vIFJlbW92ZSB0aGUgbG9jYWwgc3luYyBvdmVycmlkZXNcblx0XHRhd2FpdCBybShqb2luKHRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMubG9jYWwuanNvblwiKSk7XG5cblx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCB0ZW1wbGF0ZVN5bmMoe1xuXHRcdFx0dG1wQ2xvbmVEaXI6IFwic3R1YmJlZC1ieS1kcml2ZXJcIixcblx0XHRcdGNsb25lRHJpdmVyOiBkdW1teUNsb25lRHJpdmVyLFxuXHRcdFx0cmVwb1VybDogXCJub3QtaW1wb3J0YW50XCIsXG5cdFx0XHRyZXBvRGlyOiB0bXBEaXIsXG5cdFx0XHRjaGVja291dERyaXZlcjogZHVtbXlDaGVja291dERyaXZlcixcblx0XHRcdGN1cnJlbnRSZWZEcml2ZXI6IGR1bW15Q3VycmVudFJlZkRyaXZlcixcblx0XHR9KTtcblxuXHRcdGV4cGVjdChyZXN1bHQubG9jYWxTa2lwRmlsZXMpLnRvRXF1YWwoW10pO1xuXHRcdGV4cGVjdChyZXN1bHQubG9jYWxGaWxlQ2hhbmdlcykudG9FcXVhbCh7fSk7XG5cblx0XHQvLyBWZXJpZnkgdGhlIGZpbGVzXG5cdFx0YXdhaXQgZmlsZU1hdGNoVGVtcGxhdGUodG1wRGlyLCBcInRlbXBsYXRlc3luYy5qc29uXCIpO1xuXHRcdGF3YWl0IGZpbGVNYXRjaFRlbXBsYXRlKHRtcERpciwgXCJzcmMvdGVtcGxhdGVkLnRzXCIpO1xuXHRcdGNvbnN0IHBhY2thZ2VKc29uID0gSlNPTi5wYXJzZShcblx0XHRcdHJlYWRGaWxlU3luYyhyZXNvbHZlKHRtcERpciwgXCJwYWNrYWdlLmpzb25cIikpLnRvU3RyaW5nKCksXG5cdFx0KTtcblxuXHRcdGV4cGVjdChwYWNrYWdlSnNvbikudG9FcXVhbCh7XG5cdFx0XHRuYW1lOiBcIm15cGtnXCIsXG5cdFx0XHRkZXNjcmlwdGlvbjogXCJteSBkZXNjcmlwdGlvblwiLFxuXHRcdFx0ZGVwZW5kZW5jaWVzOiB7XG5cdFx0XHRcdG15cGFja2FnZTogXCJeMS4yLjBcIixcblx0XHRcdFx0bmV3cGFjYWtnZTogXCJeMjIuMi4yXCIsXG5cdFx0XHRcdHBhY2thZ2UyOiBcIjMuMjIuMVwiLFxuXHRcdFx0XHRodWg6IFwifjEuMC4wXCIsXG5cdFx0XHR9LFxuXHRcdFx0ZW5naW5lczoge1xuXHRcdFx0XHRub2RlOiBcIj49MTVcIixcblx0XHRcdH0sXG5cdFx0XHRzY3JpcHRzOiB7XG5cdFx0XHRcdGJ1aWxkOiBcImJ1aWxkXCIsXG5cdFx0XHRcdHRlc3Q6IFwiamVzdFwiLFxuXHRcdFx0XHRteXNjcmlwdDogXCJzb21lc2NyaXB0XCIsXG5cdFx0XHR9LFxuXHRcdFx0Ly8gQnkgZGVmYXVsdCB3ZSBhZGQgbmV3IHRvcC1sZXZlbCBmaWVsZHNcblx0XHRcdHZlcnNpb246IFwibmV3LXZlcnNpb25cIixcblx0XHR9KTtcblxuXHRcdC8vIEV4cGVjdCB0aGUgaWdub3JlcyB0byBub3QgYmUgYSBwcm9ibGVtXG5cdFx0YXdhaXQgZmlsZU1hdGNoRG93bnN0cmVhbSh0bXBEaXIsIFwic3JjL2luZGV4LnRzXCIpO1xuXHRcdGF3YWl0IGZpbGVNYXRjaERvd25zdHJlYW0odG1wRGlyLCBcInBsdWdpbnMvY3VzdG9tLXBsdWdpbi5qc1wiKTtcblx0XHRleHBlY3QoZHVtbXlDaGVja291dERyaXZlcikubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcblx0fSk7XG5cdGl0KFwiYXBwcm9wcmlhdGVseSBtZXJnZXMgYWNjb3JkaW5nIHRvIHRoZSB0ZW1wbGF0ZXN5bmMgY29uZmlnIGZpbGUgYW5kIHRoZSBsb2NhbCBjb25maWcgaW4gYW4gZXhpc3RpbmcgcmVwb1wiLCBhc3luYyAoKSA9PiB7XG5cdFx0Ly8gUmVtb3ZlIHRoZSBsb2NhbCBzeW5jIG92ZXJyaWRlc1xuXHRcdGF3YWl0IHJtKGpvaW4odG1wRGlyLCBcInRlbXBsYXRlc3luYy5sb2NhbC5qc29uXCIpKTtcblxuXHRcdHdyaXRlRmlsZVN5bmMoXG5cdFx0XHRqb2luKHRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMubG9jYWwuanNvblwiKSxcblx0XHRcdEpTT04uc3RyaW5naWZ5KHtcblx0XHRcdFx0aWdub3JlOiBbXG5cdFx0XHRcdFx0Ly8gSWdub3JlcyB0aGUgdGVtcGxhdGVkLnRzXG5cdFx0XHRcdFx0XCIqKi8qLnRzXCIsXG5cdFx0XHRcdFx0Ly8gV2UgZG9uJ3QgaGF2ZSBhIG5lZWQgZm9yIHRoaXMgaW4gaGVyZSwgYnV0IGl0J3MgYW4gZXhhbXBsZSBvZiBrZWVwaW5nIHRoaW5ncyBjbGVhbmVyIGZvciBvdXIgY3VzdG9tIHBsdWdpbnNcblx0XHRcdFx0XHRcInBsdWdpbnMvKipcIixcblx0XHRcdFx0XSxcblx0XHRcdFx0bWVyZ2U6IFtcblx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRnbG9iOiBcInBhY2thZ2UuanNvblwiLFxuXHRcdFx0XHRcdFx0cGx1Z2luOiBcInBsdWdpbnMvY3VzdG9tLXBsdWdpbi5qc1wiLFxuXHRcdFx0XHRcdFx0b3B0aW9uczoge30sXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XSxcblx0XHRcdH0pLFxuXHRcdCk7XG5cblx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCB0ZW1wbGF0ZVN5bmMoe1xuXHRcdFx0dG1wQ2xvbmVEaXI6IFwic3R1YmJlZC1ieS1kcml2ZXJcIixcblx0XHRcdGNsb25lRHJpdmVyOiBkdW1teUNsb25lRHJpdmVyLFxuXHRcdFx0cmVwb1VybDogXCJub3QtaW1wb3J0YW50XCIsXG5cdFx0XHRyZXBvRGlyOiB0bXBEaXIsXG5cdFx0XHRjaGVja291dERyaXZlcjogZHVtbXlDaGVja291dERyaXZlcixcblx0XHRcdGN1cnJlbnRSZWZEcml2ZXI6IGR1bW15Q3VycmVudFJlZkRyaXZlcixcblx0XHR9KTtcblxuXHRcdGV4cGVjdChyZXN1bHQubG9jYWxTa2lwRmlsZXMpLnRvRXF1YWwoW1wic3JjL3RlbXBsYXRlZC50c1wiXSk7XG5cdFx0Ly8gVE9ETzogbW9yZSByaWdvcm91cyB0ZXN0aW5nIGFyb3VuZCBkaWZmIGNoYW5nZXNcblx0XHRleHBlY3QocmVzdWx0LmxvY2FsRmlsZUNoYW5nZXMpLnRvRXF1YWwoXG5cdFx0XHRleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG5cdFx0XHRcdFwicGFja2FnZS5qc29uXCI6IGV4cGVjdC5hcnJheUNvbnRhaW5pbmcoW10pLFxuXHRcdFx0fSksXG5cdFx0KTtcblx0XHQvLyBNYWtlIHN1cmUgdGhlIHJlc3VsdCBjYXB0dXJlcyB0aGUgY2hhbmdlc1xuXHRcdGV4cGVjdChyZXN1bHQubW9kaWZpZWRGaWxlcykudG9FcXVhbCh7XG5cdFx0XHRhZGRlZDogW1xuXHRcdFx0XHRcInBhY2thZ2UuanNvblwiLFxuXHRcdFx0XHRcInNyYy9pbmRleC5qc1wiLFxuXHRcdFx0XHRcInNyYy90ZW1wbGF0ZWQuanNcIixcblx0XHRcdFx0XCJ0ZW1wbGF0ZXN5bmMuanNvblwiLFxuXHRcdFx0XSxcblx0XHRcdGRlbGV0ZWQ6IFtdLFxuXHRcdFx0bW9kaWZpZWQ6IFtdLFxuXHRcdFx0dG90YWw6IDQsXG5cdFx0fSk7XG5cblx0XHQvLyBWZXJpZnkgdGhlIGZpbGVzXG5cdFx0YXdhaXQgZmlsZU1hdGNoVGVtcGxhdGUodG1wRGlyLCBcInRlbXBsYXRlc3luYy5qc29uXCIpO1xuXHRcdGF3YWl0IGZpbGVNYXRjaERvd25zdHJlYW0odG1wRGlyLCBcInNyYy90ZW1wbGF0ZWQudHNcIik7XG5cdFx0Y29uc3QgcGFja2FnZUpzb24gPSBKU09OLnBhcnNlKFxuXHRcdFx0cmVhZEZpbGVTeW5jKHJlc29sdmUodG1wRGlyLCBcInBhY2thZ2UuanNvblwiKSkudG9TdHJpbmcoKSxcblx0XHQpO1xuXG5cdFx0Ly8gVGhlIHBsdWdpbiBudWtlZCB0aGlzXG5cdFx0ZXhwZWN0KHBhY2thZ2VKc29uKS50b0VxdWFsKHtcblx0XHRcdGRvd25zdHJlYW06IHRydWUsXG5cdFx0fSk7XG5cblx0XHQvLyBFeHBlY3QgdGhlIGlnbm9yZXMgdG8gbm90IGJlIGEgcHJvYmxlbVxuXHRcdGF3YWl0IGZpbGVNYXRjaERvd25zdHJlYW0odG1wRGlyLCBcInNyYy9pbmRleC50c1wiKTtcblx0XHRhd2FpdCBmaWxlTWF0Y2hEb3duc3RyZWFtKHRtcERpciwgXCJwbHVnaW5zL2N1c3RvbS1wbHVnaW4uanNcIik7XG5cdFx0ZXhwZWN0KGR1bW15Q2hlY2tvdXREcml2ZXIpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG5cdH0pO1xuXHRpdChcImFwcHJvcHJpYXRlbHkgbWVyZ2VzIGFjY29yZGluZyB0byB0aGUgdGVtcGxhdGVzeW5jIGNvbmZpZyBmaWxlIGFuZCB0aGUgbG9jYWwgY29uZmlnIGluIGFuIGV4aXN0aW5nIHJlcG8gd2l0aCBhZnRlclJlZlwiLCBhc3luYyAoKSA9PiB7XG5cdFx0Ly8gUmVtb3ZlIHRoZSBsb2NhbCBzeW5jIG92ZXJyaWRlc1xuXHRcdGF3YWl0IHJtKGpvaW4odG1wRGlyLCBcInRlbXBsYXRlc3luYy5sb2NhbC5qc29uXCIpKTtcblxuXHRcdHdyaXRlRmlsZVN5bmMoXG5cdFx0XHRqb2luKHRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMubG9jYWwuanNvblwiKSxcblx0XHRcdEpTT04uc3RyaW5naWZ5KHtcblx0XHRcdFx0YWZ0ZXJSZWY6IFwiZHVtbXlTaGFcIixcblx0XHRcdFx0aWdub3JlOiBbXG5cdFx0XHRcdFx0Ly8gV2UgZG9uJ3QgaGF2ZSBhIG5lZWQgZm9yIHRoaXMgaW4gaGVyZSwgYnV0IGl0J3MgYW4gZXhhbXBsZSBvZiBrZWVwaW5nIHRoaW5ncyBjbGVhbmVyIGZvciBvdXIgY3VzdG9tIHBsdWdpbnNcblx0XHRcdFx0XHRcInBsdWdpbnMvKipcIixcblx0XHRcdFx0XSxcblx0XHRcdH0pLFxuXHRcdCk7XG5cblx0XHQvLyBXZSB3aWxsIG9ubHkgdXBkYXRlIHRoZSB0ZW1wbGF0ZWQudHNcblx0XHRjb25zdCBtb2NrRGlmZkRyaXZlciA9IGplc3QuZm4oKS5tb2NrSW1wbGVtZW50YXRpb24oYXN5bmMgKCkgPT4gKHtcblx0XHRcdGFkZGVkOiBbXCJzcmMvdGVtcGxhdGVkLnRzXCJdLFxuXHRcdFx0bW9kaWZpZWQ6IFtdLFxuXHRcdFx0ZGVsZXRlZDogW10sXG5cdFx0fSkpO1xuXHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRlbXBsYXRlU3luYyh7XG5cdFx0XHR0bXBDbG9uZURpcjogXCJzdHViYmVkLWJ5LWRyaXZlclwiLFxuXHRcdFx0Y2xvbmVEcml2ZXI6IGR1bW15Q2xvbmVEcml2ZXIsXG5cdFx0XHRyZXBvVXJsOiBcIm5vdC1pbXBvcnRhbnRcIixcblx0XHRcdHJlcG9EaXI6IHRtcERpcixcblx0XHRcdGRpZmZEcml2ZXI6IG1vY2tEaWZmRHJpdmVyLFxuXHRcdFx0Y3VycmVudFJlZkRyaXZlcjogZHVtbXlDdXJyZW50UmVmRHJpdmVyLFxuXHRcdFx0Y2hlY2tvdXREcml2ZXI6IGR1bW15Q2hlY2tvdXREcml2ZXIsXG5cdFx0fSk7XG5cblx0XHQvLyBzaW5jZSB0aGVyZSB3YXMgbm8gb3ZlcnJpZGUgZm9yIHRoaXMgZmlsZSwgbm90IGNoYW5nZXMgZnJvbSB0aGUgbG9jYWwgZmlsZVxuXHRcdGV4cGVjdChyZXN1bHQubG9jYWxGaWxlQ2hhbmdlcykudG9FcXVhbChleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7fSkpO1xuXG5cdFx0Ly8gVmVyaWZ5IHRoZSBmaWxlc1xuXHRcdGF3YWl0IGZpbGVNYXRjaFRlbXBsYXRlKHRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMuanNvblwiKTtcblx0XHRhd2FpdCBmaWxlTWF0Y2hUZW1wbGF0ZSh0bXBEaXIsIFwic3JjL3RlbXBsYXRlZC50c1wiKTtcblxuXHRcdC8vIEV4cGVjdCB0aGUgbm9uZSBvZiB0aGUgZGlmZiBmaWxlcyB0byB3b3JrXG5cdFx0YXdhaXQgZmlsZU1hdGNoRG93bnN0cmVhbSh0bXBEaXIsIFwic3JjL2luZGV4LnRzXCIpO1xuXHRcdGF3YWl0IGZpbGVNYXRjaERvd25zdHJlYW0odG1wRGlyLCBcInBsdWdpbnMvY3VzdG9tLXBsdWdpbi5qc1wiKTtcblx0XHRhd2FpdCBmaWxlTWF0Y2hEb3duc3RyZWFtKHRtcERpciwgXCJwYWNrYWdlLmpzb25cIik7XG5cdFx0ZXhwZWN0KGR1bW15Q2hlY2tvdXREcml2ZXIpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG5cdH0pO1xuXHRpdChcInVwZGF0ZXMgdGhlIGxvY2FsIHRlbXBsYXRlc3luYyB3aXRoIHRoZSBjdXJyZW50IHJlZiBpZiB1cGRhdGVBZnRlclJlZiBpcyB0cnVlXCIsIGFzeW5jICgpID0+IHtcblx0XHQvLyBSZW1vdmUgdGhlIGxvY2FsIHN5bmMgb3ZlcnJpZGVzXG5cdFx0YXdhaXQgcm0oam9pbih0bXBEaXIsIFwidGVtcGxhdGVzeW5jLmxvY2FsLmpzb25cIikpO1xuXG5cdFx0Y29uc3QgbW9ja0xvY2FsQ29uZmlnID0ge1xuXHRcdFx0YWZ0ZXJSZWY6IFwiZHVtbXlTaGFcIixcblx0XHRcdGlnbm9yZTogW1xuXHRcdFx0XHQvLyBXZSBkb24ndCBoYXZlIGEgbmVlZCBmb3IgdGhpcyBpbiBoZXJlLCBidXQgaXQncyBhbiBleGFtcGxlIG9mIGtlZXBpbmcgdGhpbmdzIGNsZWFuZXIgZm9yIG91ciBjdXN0b20gcGx1Z2luc1xuXHRcdFx0XHRcInBsdWdpbnMvKipcIixcblx0XHRcdF0sXG5cdFx0fTtcblxuXHRcdHdyaXRlRmlsZVN5bmMoXG5cdFx0XHRqb2luKHRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMubG9jYWwuanNvblwiKSxcblx0XHRcdEpTT04uc3RyaW5naWZ5KG1vY2tMb2NhbENvbmZpZyksXG5cdFx0KTtcblxuXHRcdC8vIFdlIHdpbGwgb25seSB1cGRhdGUgdGhlIHRlbXBsYXRlZC50c1xuXHRcdGNvbnN0IG1vY2tEaWZmRHJpdmVyID0gamVzdC5mbigpLm1vY2tJbXBsZW1lbnRhdGlvbihhc3luYyAoKSA9PiAoe1xuXHRcdFx0YWRkZWQ6IFtcInNyYy90ZW1wbGF0ZWQudHNcIl0sXG5cdFx0XHRtb2RpZmllZDogW1wic3JjL2luZGV4LnRzXCJdLCAvLyBBZGQgaW5kZXgudHMgc28gd2UgbWFrZSBzdXJlIGl0IGlzIHN0aWxsIGlnbm9yZWQgLSBzZWUgdGVzdC1maXh0dXJlcy90ZW1wbGF0ZS90ZW1wbGF0ZXN5bmMuanNvbiBpZ25vcmVzXG5cdFx0XHRkZWxldGVkOiBbXSxcblx0XHR9KSk7XG5cdFx0Y29uc3QgbW9ja0N1cnJlbnRSZWZEcml2ZXIgPSBqZXN0XG5cdFx0XHQuZm4oKVxuXHRcdFx0Lm1vY2tJbXBsZW1lbnRhdGlvbihhc3luYyAoKSA9PiBcIm5ld2VzdFNoYVwiKTtcblx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCB0ZW1wbGF0ZVN5bmMoe1xuXHRcdFx0dG1wQ2xvbmVEaXI6IFwic3R1YmJlZC1ieS1kcml2ZXJcIixcblx0XHRcdGNsb25lRHJpdmVyOiBkdW1teUNsb25lRHJpdmVyLFxuXHRcdFx0cmVwb1VybDogXCJub3QtaW1wb3J0YW50XCIsXG5cdFx0XHRyZXBvRGlyOiB0bXBEaXIsXG5cdFx0XHR1cGRhdGVBZnRlclJlZjogdHJ1ZSxcblx0XHRcdGRpZmZEcml2ZXI6IG1vY2tEaWZmRHJpdmVyLFxuXHRcdFx0Y3VycmVudFJlZkRyaXZlcjogbW9ja0N1cnJlbnRSZWZEcml2ZXIsXG5cdFx0XHRjaGVja291dERyaXZlcjogZHVtbXlDaGVja291dERyaXZlcixcblx0XHR9KTtcblxuXHRcdC8vIHNpbmNlIHRoZXJlIHdhcyBubyBvdmVycmlkZSBmb3IgdGhpcyBmaWxlLCBubyBjaGFuZ2VzIGZyb20gdGhlIGxvY2FsIGZpbGVcblx0XHRleHBlY3QocmVzdWx0LmxvY2FsRmlsZUNoYW5nZXMpLnRvRXF1YWwoZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe30pKTtcblx0XHRleHBlY3QocmVzdWx0Lm1vZGlmaWVkRmlsZXMpLnRvRXF1YWwoe1xuXHRcdFx0YWRkZWQ6IFtcInNyYy90ZW1wbGF0ZWQudHNcIl0sXG5cdFx0XHRtb2RpZmllZDogW1widGVtcGxhdGVzeW5jLmxvY2FsLmpzb25cIl0sIC8vIEFkZCBpbmRleC50cyBzbyB3ZSBtYWtlIHN1cmUgaXQgaXMgc3RpbGwgaWdub3JlZCAtIGR1ZSB0byBhIGJ1Z1xuXHRcdFx0ZGVsZXRlZDogW10sXG5cdFx0XHR0b3RhbDogMixcblx0XHR9KTtcblxuXHRcdC8vIFZlcmlmeSB0aGUgZmlsZXNcblx0XHRhd2FpdCBmaWxlTWF0Y2hUZW1wbGF0ZSh0bXBEaXIsIFwidGVtcGxhdGVzeW5jLmpzb25cIik7XG5cdFx0YXdhaXQgZmlsZU1hdGNoVGVtcGxhdGUodG1wRGlyLCBcInNyYy90ZW1wbGF0ZWQudHNcIik7XG5cblx0XHQvLyBFeHBlY3QgdGhlIG5vbmUgb2YgdGhlIGRpZmYgZmlsZXMgdG8gd29ya1xuXHRcdGF3YWl0IGZpbGVNYXRjaERvd25zdHJlYW0odG1wRGlyLCBcInNyYy9pbmRleC50c1wiKTtcblx0XHRhd2FpdCBmaWxlTWF0Y2hEb3duc3RyZWFtKHRtcERpciwgXCJwbHVnaW5zL2N1c3RvbS1wbHVnaW4uanNcIik7XG5cdFx0YXdhaXQgZmlsZU1hdGNoRG93bnN0cmVhbSh0bXBEaXIsIFwicGFja2FnZS5qc29uXCIpO1xuXG5cdFx0Ly8gRW5zdXJlIHdlIGhhdmUgdXBkYXRlZCB0aGUgbG9jYWwgdGVtcGxhdGUgZmllbGRcblx0XHRleHBlY3QoXG5cdFx0XHRKU09OLnBhcnNlKFxuXHRcdFx0XHQoYXdhaXQgcmVhZEZpbGUoam9pbih0bXBEaXIsIFwidGVtcGxhdGVzeW5jLmxvY2FsLmpzb25cIikpKS50b1N0cmluZygpLFxuXHRcdFx0KSxcblx0XHQpLnRvRXF1YWwoe1xuXHRcdFx0Li4ubW9ja0xvY2FsQ29uZmlnLFxuXHRcdFx0YWZ0ZXJSZWY6IFwibmV3ZXN0U2hhXCIsXG5cdFx0fSk7XG5cdFx0ZXhwZWN0KGR1bW15Q2hlY2tvdXREcml2ZXIpLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XG5cdH0pO1xuXHRpdChcIkRvZXMgbm90IHVwZGF0ZSB0aGUgbG9jYWwgdGVtcGxhdGVzeW5jIGlmIHVwZGF0ZUFmdGVyUmVmIGlzIHRydWUgYW5kIHRoZSByZWYgaXMgdGhlIHNhbWVcIiwgYXN5bmMgKCkgPT4ge1xuXHRcdC8vIFJlbW92ZSB0aGUgbG9jYWwgc3luYyBvdmVycmlkZXNcblx0XHRhd2FpdCBybShqb2luKHRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMubG9jYWwuanNvblwiKSk7XG5cblx0XHRjb25zdCBtb2NrTG9jYWxDb25maWcgPSB7XG5cdFx0XHRhZnRlclJlZjogXCJkdW1teVNoYVwiLFxuXHRcdFx0aWdub3JlOiBbXG5cdFx0XHRcdC8vIFdlIGRvbid0IGhhdmUgYSBuZWVkIGZvciB0aGlzIGluIGhlcmUsIGJ1dCBpdCdzIGFuIGV4YW1wbGUgb2Yga2VlcGluZyB0aGluZ3MgY2xlYW5lciBmb3Igb3VyIGN1c3RvbSBwbHVnaW5zXG5cdFx0XHRcdFwicGx1Z2lucy8qKlwiLFxuXHRcdFx0XSxcblx0XHR9O1xuXG5cdFx0d3JpdGVGaWxlU3luYyhcblx0XHRcdGpvaW4odG1wRGlyLCBcInRlbXBsYXRlc3luYy5sb2NhbC5qc29uXCIpLFxuXHRcdFx0SlNPTi5zdHJpbmdpZnkobW9ja0xvY2FsQ29uZmlnKSxcblx0XHQpO1xuXG5cdFx0Ly8gV2Ugd2lsbCBvbmx5IHVwZGF0ZSB0aGUgdGVtcGxhdGVkLnRzXG5cdFx0Y29uc3QgbW9ja0RpZmZEcml2ZXIgPSBqZXN0LmZuKCkubW9ja0ltcGxlbWVudGF0aW9uKGFzeW5jICgpID0+ICh7XG5cdFx0XHRhZGRlZDogW1wic3JjL3RlbXBsYXRlZC50c1wiXSxcblx0XHRcdG1vZGlmaWVkOiBbXCJzcmMvaW5kZXgudHNcIl0sIC8vIEFkZCBpbmRleC50cyBzbyB3ZSBtYWtlIHN1cmUgaXQgaXMgc3RpbGwgaWdub3JlZCAtIHNlZSB0ZXN0LWZpeHR1cmVzL3RlbXBsYXRlL3RlbXBsYXRlc3luYy5qc29uIGlnbm9yZXNcblx0XHRcdGRlbGV0ZWQ6IFtdLFxuXHRcdH0pKTtcblx0XHRjb25zdCBtb2NrQ3VycmVudFJlZkRyaXZlciA9IGplc3Rcblx0XHRcdC5mbigpXG5cdFx0XHQubW9ja0ltcGxlbWVudGF0aW9uKGFzeW5jICgpID0+IFwiZHVtbXlTaGFcIik7XG5cdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgdGVtcGxhdGVTeW5jKHtcblx0XHRcdHRtcENsb25lRGlyOiBcInN0dWJiZWQtYnktZHJpdmVyXCIsXG5cdFx0XHRjbG9uZURyaXZlcjogZHVtbXlDbG9uZURyaXZlcixcblx0XHRcdHJlcG9Vcmw6IFwibm90LWltcG9ydGFudFwiLFxuXHRcdFx0cmVwb0RpcjogdG1wRGlyLFxuXHRcdFx0dXBkYXRlQWZ0ZXJSZWY6IHRydWUsXG5cdFx0XHRkaWZmRHJpdmVyOiBtb2NrRGlmZkRyaXZlcixcblx0XHRcdGN1cnJlbnRSZWZEcml2ZXI6IG1vY2tDdXJyZW50UmVmRHJpdmVyLFxuXHRcdFx0Y2hlY2tvdXREcml2ZXI6IGR1bW15Q2hlY2tvdXREcml2ZXIsXG5cdFx0fSk7XG5cblx0XHQvLyBOb3RoaW5nIHNob3VkbCBiZSByZXBvcnRlZCBhcyBjaGFuZ2luZ1xuXHRcdGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoe1xuXHRcdFx0bG9jYWxGaWxlQ2hhbmdlczoge30sXG5cdFx0XHRsb2NhbFNraXBGaWxlczogW10sXG5cdFx0XHRtb2RpZmllZEZpbGVzOiB7XG5cdFx0XHRcdGFkZGVkOiBbXSxcblx0XHRcdFx0bW9kaWZpZWQ6IFtdLFxuXHRcdFx0XHRkZWxldGVkOiBbXSxcblx0XHRcdFx0dG90YWw6IDAsXG5cdFx0XHR9LFxuXHRcdH0pO1xuXHRcdC8vIFZlcmlmeSB0aGUgZmlsZXNcblx0XHRhd2FpdCBmaWxlTWF0Y2hEb3duc3RyZWFtKHRtcERpciwgXCJ0ZW1wbGF0ZXN5bmMuanNvblwiKTtcblx0XHRhd2FpdCBmaWxlTWF0Y2hEb3duc3RyZWFtKHRtcERpciwgXCJzcmMvdGVtcGxhdGVkLnRzXCIpO1xuXG5cdFx0Ly8gRXhwZWN0IHRoZSBub25lIG9mIHRoZSBkaWZmIGZpbGVzIHRvIHdvcmtcblx0XHRhd2FpdCBmaWxlTWF0Y2hEb3duc3RyZWFtKHRtcERpciwgXCJzcmMvaW5kZXgudHNcIik7XG5cdFx0YXdhaXQgZmlsZU1hdGNoRG93bnN0cmVhbSh0bXBEaXIsIFwicGx1Z2lucy9jdXN0b20tcGx1Z2luLmpzXCIpO1xuXHRcdGF3YWl0IGZpbGVNYXRjaERvd25zdHJlYW0odG1wRGlyLCBcInBhY2thZ2UuanNvblwiKTtcblxuXHRcdC8vIEVuc3VyZSB3ZSBoYXZlIHVwZGF0ZWQgdGhlIGxvY2FsIHRlbXBsYXRlIGZpZWxkXG5cdFx0ZXhwZWN0KFxuXHRcdFx0SlNPTi5wYXJzZShcblx0XHRcdFx0KGF3YWl0IHJlYWRGaWxlKGpvaW4odG1wRGlyLCBcInRlbXBsYXRlc3luYy5sb2NhbC5qc29uXCIpKSkudG9TdHJpbmcoKSxcblx0XHRcdCksXG5cdFx0KS50b0VxdWFsKHtcblx0XHRcdC4uLm1vY2tMb2NhbENvbmZpZyxcblx0XHR9KTtcblx0XHRleHBlY3QoZHVtbXlDaGVja291dERyaXZlcikubm90LnRvSGF2ZUJlZW5DYWxsZWQoKTtcblx0fSk7XG5cdGl0KFwiY3JlYXRlcyB0aGUgbG9jYWwgdGVtcGxhdGVzeW5jIHdpdGggdGhlIGN1cnJlbnQgcmVmIGlmIHVwZGF0ZUFmdGVyUmVmIGlzIHRydWUgYW5kIG5vIGxvY2FsIHRlbXBsYXRlIGV4aXN0c1wiLCBhc3luYyAoKSA9PiB7XG5cdFx0Ly8gUmVtb3ZlIHRoZSBsb2NhbCBzeW5jIG92ZXJyaWRlc1xuXHRcdGF3YWl0IHJtKGpvaW4odG1wRGlyLCBcInRlbXBsYXRlc3luYy5sb2NhbC5qc29uXCIpKTtcblxuXHRcdC8vIFdlIHdpbGwgb25seSB1cGRhdGUgdGhlIHRlbXBsYXRlZC50c1xuXHRcdGNvbnN0IG1vY2tEaWZmRHJpdmVyID0gamVzdC5mbigpLm1vY2tJbXBsZW1lbnRhdGlvbihhc3luYyAoKSA9PiAoe1xuXHRcdFx0YWRkZWQ6IFtcInNyYy90ZW1wbGF0ZWQudHNcIl0sXG5cdFx0fSkpO1xuXHRcdGNvbnN0IG1vY2tDdXJyZW50UmVmRHJpdmVyID0gamVzdFxuXHRcdFx0LmZuKClcblx0XHRcdC5tb2NrSW1wbGVtZW50YXRpb24oYXN5bmMgKCkgPT4gXCJuZXdlc3RTaGFcIik7XG5cdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgdGVtcGxhdGVTeW5jKHtcblx0XHRcdHRtcENsb25lRGlyOiBcInN0dWJiZWQtYnktZHJpdmVyXCIsXG5cdFx0XHRjbG9uZURyaXZlcjogZHVtbXlDbG9uZURyaXZlcixcblx0XHRcdHJlcG9Vcmw6IFwibm90LWltcG9ydGFudFwiLFxuXHRcdFx0cmVwb0RpcjogdG1wRGlyLFxuXHRcdFx0dXBkYXRlQWZ0ZXJSZWY6IHRydWUsXG5cdFx0XHRkaWZmRHJpdmVyOiBtb2NrRGlmZkRyaXZlcixcblx0XHRcdGN1cnJlbnRSZWZEcml2ZXI6IG1vY2tDdXJyZW50UmVmRHJpdmVyLFxuXHRcdFx0Y2hlY2tvdXREcml2ZXI6IGR1bW15Q2hlY2tvdXREcml2ZXIsXG5cdFx0fSk7XG5cblx0XHQvLyBzaW5jZSB0aGVyZSB3YXMgbm8gb3ZlcnJpZGUgZm9yIHRoaXMgZmlsZSwgbm8gY2hhbmdlcyBmcm9tIHRoZSBsb2NhbCBmaWxlXG5cdFx0ZXhwZWN0KHJlc3VsdC5sb2NhbEZpbGVDaGFuZ2VzKS50b0VxdWFsKGV4cGVjdC5vYmplY3RDb250YWluaW5nKHt9KSk7XG5cdFx0ZXhwZWN0KHJlc3VsdC5tb2RpZmllZEZpbGVzKS50b0VxdWFsKHtcblx0XHRcdGFkZGVkOiBbXG5cdFx0XHRcdFwicGFja2FnZS5qc29uXCIsXG5cdFx0XHRcdFwic3JjL2luZGV4LmpzXCIsXG5cdFx0XHRcdFwic3JjL3RlbXBsYXRlZC5qc1wiLFxuXHRcdFx0XHRcInNyYy90ZW1wbGF0ZWQudHNcIixcblx0XHRcdFx0XCJ0ZW1wbGF0ZXN5bmMuanNvblwiLFxuXHRcdFx0XHRcInRlbXBsYXRlc3luYy5sb2NhbC5qc29uXCIsXG5cdFx0XHRdLFxuXHRcdFx0ZGVsZXRlZDogW10sXG5cdFx0XHRtb2RpZmllZDogW10sXG5cdFx0XHR0b3RhbDogNixcblx0XHR9KTtcblxuXHRcdC8vIFZlcmlmeSB0aGUgZmlsZXNcblx0XHRhd2FpdCBmaWxlTWF0Y2hUZW1wbGF0ZSh0bXBEaXIsIFwidGVtcGxhdGVzeW5jLmpzb25cIik7XG5cdFx0YXdhaXQgZmlsZU1hdGNoVGVtcGxhdGUodG1wRGlyLCBcInNyYy90ZW1wbGF0ZWQudHNcIik7XG5cdFx0Y29uc3QgcGFja2FnZUpzb24gPSBKU09OLnBhcnNlKFxuXHRcdFx0cmVhZEZpbGVTeW5jKHJlc29sdmUodG1wRGlyLCBcInBhY2thZ2UuanNvblwiKSkudG9TdHJpbmcoKSxcblx0XHQpO1xuXG5cdFx0ZXhwZWN0KHBhY2thZ2VKc29uKS50b0VxdWFsKHtcblx0XHRcdG5hbWU6IFwibXlwa2dcIixcblx0XHRcdGRlc2NyaXB0aW9uOiBcIm15IGRlc2NyaXB0aW9uXCIsXG5cdFx0XHRkZXBlbmRlbmNpZXM6IHtcblx0XHRcdFx0bXlwYWNrYWdlOiBcIl4xLjIuMFwiLFxuXHRcdFx0XHRuZXdwYWNha2dlOiBcIl4yMi4yLjJcIixcblx0XHRcdFx0cGFja2FnZTI6IFwiMy4yMi4xXCIsXG5cdFx0XHRcdGh1aDogXCJ+MS4wLjBcIixcblx0XHRcdH0sXG5cdFx0XHRlbmdpbmVzOiB7XG5cdFx0XHRcdG5vZGU6IFwiPj0xNVwiLFxuXHRcdFx0fSxcblx0XHRcdHNjcmlwdHM6IHtcblx0XHRcdFx0YnVpbGQ6IFwiYnVpbGRcIixcblx0XHRcdFx0dGVzdDogXCJqZXN0XCIsXG5cdFx0XHRcdG15c2NyaXB0OiBcInNvbWVzY3JpcHRcIixcblx0XHRcdH0sXG5cdFx0XHQvLyBCeSBkZWZhdWx0IHdlIGFkZCBuZXcgdG9wLWxldmVsIGZpZWxkc1xuXHRcdFx0dmVyc2lvbjogXCJuZXctdmVyc2lvblwiLFxuXHRcdH0pO1xuXG5cdFx0Ly8gRXhwZWN0IHRoZSBub25lIG9mIHRoZSBkaWZmIGZpbGVzIHRvIHdvcmtcblx0XHRhd2FpdCBmaWxlTWF0Y2hEb3duc3RyZWFtKHRtcERpciwgXCJzcmMvaW5kZXgudHNcIik7XG5cdFx0YXdhaXQgZmlsZU1hdGNoRG93bnN0cmVhbSh0bXBEaXIsIFwicGx1Z2lucy9jdXN0b20tcGx1Z2luLmpzXCIpO1xuXG5cdFx0Ly8gRW5zdXJlIHdlIGhhdmUgdXBkYXRlZCB0aGUgbG9jYWwgdGVtcGxhdGUgZmllbGRcblx0XHRleHBlY3QoXG5cdFx0XHRKU09OLnBhcnNlKFxuXHRcdFx0XHQoYXdhaXQgcmVhZEZpbGUoam9pbih0bXBEaXIsIFwidGVtcGxhdGVzeW5jLmxvY2FsLmpzb25cIikpKS50b1N0cmluZygpLFxuXHRcdFx0KSxcblx0XHQpLnRvRXF1YWwoe1xuXHRcdFx0YWZ0ZXJSZWY6IFwibmV3ZXN0U2hhXCIsXG5cdFx0fSk7XG5cdH0pO1xuXHQvLyBoZWxwZXJcblx0YXN5bmMgZnVuY3Rpb24gZmlsZU1hdGNoVGVtcGxhdGUoX3RtcERpcjogc3RyaW5nLCByZWxQYXRoOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gZmlsZU1hdGNoKF90bXBEaXIsIHJlbFBhdGgsIFwidGVtcGxhdGVcIik7XG5cdH1cblxuXHRhc3luYyBmdW5jdGlvbiBmaWxlTWF0Y2hEb3duc3RyZWFtKF90bXBEaXI6IHN0cmluZywgcmVsUGF0aDogc3RyaW5nKSB7XG5cdFx0cmV0dXJuIGZpbGVNYXRjaChfdG1wRGlyLCByZWxQYXRoLCBcImRvd25zdHJlYW1cIik7XG5cdH1cblxuXHRhc3luYyBmdW5jdGlvbiBmaWxlTWF0Y2goXG5cdFx0X3RtcERpcjogc3RyaW5nLFxuXHRcdHJlbFBhdGg6IHN0cmluZyxcblx0XHRzb3VyY2U6IFwiZG93bnN0cmVhbVwiIHwgXCJ0ZW1wbGF0ZVwiLFxuXHQpIHtcblx0XHRjb25zdCBkaXIgPVxuXHRcdFx0c291cmNlID09PSBcImRvd25zdHJlYW1cIiA/IGRvd25zdHJlYW1EaXIgOiAoYXdhaXQgZHVtbXlDbG9uZURyaXZlcigpKS5kaXI7XG5cdFx0ZXhwZWN0KChhd2FpdCByZWFkRmlsZShyZXNvbHZlKF90bXBEaXIsIHJlbFBhdGgpKSkudG9TdHJpbmcoKSkudG9FcXVhbChcblx0XHRcdChhd2FpdCByZWFkRmlsZShyZXNvbHZlKGRpciwgcmVsUGF0aCkpKS50b1N0cmluZygpLFxuXHRcdCk7XG5cdH1cbn0pO1xuIl0sIm5hbWVzIjpbImR1bW15Q2hlY2tvdXREcml2ZXIiLCJqZXN0IiwiZm4iLCJkdW1teUN1cnJlbnRSZWZEcml2ZXIiLCJkb3duc3RyZWFtRGlyIiwicmVzb2x2ZSIsIlRFU1RfRklYVFVSRVNfRElSIiwiZGVzY3JpYmUiLCJ0bXBEaXIiLCJ0ZW1wbGF0ZURpciIsImR1bW15Q2xvbmVEcml2ZXIiLCJiZWZvcmVFYWNoIiwicmVzZXRBbGxNb2NrcyIsIm1rZHRlbXAiLCJ0ZW1wRGlyIiwiY29weSIsImRpciIsInJlbW90ZU5hbWUiLCJhZnRlckVhY2giLCJybSIsImZvcmNlIiwicmVjdXJzaXZlIiwiaXQiLCJlYWNoIiwibW9kZSIsImV4cGVjdGVkIiwiam9pbiIsIndyaXRlRmlsZVN5bmMiLCJKU09OIiwic3RyaW5naWZ5IiwiaWdub3JlIiwibWVyZ2UiLCJnbG9iIiwicGx1Z2luIiwib3B0aW9ucyIsImV4cGVjdCIsInRlbXBsYXRlU3luYyIsInRtcENsb25lRGlyIiwiY2xvbmVEcml2ZXIiLCJyZXBvVXJsIiwicmVwb0RpciIsImNoZWNrb3V0RHJpdmVyIiwiY3VycmVudFJlZkRyaXZlciIsInJlamVjdHMiLCJ0b1Rocm93IiwiZW1wdHlUbXBEaXIiLCJ0b0VxdWFsIiwibG9jYWxTa2lwRmlsZXMiLCJsb2NhbEZpbGVDaGFuZ2VzIiwibW9kaWZpZWRGaWxlcyIsImFkZGVkIiwiZGVsZXRlZCIsIm1vZGlmaWVkIiwidG90YWwiLCJmaWxlTWF0Y2hUZW1wbGF0ZSIsImV4aXN0c1N5bmMiLCJ0b0JlRmFsc3kiLCJub3QiLCJ0b0hhdmVCZWVuQ2FsbGVkIiwiYnJhbmNoIiwiY2xvbmVJbmZvIiwidG9IYXZlQmVlbkNhbGxlZFdpdGgiLCJyZXN1bHQiLCJwYWNrYWdlSnNvbiIsInBhcnNlIiwicmVhZEZpbGVTeW5jIiwidG9TdHJpbmciLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJkZXBlbmRlbmNpZXMiLCJteXBhY2thZ2UiLCJuZXdwYWNha2dlIiwicGFja2FnZTIiLCJodWgiLCJlbmdpbmVzIiwibm9kZSIsInNjcmlwdHMiLCJidWlsZCIsInRlc3QiLCJteXNjcmlwdCIsInZlcnNpb24iLCJmaWxlTWF0Y2hEb3duc3RyZWFtIiwib2JqZWN0Q29udGFpbmluZyIsImFycmF5Q29udGFpbmluZyIsImRvd25zdHJlYW0iLCJhZnRlclJlZiIsIm1vY2tEaWZmRHJpdmVyIiwibW9ja0ltcGxlbWVudGF0aW9uIiwiZGlmZkRyaXZlciIsIm1vY2tMb2NhbENvbmZpZyIsIm1vY2tDdXJyZW50UmVmRHJpdmVyIiwidXBkYXRlQWZ0ZXJSZWYiLCJyZWFkRmlsZSIsIl90bXBEaXIiLCJyZWxQYXRoIiwiZmlsZU1hdGNoIiwic291cmNlIl0sIm1hcHBpbmdzIjoiOzs7O29CQUF3RDswQkFDbEI7eUJBQ2pCO3NCQUNTOzhCQUNEOzJCQUNjO0FBRTNDLE1BQU1BLHNCQUFzQkMsS0FBS0MsRUFBRTtBQUNuQyxNQUFNQyx3QkFBd0JGLEtBQUtDLEVBQUU7QUFFckMsTUFBTUUsZ0JBQWdCQyxJQUFBQSxhQUFPLEVBQUNDLDRCQUFpQixFQUFFO0FBRWpEQyxTQUFTLGdCQUFnQjtJQUN4QixJQUFJQztJQUNKLElBQUlDO0lBQ0osSUFBSUM7SUFDSkMs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
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ TEST_FIXTURES_DIR: function() {
13
+ return TEST_FIXTURES_DIR;
14
+ },
15
+ tempDir: function() {
16
+ return tempDir;
17
+ }
18
+ });
19
+ const _os = require("os");
20
+ const _path = require("path");
21
+ const TEST_FIXTURES_DIR = (0, _path.resolve)(__dirname, "..", "..", "test-fixtures");
22
+ function tempDir() {
23
+ return process.env.RUNNER_TEMP ?? (0, _os.tmpdir)();
24
+ }
25
+
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0LXV0aWxzL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHRtcGRpciB9IGZyb20gXCJvc1wiO1xuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gXCJwYXRoXCI7XG5cbmV4cG9ydCBjb25zdCBURVNUX0ZJWFRVUkVTX0RJUiA9IHJlc29sdmUoXG5cdF9fZGlybmFtZSxcblx0XCIuLlwiLFxuXHRcIi4uXCIsXG5cdFwidGVzdC1maXh0dXJlc1wiLFxuKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHRlbXBEaXIoKTogc3RyaW5nIHtcblx0cmV0dXJuIHByb2Nlc3MuZW52LlJVTk5FUl9URU1QID8/IHRtcGRpcigpO1xufVxuIl0sIm5hbWVzIjpbIlRFU1RfRklYVFVSRVNfRElSIiwidGVtcERpciIsInJlc29sdmUiLCJfX2Rpcm5hbWUiLCJwcm9jZXNzIiwiZW52IiwiUlVOTkVSX1RFTVAiLCJ0bXBkaXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0lBR2FBLGlCQUFpQjtlQUFqQkE7O0lBT0dDLE9BQU87ZUFBUEE7OztvQkFWTztzQkFDQztBQUVqQixNQUFNRCxvQkFBb0JFLElBQUFBLGFBQU8sRUFDdkNDLFdBQ0EsTUFDQSxNQUNBO0FBR00sU0FBU0Y7SUFDZixPQUFPRyxRQUFRQyxHQUFHLENBQUNDLFdBQVcsSUFBSUMsSUFBQUEsVUFBTTtBQUN6QyJ9
@@ -0,0 +1,12 @@
1
+ /**
2
+ * How we want to merge json
3
+ *
4
+ * overwrite - the template sync overwrites completely
5
+ * merge-template - we merge template into the current json with overrides on matching values happening from the template
6
+ * merge-current - we merge the current json into the template json with overrides on matching values happening from the current json
7
+ */ "use strict";
8
+ Object.defineProperty(exports, "__esModule", {
9
+ value: true
10
+ });
11
+
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEhvdyB3ZSB3YW50IHRvIG1lcmdlIGpzb25cbiAqXG4gKiBvdmVyd3JpdGUgLSB0aGUgdGVtcGxhdGUgc3luYyBvdmVyd3JpdGVzIGNvbXBsZXRlbHlcbiAqIG1lcmdlLXRlbXBsYXRlIC0gd2UgbWVyZ2UgdGVtcGxhdGUgaW50byB0aGUgY3VycmVudCBqc29uIHdpdGggb3ZlcnJpZGVzIG9uIG1hdGNoaW5nIHZhbHVlcyBoYXBwZW5pbmcgZnJvbSB0aGUgdGVtcGxhdGVcbiAqIG1lcmdlLWN1cnJlbnQgLSB3ZSBtZXJnZSB0aGUgY3VycmVudCBqc29uIGludG8gdGhlIHRlbXBsYXRlIGpzb24gd2l0aCBvdmVycmlkZXMgb24gbWF0Y2hpbmcgdmFsdWVzIGhhcHBlbmluZyBmcm9tIHRoZSBjdXJyZW50IGpzb25cbiAqL1xuZXhwb3J0IHR5cGUgQmFzZUpzb25NZXJnZU9wdGlvbnMgPVxuXHR8IFwib3ZlcndyaXRlXCJcblx0fCBcIm1lcmdlLXRlbXBsYXRlXCJcblx0fCBcIm1lcmdlLWN1cnJlbnRcIjtcbmV4cG9ydCBpbnRlcmZhY2UgSnNvblBhdGhPdmVycmlkZXMge1xuXHQvKipcblx0ICogSWYgc2V0IHRvIHRydWUsIHRoaXMgbWVhbnMgd2Ugd29uJ3QgYWRkIG5ldyBwcm9wZXJ0aWVzIGZyb20gdGhlIHRlbXBsYXRlXG5cdCAqL1xuXHRpZ25vcmVOZXdQcm9wZXJ0aWVzPzogYm9vbGVhbjtcblx0LyoqXG5cdCAqIElmIHNldCB0byB0cnVlLCBvdmVyd3JpdGUgd2lsbCBhcHBseSB1bmRlZmluZWQgdmFsdWVzIGFzIGRlbGV0ZWQgZm9yIHRoZSBqc29ucGF0aHNcblx0ICogb3IgZm9yIHZhbHVlcyB0aGF0IGFyZSBzdXBwb3NlZCB0byBiZSBtZXJnZWQgb24gdG9wIG9mIG90aGVyIHZhbHVlc1xuXHQgKi9cblx0bWlzc2luZ0lzRGVsZXRlPzogYm9vbGVhbjtcblx0LyoqXG5cdCAqIE5vdGUsIGlmIG11bHRpcGxlIGpzb24gcGF0aHMgbWF0Y2ggYSBydWxlLCB3ZSBwaWNrIHRoZSBmaXJzdCBvbmUgaW4gdGhlIGxpc3QgdGhhdCBtYXRjaGVzXG5cdCAqL1xuXHRwYXRoczogLyoqXG5cdCAqIFdlIG9ubHkgb3ZlcnJpZGUganNvbnBhdGhzLiAgQW55dGhpbmcgbm90IHNwZWNpZmllZCBpcyBrZXB0IHRoZSBzYW1lLlxuXHQgKi9cblx0W2pzb25QYXRoOiBgJC4ke3N0cmluZ31gLCBvcHRpb25zOiBCYXNlSnNvbk1lcmdlT3B0aW9uc11bXTtcbn1cbmV4cG9ydCB0eXBlIEpzb25GaWxlTWVyZ2VPcHRpb25zID0gQmFzZUpzb25NZXJnZU9wdGlvbnMgfCBKc29uUGF0aE92ZXJyaWRlcztcblxuLy8gU3VtIG9mIGFsbCBiYXNpYyBmaWxlIG1lcmdlIG9wdGlvbnNcbnR5cGUgTWVyZ2VQbHVnaW5PcHRpb25zID0gSnNvbkZpbGVNZXJnZU9wdGlvbnM7XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBvYmplY3QgZm9yIGEgZ2l2ZW4gZmlsZSB0eXBlIG1lcmdlIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXJnZUNvbmZpZzxUPiB7XG5cdC8qKlxuXHQgKiBBIGdsb2Igb3IgYXJyYXkgb2YgZ2xvYnMgKHVzaW5nIG1pY3JvbWF0Y2ggc3ludGF4KSB0aGF0IHNlbGVjdHMgdGhlIGZpbGVzIHRoYXQgdGhpcyBhcHBsaWVzIHRvXG5cdCAqIHdoZW4gbWVyZ2luZ1xuXHQgKi9cblx0Z2xvYjogc3RyaW5nIHwgc3RyaW5nW107XG5cdC8qKlxuXHQgKiBUaGUgbm9kZSBtb2R1bGUsIGF2YWlsYWJsZSBvbiB0aGUgY2FsbGluZyBub2RlIGNvbnRleHQsIHRoYXQgeW91IHdhbnQgdG8gcnVuLlxuXHQgKiBCdWlsdC1pbiBwbHVnaW5zIGNhbiBiZSBzcGVjaWZpZWQgdmlhIHRoZWlyIGJ1aWx0LWluIG5hbWUgKHNlZSBkb2N1bWVudGF0aW9uKTpcblx0ICpcblx0ICogRXhhbXBsZTogX2pzb25cblx0ICovXG5cdHBsdWdpbjogc3RyaW5nO1xuXHQvKipcblx0ICogQW4gYXJyYXkgb2YgZmlyc3QgbWF0Y2ggZmlsZSBnbG9icyB0aGF0IHdpbGwgdGhlbiBjYWxsIHRoZSBwbHVnaW4gd2l0aCB0aGUgYXBwcm9wcmlhdGUgb3B0aW9uc1xuXHQgKi9cblx0b3B0aW9uczogTWVyZ2VQbHVnaW5PcHRpb25zIHwgVDtcbn1cblxuLyoqXG4gKiBUaGUgc2hhcGUgb2YgYSB0ZW1wbGF0ZSBzeW5jIGNvbmZpZyBmaWxlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnPFQgPSB1bmtub3duPiB7XG5cdGlnbm9yZTogc3RyaW5nW107XG5cdC8qKlxuXHQgKiBJZiB0aGVyZSBpcyBubyBtZXJnZSBjb25maWcsIHRoZW4gd2Ugd2lsbCBhbHdheXMganVzdCBvdmVyd3JpdGUgdGhlIGZpbGUgZm9yIHRoZSBkaWZmXG5cdCAqL1xuXHRtZXJnZT86IE1lcmdlQ29uZmlnPFQ+W107XG59XG5cbi8qKlxuICogVGhlIHNoYXBlIG9mIGEgbG9jYWwgdGVtcGxhdGUgc3luYyBjb25maWcgZmlsZSB0aGF0IG92ZXJyaWRlcyB0aGUgcm9vdCB0ZW1wbGF0ZSByZXBvXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTG9jYWxDb25maWc8VCA9IHVua25vd24+IHtcblx0LyoqXG5cdCAqIFRoaXMgaXMgdGhlIHJlZiB0aGF0IHdlIGNvbXBhcmUgYWdhaW5zdC4gIElmIGVtcHR5LCB3ZSB1c2UgYWxsIGZpbGVzIHRoYXQgaGF2ZSBjaGFuZ2VkIHNpbmNlIHRoZVxuXHQgKiBiZWdpbm5pbmcgb2YgdGhlIHRlbXBsYXRlIHJlcG8uXG5cdCAqL1xuXHRhZnRlclJlZj86IHN0cmluZztcblxuXHRpZ25vcmU6IHN0cmluZ1tdO1xuXHQvKipcblx0ICogSWYgdGhlcmUgaXMgbm8gbWVyZ2UgY29uZmlnLCB0aGVuIHdlIHdpbGwgYWx3YXlzIGp1c3Qgb3ZlcndyaXRlIHRoZSBmaWxlIGZvciB0aGUgZGlmZlxuXHQgKi9cblx0bWVyZ2U/OiBNZXJnZUNvbmZpZzxUPltdO1xufVxuXG4vKipcbiAqIEluZm9ybWF0aW9uIGFyb3VuZCB0aGUgZmlsZSB3ZSBhcmUgdHJ5aW5nIHRvIG1lcmdlIGFuZCB0aGF0IGFyZ3VtZW50cyBmb3IgdGhhdCBtZXJnZVxuICogZnJvbSBtYXRjaGluZyBhIG1lcmdlIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXJnZUNvbnRleHQ8UGx1Z2luT3B0aW9ucyA9IHVua25vd24+IHtcblx0cmVsRmlsZVBhdGg6IHN0cmluZztcblx0LyoqXG5cdCAqIElmIHlvdSBoYXZlIHByb3ZpZGVkIGEgY3VzdG9tIG1lcmdlIHBsdWdpbiwgdGhpcyB3aWxsIGJlIHRoZSBcIm9wdGlvbnNcIiBzZWN0aW9uIG9mXG5cdCAqIHRoZSBtYXRjaGluZyBnbG9iXG5cdCAqL1xuXHRtZXJnZUFyZ3VtZW50czogUGx1Z2luT3B0aW9ucztcblx0LyoqXG5cdCAqIElmIHRoaXMgcnVuIGlzIGZvciB0aGUgbG9jYWwgY29uZmlnLiAgS2VlcCBpbiBtaW5kIHRoYXQgYW55IGxvY2FsIGNvbmZpZyBvdmVycmlkZXMgd2lsbFxuXHQgKiBiZSBydW4gYWZ0ZXIgdGhlIHRlbXBsYXRlIHN5bmMgb3B0aW9ucyBhbmQgd2Ugd291bGQgbGlrZSB0byByZXBvcnQgYW55IGNoYW5nZXMgdGhhdFxuXHQgKiBhcmUgZG9uZVxuXHQgKi9cblx0aXNMb2NhbE9wdGlvbnM/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1lcmdlUGx1Z2luPFBsdWdpbk9wdGlvbnM+IHtcblx0LyoqXG5cdCAqIFRoaXMgbWV0aG9kIHdpbGwgYmUgY2FsbGVkIHdoZW4gYSBmaWxlIGZyb20gdGhlIHRlbXBsYXRlIGFuZCBpdCdzIGFuYWxvZyBpbiB0aGUgZG93bnN0cmVhbSByZXBvXG5cdCAqIGhhdmUgc29tZSBkaWZmZXJlbmNlcy4gIFRoZSBwbHVnaW4gbXVzdCBwZXJmb3JtIHRoZSBtZXJnZSBhbmQgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSBmaWxlIGNvbnRlbnRzXG5cdCAqIGFzIGEgc3RyaW5nXG5cdCAqXG5cdCAqIFRPRE86IHdlIG1heSBjcmVhdGUgYSBWMiBwbHVnaW4gdGhhdCBjb3VsZCBkZWFsIHdpdGggbGFyZ2UgZmlsZXMgYW5kIG5vdCBwYXNzIGFyb3VuZCBzdHJpbmdzIGluIG1lbW9yeSxcblx0ICogYnV0IGZvciBub3csIHRoaXMgaXMgdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb25cblx0ICpcblx0ICogQHBhcmFtIGN1cnJlbnQgLSBUaGUgZG93bnN0cmVhbSByZXBvcyBjdXJyZW50IGZpbGUgY29udGVudHNcblx0ICogQHBhcmFtIGZyb21UZW1wbGF0ZVJlcG8gLSB0aGUgY3VycmVudFxuXHQgKiBAcGFyYW0gY29udGV4dCAtIGFuIG9iamVjdCBkZWZpbmluZyB0aGUgY29udGV4dCBhcm91bmQgdGhlIGZpbGUgYW5kIHRoZSBzcGVjaWZpYyBvcHRpb25zXG5cdCAqL1xuXHRtZXJnZShcblx0XHRjdXJyZW50OiBzdHJpbmcsXG5cdFx0ZnJvbVRlbXBsYXRlUmVwbzogc3RyaW5nLFxuXHRcdGNvbnRleHQ6IE1lcmdlQ29udGV4dDxQbHVnaW5PcHRpb25zPixcblx0KTogUHJvbWlzZTxzdHJpbmc+O1xuXHQvKipcblx0ICogR2l2ZW4gYW4gb3B0aW9ucyBvYmplY3QgZm9yIHRoZSBtZXJnZSwgdGhpcyB2YWxpZGF0ZXMgdGhlIG9wdGlvbnMgb2JqZWN0IGFuZCByZXR1cm5zIGVycm9yIG1lc3NhZ2VzIGlmIHRoZXJlIGlzIGFueXRoaW5nIHdyb25nLlxuXHQgKiBAcGFyYW0gb3B0aW9ucyBhbnkganNvbiB2YWx1ZSB0aGF0IHRoZSB1c2VyIHByb3ZpZGVkIC0gbXVzdCBiZSB2YWxpZGF0ZWQgYWdhaW5zdCB0aGUgZXhwZWN0ZWQgb3B0aW9uc1xuXHQgKi9cblx0dmFsaWRhdGUob3B0aW9uczogdW5rbm93bik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgdHlwZSBGaWxlT3BlcmF0aW9uID0gXCJhZGRlZFwiIHwgXCJtb2RpZmllZFwiIHwgXCJkZWxldGVkXCI7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztDQU1DIn0=