@salty-css/core 0.0.1-alpha.28 → 0.0.1-alpha.280

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 (101) hide show
  1. package/.saltyrc.schema.json +48 -0
  2. package/README.md +469 -26
  3. package/bin/logger.d.ts +1 -0
  4. package/bin/main.cjs +8 -5
  5. package/bin/main.js +230 -100
  6. package/cache/resolve-dynamic-config-cache.cjs +1 -0
  7. package/cache/resolve-dynamic-config-cache.d.ts +1 -0
  8. package/cache/resolve-dynamic-config-cache.js +10 -0
  9. package/compiler/get-files.d.ts +3 -0
  10. package/compiler/get-function-range.d.ts +1 -0
  11. package/compiler/index.cjs +1 -11
  12. package/compiler/index.d.ts +19 -11
  13. package/compiler/index.js +19 -172
  14. package/config/define-config.d.ts +1 -1
  15. package/config/index.cjs +1 -1
  16. package/config/index.d.ts +2 -1
  17. package/config/index.js +12 -2
  18. package/css/index.cjs +1 -1
  19. package/css/index.d.ts +4 -1
  20. package/css/index.js +10 -2
  21. package/css/keyframes.cjs +1 -0
  22. package/css/keyframes.d.ts +22 -0
  23. package/css/keyframes.js +34 -0
  24. package/css/media.cjs +1 -0
  25. package/css/media.d.ts +87 -0
  26. package/css/media.js +88 -0
  27. package/css/merge.cjs +1 -0
  28. package/css/merge.d.ts +7 -0
  29. package/css/merge.js +5 -0
  30. package/css/token.cjs +1 -0
  31. package/css/token.d.ts +1 -0
  32. package/css/token.js +4 -0
  33. package/{dash-case-DKzpenwY.cjs → dash-case-BJEkFEGQ.cjs} +1 -1
  34. package/{dash-case-DMQMcCO6.js → dash-case-DBThphLm.js} +2 -2
  35. package/define-templates-4A2yHcMF.js +52 -0
  36. package/define-templates-Cunsb_Tr.cjs +1 -0
  37. package/factories/define-global-styles.d.ts +7 -0
  38. package/factories/define-media-query.d.ts +8 -0
  39. package/factories/define-templates.d.ts +27 -0
  40. package/factories/define-variables.d.ts +12 -0
  41. package/factories/index.cjs +1 -0
  42. package/factories/index.d.ts +4 -0
  43. package/factories/index.js +30 -0
  44. package/generators/class-name-generator.d.ts +6 -0
  45. package/generators/index.cjs +1 -0
  46. package/generators/index.d.ts +2 -0
  47. package/generators/index.js +88 -0
  48. package/generators/styled-generator.d.ts +20 -0
  49. package/generators/styles-generator.d.ts +22 -0
  50. package/helpers/color.d.ts +18 -0
  51. package/helpers/index.cjs +1 -0
  52. package/helpers/index.d.ts +2 -0
  53. package/helpers/index.js +1154 -0
  54. package/helpers/viewport-clamp.d.ts +8 -0
  55. package/index-BgHtTuZf.cjs +41 -0
  56. package/index-CXjwv_Dc.js +519 -0
  57. package/package.json +54 -6
  58. package/parse-styles-Bdgw_4ME.cjs +5 -0
  59. package/parse-styles-C1E6ETeH.js +154 -0
  60. package/parsers/index.cjs +2 -0
  61. package/parsers/index.d.ts +5 -0
  62. package/parsers/index.js +33 -0
  63. package/parsers/parse-modifiers.d.ts +3 -0
  64. package/parsers/parse-styles.d.ts +13 -0
  65. package/parsers/parse-templates.d.ts +4 -0
  66. package/parsers/parse-tokens.d.ts +3 -0
  67. package/parsers/parser-types.d.ts +8 -0
  68. package/parsers/property-name-check.d.ts +1 -0
  69. package/parsers/unit-check.d.ts +7 -0
  70. package/react-vanilla-file-CCXbsjIb.js +18 -0
  71. package/react-vanilla-file-CG_WJLam.cjs +15 -0
  72. package/{salty.config-D9ANEDiH.js → salty.config-BhBY_oOk.js} +1 -0
  73. package/{salty.config-BupieCfE.cjs → salty.config-Dk6ZcCxI.cjs} +3 -2
  74. package/server/index.cjs +1 -0
  75. package/server/index.d.ts +1 -0
  76. package/server/index.js +4 -0
  77. package/server/should-restart.d.ts +1 -0
  78. package/should-restart-BELKpXEw.js +12 -0
  79. package/should-restart-CBwAaej8.cjs +1 -0
  80. package/templates/salty-reset.d.ts +2 -0
  81. package/types/cli-types.d.ts +10 -0
  82. package/types/config-types.d.ts +85 -0
  83. package/types/index.d.ts +53 -22
  84. package/util/dot-case.d.ts +1 -0
  85. package/util/index.cjs +1 -1
  86. package/util/index.js +1 -1
  87. package/util/module-type.d.ts +1 -0
  88. package/viewport-clamp-BOc-8Oph.js +7 -0
  89. package/viewport-clamp-kY8JqYzm.cjs +1 -0
  90. package/config/config-types.d.ts +0 -59
  91. package/generator/index.cjs +0 -1
  92. package/generator/index.d.ts +0 -1
  93. package/generator/index.js +0 -61
  94. package/generator/parse-modifiers.d.ts +0 -3
  95. package/generator/parse-styles.d.ts +0 -2
  96. package/generator/parse-templates.d.ts +0 -2
  97. package/generator/parse-tokens.d.ts +0 -2
  98. package/generator/parser-types.d.ts +0 -4
  99. package/generator/style-generator.d.ts +0 -28
  100. package/parse-templates-D4p3pgQR.js +0 -92
  101. package/parse-templates-W0YfTmOT.cjs +0 -8
@@ -0,0 +1,519 @@
1
+ import * as Xg from "esbuild";
2
+ import { execSync as Hg } from "child_process";
3
+ import { t as Q, d as E } from "./dash-case-DBThphLm.js";
4
+ import { join as b, parse as gg } from "path";
5
+ import { existsSync as ag, writeFileSync as p, mkdirSync as f, readFileSync as F, statSync as Kg, readdirSync as zg } from "fs";
6
+ import { readFile as pg } from "fs/promises";
7
+ import { p as Yg, a as wg } from "./parse-styles-C1E6ETeH.js";
8
+ import { parseTemplates as Sg, getTemplateTypes as vg } from "./parsers/index.js";
9
+ import { createLogger as kg, format as ng, transports as jg } from "winston";
10
+ import { mergeObjects as U, mergeFactories as xg } from "./css/merge.js";
11
+ import { d as fg } from "./define-templates-4A2yHcMF.js";
12
+ import tg from "typescript";
13
+ const Vg = (g) => {
14
+ if (!g || g === "/") throw new Error("Could not find package.json file");
15
+ const I = b(g, "package.json");
16
+ return ag(I) ? I : Vg(b(g, ".."));
17
+ }, Ug = async (g) => {
18
+ const I = Vg(g);
19
+ return await pg(I, "utf-8").then(JSON.parse).catch(() => {
20
+ });
21
+ }, Qg = async (g) => {
22
+ const I = await Ug(g);
23
+ if (I)
24
+ return I.type;
25
+ };
26
+ let x;
27
+ const Ng = async (g) => {
28
+ if (x) return x;
29
+ const I = await Qg(g);
30
+ return I === "module" ? x = "esm" : (I === "commonjs" || import.meta.url.endsWith(".cjs")) && (x = "cjs"), x || "esm";
31
+ }, _ = kg({
32
+ level: "debug",
33
+ format: ng.combine(ng.colorize(), ng.cli()),
34
+ transports: [new jg.Console({})]
35
+ }), tI = (g) => {
36
+ _.error(g);
37
+ };
38
+ function hg(g) {
39
+ return g ? typeof g != "string" ? hg(String(g)) : g.replace(/[^\d\w]/g, ".") : "";
40
+ }
41
+ const Tg = {
42
+ /** Set box model to border-box */
43
+ "*, *::before, *::after": {
44
+ boxSizing: "border-box"
45
+ },
46
+ /** Remove default margin and padding */
47
+ "*": {
48
+ margin: 0
49
+ },
50
+ /** Remove adjust font properties */
51
+ html: {
52
+ lineHeight: 1.15,
53
+ textSizeAdjust: "100%",
54
+ WebkitFontSmoothing: "antialiased"
55
+ },
56
+ /** Make media elements responsive */
57
+ "img, picture, video, canvas, svg": {
58
+ display: "block",
59
+ maxWidth: "100%"
60
+ },
61
+ /** Avoid overflow of text */
62
+ "p, h1, h2, h3, h4, h5, h6": {
63
+ overflowWrap: "break-word"
64
+ },
65
+ /** Improve text wrapping */
66
+ p: {
67
+ textWrap: "pretty"
68
+ },
69
+ "h1, h2, h3, h4, h5, h6": {
70
+ textWrap: "balance"
71
+ },
72
+ /** Improve link color */
73
+ a: {
74
+ color: "currentColor"
75
+ },
76
+ /** Improve button line height */
77
+ button: {
78
+ lineHeight: "1em",
79
+ color: "currentColor"
80
+ },
81
+ /** Improve form elements */
82
+ "input, optgroup, select, textarea": {
83
+ fontFamily: "inherit",
84
+ fontSize: "100%",
85
+ lineHeight: "1.15em"
86
+ }
87
+ }, Lg = (g, I) => new Promise((c, l) => {
88
+ const Z = setTimeout(() => {
89
+ l(new Error("Timeout"));
90
+ }, 100), n = tg.createSourceFile("temp.ts", g, tg.ScriptTarget.Latest, !0);
91
+ function C(G) {
92
+ if (tg.isVariableDeclaration(G) && G.name.getText() === I) {
93
+ const W = G.getStart(), e = G.getEnd();
94
+ clearTimeout(Z), c([W, e]);
95
+ }
96
+ G.forEachChild(C);
97
+ }
98
+ C(n);
99
+ }), Dg = new URL("data:video/mp2t;base64,LyogZXNsaW50LWRpc2FibGUgcHJlZmVyLWNvbnN0ICovCi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi8KaW1wb3J0ICogYXMgZXNidWlsZCBmcm9tICdlc2J1aWxkJzsKaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJzsKaW1wb3J0IHsgdG9IYXNoIH0gZnJvbSAnLi4vdXRpbC90by1oYXNoJzsKaW1wb3J0IHsgam9pbiwgcGFyc2UgYXMgcGFyc2VQYXRoIH0gZnJvbSAncGF0aCc7CmltcG9ydCB7IHN0YXRTeW5jLCBleGlzdHNTeW5jLCBta2RpclN5bmMsIHJlYWRkaXJTeW5jLCB3cml0ZUZpbGVTeW5jLCByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7CmltcG9ydCB7IGRhc2hDYXNlIH0gZnJvbSAnLi4vdXRpbC9kYXNoLWNhc2UnOwppbXBvcnQgeyByZWFkRmlsZSB9IGZyb20gJ2ZzL3Byb21pc2VzJzsKaW1wb3J0IHsgcGFyc2VBbmRKb2luU3R5bGVzIH0gZnJvbSAnLi4vcGFyc2Vycy9wYXJzZS1zdHlsZXMnOwppbXBvcnQgeyBnZXRUZW1wbGF0ZVR5cGVzLCBwYXJzZVRlbXBsYXRlcyB9IGZyb20gJy4uL3BhcnNlcnMvcGFyc2UtdGVtcGxhdGVzJzsKaW1wb3J0IHsgQ2FjaGVkQ29uZmlnLCBDc3NDb25kaXRpb25hbFZhcmlhYmxlcywgQ3NzUmVzcG9uc2l2ZVZhcmlhYmxlcywgQ3NzVGVtcGxhdGVzLCBTYWx0eUNvbmZpZywgU2FsdHlWYXJpYWJsZXMgfSBmcm9tICcuLi9jb25maWcnOwppbXBvcnQgeyBwYXJzZVZhcmlhYmxlVG9rZW5zIH0gZnJvbSAnLi4vcGFyc2Vycy9wYXJzZS10b2tlbnMnOwppbXBvcnQgeyBkZXRlY3RDdXJyZW50TW9kdWxlVHlwZSB9IGZyb20gJy4uL3V0aWwvbW9kdWxlLXR5cGUnOwppbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9iaW4vbG9nZ2VyJzsKaW1wb3J0IHsgZG90Q2FzZSB9IGZyb20gJy4uL3V0aWwvZG90LWNhc2UnOwppbXBvcnQgeyBzYWx0eVJlc2V0IH0gZnJvbSAnLi4vdGVtcGxhdGVzL3NhbHR5LXJlc2V0JzsKaW1wb3J0IHsgUkNGaWxlIH0gZnJvbSAnLi4vdHlwZXMvY2xpLXR5cGVzJzsKaW1wb3J0IHsgbWVyZ2VGYWN0b3JpZXMsIG1lcmdlT2JqZWN0cyB9IGZyb20gJy4uL2Nzcyc7CmltcG9ydCB7IGRlZmluZVRlbXBsYXRlcywgR2xvYmFsU3R5bGVzRmFjdG9yeSwgVGVtcGxhdGVzRmFjdG9yeSwgVmFyaWFibGVzRmFjdG9yeSB9IGZyb20gJy4uL2ZhY3Rvcmllcyc7CmltcG9ydCB7IFN0eWxlZEdlbmVyYXRvciwgQ2xhc3NOYW1lR2VuZXJhdG9yIH0gZnJvbSAnLi4vZ2VuZXJhdG9ycyc7CmltcG9ydCB7IFN0eWxlc0dlbmVyYXRvciB9IGZyb20gJy4uL2dlbmVyYXRvcnMvc3R5bGVzLWdlbmVyYXRvcic7CmltcG9ydCB7IGdldEZ1bmN0aW9uUmFuZ2UgfSBmcm9tICcuL2dldC1mdW5jdGlvbi1yYW5nZSc7CgppbnRlcmZhY2UgR2VuZXJhdG9yUmVzdWx0PFYgZXh0ZW5kcyBTdHlsZXNHZW5lcmF0b3I+IHsKICBnZW5lcmF0b3I6IFY7CiAgc3JjOiBzdHJpbmc7CiAgbmFtZTogc3RyaW5nOwp9CgppbnRlcmZhY2UgRnVuY3Rpb25SZXN1bHQ8ViBleHRlbmRzIG9iamVjdD4gewogIHZhbHVlOiBWOwogIHNyYzogc3RyaW5nOwogIG5hbWU6IHN0cmluZzsKfQoKaW50ZXJmYWNlIENvbmZpZ0dlbmVyYXRpb25SZXN1bHRzIHsKICBtZWRpYVF1ZXJpZXM6IFtzdHJpbmcsIHN0cmluZ11bXTsKICBnbG9iYWxTdHlsZXM6IEdsb2JhbFN0eWxlc0ZhY3RvcnlbXTsKICB2YXJpYWJsZXM6IFZhcmlhYmxlc0ZhY3RvcnlbXTsKICB0ZW1wbGF0ZXM6IFRlbXBsYXRlc0ZhY3RvcnlbXTsKfQoKaW50ZXJmYWNlIFN0eWxlc0dlbmVyYXRpb25SZXN1bHRzIHsKICBjb21wb25lbnRzOiBHZW5lcmF0b3JSZXN1bHQ8U3R5bGVkR2VuZXJhdG9yPltdOwogIGNsYXNzTmFtZXM6IEdlbmVyYXRvclJlc3VsdDxDbGFzc05hbWVHZW5lcmF0b3I+W107CiAga2V5ZnJhbWVzOiBGdW5jdGlvblJlc3VsdDx7IGFuaW1hdGlvbk5hbWU6IHN0cmluZzsgY3NzOiBzdHJpbmcgfT5bXTsKfQoKaW50ZXJmYWNlIENhY2hlIHsKICBleHRlcm5hbE1vZHVsZXM6IHN0cmluZ1tdOwogIHJjRmlsZT86IFJDRmlsZTsKICBkZXN0RGlyPzogc3RyaW5nOwp9Cgpjb25zdCBfZGlybmFtZSA9IG5ldyBVUkwoJy4nLCBpbXBvcnQubWV0YS51cmwpLnBhdGhuYW1lOwoKY29uc3QgY2FjaGU6IENhY2hlID0gewogIGV4dGVybmFsTW9kdWxlczogW10sCiAgcmNGaWxlOiB1bmRlZmluZWQsCiAgZGVzdERpcjogdW5kZWZpbmVkLAp9OwoKY29uc3QgZ2V0RXh0ZXJuYWxNb2R1bGVzID0gKGNvcmVDb25maWdQYXRoOiBzdHJpbmcpID0+IHsKICBpZiAoY2FjaGUuZXh0ZXJuYWxNb2R1bGVzLmxlbmd0aCA+IDApIHJldHVybiBjYWNoZS5leHRlcm5hbE1vZHVsZXM7CiAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhjb3JlQ29uZmlnUGF0aCwgJ3V0ZjgnKTsKICBjb25zdCBtYXRjaCA9IGNvbnRlbnQubWF0Y2goL2V4dGVybmFsTW9kdWxlczpccz9cWyguKilcXS8pOwogIGlmICghbWF0Y2gpIHJldHVybiBbXTsKICBjb25zdCBleHRlcm5hbE1vZHVsZXMgPSBtYXRjaFsxXS5zcGxpdCgnLCcpLm1hcCgoZCkgPT4gZC5yZXBsYWNlKC9bJyJgXS9nLCAnJykudHJpbSgpKTsKICBjYWNoZS5leHRlcm5hbE1vZHVsZXMgPSBleHRlcm5hbE1vZHVsZXM7CiAgcmV0dXJuIGV4dGVybmFsTW9kdWxlczsKfTsKCmNvbnN0IGdldERlc3REaXIgPSBhc3luYyAoZGlybmFtZTogc3RyaW5nKSA9PiB7CiAgaWYgKGNhY2hlLmRlc3REaXIpIHJldHVybiBjYWNoZS5kZXN0RGlyOwogIGNvbnN0IHByb2plY3RDb25maWcgPSBhd2FpdCBnZXRSQ1Byb2plY3RDb25maWcoZGlybmFtZSk7CiAgY29uc3QgZGVzdERpciA9IGpvaW4oZGlybmFtZSwgcHJvamVjdENvbmZpZz8uc2FsdHlnZW5EaXIgfHwgJ3NhbHR5Z2VuJyk7CiAgY2FjaGUuZGVzdERpciA9IGRlc3REaXI7CiAgcmV0dXJuIGRlc3REaXI7Cn07CgpleHBvcnQgY29uc3Qgc2FsdHlGaWxlRXh0ZW5zaW9ucyA9IFsnc2FsdHknLCAnY3NzJywgJ3N0eWxlcycsICdzdHlsZWQnXTsKZXhwb3J0IGNvbnN0IHNhbHR5RmlsZVJlZ0V4cCA9IChhZGRpdGlvbmFsOiBzdHJpbmdbXSA9IFtdKSA9PiBuZXcgUmVnRXhwKGBcXC4oJHtbLi4uc2FsdHlGaWxlRXh0ZW5zaW9ucywgLi4uYWRkaXRpb25hbF0uam9pbignfCcpfSlcXC5gKTsKZXhwb3J0IGNvbnN0IGlzU2FsdHlGaWxlID0gKGZpbGU6IHN0cmluZywgYWRkaXRpb25hbDogc3RyaW5nW10gPSBbXSkgPT4gc2FsdHlGaWxlUmVnRXhwKGFkZGl0aW9uYWwpLnRlc3QoZmlsZSk7Cgpjb25zdCByZWFkUkNGaWxlID0gYXN5bmMgKGN1cnJlbnREaXI6IHN0cmluZykgPT4gewogIGlmIChjYWNoZS5yY0ZpbGUpIHJldHVybiBjYWNoZS5yY0ZpbGU7CiAgaWYgKGN1cnJlbnREaXIgPT09ICcvJykgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZmluZCAuc2FsdHlyYy5qc29uIGZpbGUnKTsKICBjb25zdCByY1BhdGggPSBqb2luKGN1cnJlbnREaXIsICcuc2FsdHlyYy5qc29uJyk7CiAgY29uc3QgcmNDb250ZW50ID0gYXdhaXQgcmVhZEZpbGUocmNQYXRoLCAndXRmLTgnKQogICAgLnRoZW4oSlNPTi5wYXJzZSkKICAgIC5jYXRjaCgoKSA9PiB1bmRlZmluZWQpOwoKICBpZiAoIXJjQ29udGVudCkgcmV0dXJuIHJlYWRSQ0ZpbGUoam9pbihjdXJyZW50RGlyLCAnLi4nKSk7CiAgY2FjaGUucmNGaWxlID0gcmNDb250ZW50OwogIHJldHVybiByY0NvbnRlbnQgYXMgUkNGaWxlOwp9OwoKY29uc3QgZ2V0UkNQcm9qZWN0Q29uZmlnID0gYXN5bmMgKGRpcm5hbWU6IHN0cmluZykgPT4gewogIGNvbnN0IHJjRmlsZSA9IGF3YWl0IHJlYWRSQ0ZpbGUoZGlybmFtZSk7CiAgY29uc3QgcHJvamVjdENvbmZpZyA9IHJjRmlsZS5wcm9qZWN0cz8uZmluZCgocHJvamVjdCkgPT4gZGlybmFtZS5lbmRzV2l0aChwcm9qZWN0LmRpciB8fCAnJykpOwogIGlmICghcHJvamVjdENvbmZpZykgcmV0dXJuIHJjRmlsZS5wcm9qZWN0cz8uZmluZCgocHJvamVjdCkgPT4gcHJvamVjdC5kaXIgPT09IHJjRmlsZS5kZWZhdWx0UHJvamVjdCk7CiAgcmV0dXJuIHByb2plY3RDb25maWc7Cn07Cgpjb25zdCBnZW5lcmF0ZUNvbmZpZyA9IGFzeW5jIChkaXJuYW1lOiBzdHJpbmcpID0+IHsKICBjb25zdCByY1Byb2plY3QgPSBhd2FpdCBnZXRSQ1Byb2plY3RDb25maWcoZGlybmFtZSk7CiAgY29uc3QgZGVzdERpciA9IGF3YWl0IGdldERlc3REaXIoZGlybmFtZSk7CiAgY29uc3QgY29yZUNvbmZpZ1BhdGggPSBqb2luKGRpcm5hbWUsIHJjUHJvamVjdD8uY29uZmlnRGlyIHx8ICcnLCAnc2FsdHkuY29uZmlnLnRzJyk7CiAgY29uc3QgY29yZUNvbmZpZ0Rlc3QgPSBqb2luKGRlc3REaXIsICdzYWx0eS5jb25maWcuanMnKTsKCiAgY29uc3QgbW9kdWxlVHlwZSA9IGF3YWl0IGRldGVjdEN1cnJlbnRNb2R1bGVUeXBlKGRpcm5hbWUpOwogIGNvbnN0IGV4dGVybmFsTW9kdWxlcyA9IGdldEV4dGVybmFsTW9kdWxlcyhjb3JlQ29uZmlnUGF0aCk7CiAgYXdhaXQgZXNidWlsZC5idWlsZCh7CiAgICBlbnRyeVBvaW50czogW2NvcmVDb25maWdQYXRoXSwKICAgIG1pbmlmeTogdHJ1ZSwKICAgIHRyZWVTaGFraW5nOiB0cnVlLAogICAgYnVuZGxlOiB0cnVlLAogICAgb3V0ZmlsZTogY29yZUNvbmZpZ0Rlc3QsCiAgICBmb3JtYXQ6IG1vZHVsZVR5cGUsCiAgICBleHRlcm5hbDogZXh0ZXJuYWxNb2R1bGVzLAogIH0pOwoKICBjb25zdCBub3cgPSBEYXRlLm5vdygpOwogIGNvbnN0IHsgY29uZmlnIH0gPSBhd2FpdCBpbXBvcnQoYCR7Y29yZUNvbmZpZ0Rlc3R9P3Q9JHtub3d9YCk7CiAgcmV0dXJuIHsgY29uZmlnLCBwYXRoOiBjb3JlQ29uZmlnRGVzdCB9Owp9OwoKZXhwb3J0IGNvbnN0IGdlbmVyYXRlQ29uZmlnU3R5bGVzID0gYXN5bmMgKGRpcm5hbWU6IHN0cmluZywgY29uZmlnRmlsZXM6IFNldDxzdHJpbmc+KSA9PiB7CiAgY29uc3QgZGVzdERpciA9IGF3YWl0IGdldERlc3REaXIoZGlybmFtZSk7CgogIGNvbnN0IGdlbmVyYXRpb25SZXN1bHRzOiBDb25maWdHZW5lcmF0aW9uUmVzdWx0cyA9IHsKICAgIG1lZGlhUXVlcmllczogW10sCiAgICBnbG9iYWxTdHlsZXM6IFtdLAogICAgdmFyaWFibGVzOiBbXSwKICAgIHRlbXBsYXRlczogW10sCiAgfTsKCiAgYXdhaXQgUHJvbWlzZS5hbGwoCiAgICBbLi4uY29uZmlnRmlsZXNdLm1hcChhc3luYyAoc3JjKSA9PiB7CiAgICAgIGNvbnN0IHsgY29udGVudHMsIG91dHB1dEZpbGVQYXRoIH0gPSBhd2FpdCBjb21waWxlU2FsdHlGaWxlKGRpcm5hbWUsIHNyYywgZGVzdERpcik7CiAgICAgIE9iamVjdC5lbnRyaWVzKGNvbnRlbnRzKS5mb3JFYWNoKChbbmFtZSwgdmFsdWVdKSA9PiB7CiAgICAgICAgaWYgKHZhbHVlLmlzTWVkaWEpIGdlbmVyYXRpb25SZXN1bHRzLm1lZGlhUXVlcmllcy5wdXNoKFtuYW1lLCB2YWx1ZSBhcyBhbnldKTsKICAgICAgICBlbHNlIGlmICh2YWx1ZS5pc0dsb2JhbERlZmluZSkgZ2VuZXJhdGlvblJlc3VsdHMuZ2xvYmFsU3R5bGVzLnB1c2godmFsdWUgYXMgYW55KTsKICAgICAgICBlbHNlIGlmICh2YWx1ZS5pc0RlZmluZVZhcmlhYmxlcykgZ2VuZXJhdGlvblJlc3VsdHMudmFyaWFibGVzLnB1c2godmFsdWUgYXMgYW55KTsKICAgICAgICBlbHNlIGlmICh2YWx1ZS5pc0RlZmluZVRlbXBsYXRlcykgZ2VuZXJhdGlvblJlc3VsdHMudGVtcGxhdGVzLnB1c2goKHZhbHVlIGFzIGFueSkuX3NldFBhdGgoYCR7bmFtZX07OyR7b3V0cHV0RmlsZVBhdGh9YCkpOwogICAgICB9KTsKICAgIH0pCiAgKTsKCiAgLy8gR2VuZXJhdGUgdGhlIGNvbmZpZyBmaWxlcwogIGNvbnN0IHsgY29uZmlnLCBwYXRoOiBjb25maWdQYXRoIH0gPSBhd2FpdCBnZW5lcmF0ZUNvbmZpZyhkaXJuYW1lKTsKCiAgLy8gQ2FjaGUgdGhlIGNvbmZpZyBjb250ZW50CiAgY29uc3QgY29uZmlnQ2FjaGVDb250ZW50ID0geyAuLi5jb25maWcgfSBhcyBDYWNoZWRDb25maWc7CgogIC8vIEdlbmVyYXRlIG1lZGlhIHF1ZXJ5IGhlbHBlcnMKICBjb25zdCB7IG1lZGlhUXVlcmllcyB9ID0gZ2VuZXJhdGlvblJlc3VsdHM7CiAgY29uZmlnQ2FjaGVDb250ZW50Lm1lZGlhUXVlcmllcyA9IE9iamVjdC5mcm9tRW50cmllcyhtZWRpYVF1ZXJpZXMubWFwKChbbmFtZSwgdmFsdWVdKSA9PiBbYEAke25hbWV9YCwgdmFsdWVdKSk7CiAgY29uc3QgbWVkaWFRdWVyeUtleXMgPSBtZWRpYVF1ZXJpZXMubWFwKChbbmFtZV0pID0+IGAnQCR7bmFtZX0nYCkuam9pbignIHwgJyk7CgogIC8vIEdlbmVyYXRlIHZhcmlhYmxlcyBjc3MgZmlsZQogIGNvbnN0IHZhcmlhYmxlVG9rZW5zID0gbmV3IFNldDxzdHJpbmc+KCk7CgogIHR5cGUgVmFyaWFibGVzID0gc3RyaW5nIHwgdW5kZWZpbmVkOwogIGNvbnN0IHBhcnNlVmFyaWFibGVzID0gYXN5bmMgPFQgZXh0ZW5kcyBvYmplY3Q+KG9iajogVCwgcGF0aDogUHJvcGVydHlLZXlbXSA9IFtdKTogUHJvbWlzZTxWYXJpYWJsZXNbXT4gPT4gewogICAgaWYgKCFvYmopIHJldHVybiBbXTsKICAgIGNvbnN0IHByb21pc2VzID0gT2JqZWN0LmVudHJpZXMob2JqKS5tYXAoYXN5bmMgKFtrZXksIHZhbHVlXSk6IFByb21pc2U8VmFyaWFibGVzIHwgVmFyaWFibGVzW10+ID0+IHsKICAgICAgY29uc3QgcGFyc2VWYXJpYWJsZSA9IGFzeW5jICh2YWx1ZTogdW5rbm93bikgPT4gewogICAgICAgIGlmICghdmFsdWUpIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgUHJvbWlzZSkgcmV0dXJuIGF3YWl0IHBhcnNlVmFyaWFibGUoYXdhaXQgdmFsdWUpOwogICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHJldHVybiBhd2FpdCBwYXJzZVZhcmlhYmxlKGF3YWl0IHZhbHVlKCkpOwogICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSByZXR1cm4gYXdhaXQgcGFyc2VWYXJpYWJsZXModmFsdWUsIFsuLi5wYXRoLCBrZXldKTsKCiAgICAgICAgY29uc3QgZG90dGVkS2V5ID0gZG90Q2FzZShrZXkpOwogICAgICAgIGNvbnN0IGRhc2hlZEtleSA9IGRhc2hDYXNlKGtleSk7CgogICAgICAgIGNvbnN0IHRzTmFtZSA9IFsuLi5wYXRoLCBkb3R0ZWRLZXldLmpvaW4oJy4nKTsKICAgICAgICB2YXJpYWJsZVRva2Vucy5hZGQoYCIke3RzTmFtZX0iYCk7CgogICAgICAgIGNvbnN0IGNzc05hbWUgPSBbLi4ucGF0aC5tYXAoZGFzaENhc2UpLCBkYXNoZWRLZXldLmpvaW4oJy0nKTsKICAgICAgICBjb25zdCByZXN1bHQgPSBwYXJzZVZhcmlhYmxlVG9rZW5zKHZhbHVlKTsKICAgICAgICBpZiAoIXJlc3VsdCkgcmV0dXJuIGAtLSR7Y3NzTmFtZX06ICR7dmFsdWV9O2A7CiAgICAgICAgcmV0dXJuIGAtLSR7Y3NzTmFtZX06ICR7cmVzdWx0LnRyYW5zZm9ybWVkfTtgOwogICAgICB9OwogICAgICByZXR1cm4gYXdhaXQgcGFyc2VWYXJpYWJsZSh2YWx1ZSk7CiAgICB9KTsKCiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpOwogICAgcmV0dXJuIHJlc3VsdHMuZmxhdCgpOwogIH07CgogIGNvbnN0IHBhcnNlUmVzcG9uc2l2ZVZhcmlhYmxlcyA9IGFzeW5jIDxUIGV4dGVuZHMgQ3NzUmVzcG9uc2l2ZVZhcmlhYmxlcz4ob2JqOiBUKTogUHJvbWlzZTxWYXJpYWJsZXNbXT4gPT4gewogICAgaWYgKCFvYmopIHJldHVybiBbXTsKCiAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5lbnRyaWVzKG9iaikubWFwKGFzeW5jIChbbWVkaWFRdWVyeSwgdmFsdWVzXSk6IFByb21pc2U8VmFyaWFibGVzIHwgVmFyaWFibGVzW10+ID0+IHsKICAgICAgY29uc3QgdmFyaWFibGVzID0gYXdhaXQgcGFyc2VWYXJpYWJsZXModmFsdWVzKTsKICAgICAgaWYgKG1lZGlhUXVlcnkgPT09ICdiYXNlJykgcmV0dXJuIHZhcmlhYmxlcy5qb2luKCcnKTsKICAgICAgaWYgKGNvbmZpZ0NhY2hlQ29udGVudC5tZWRpYVF1ZXJpZXNbbWVkaWFRdWVyeV0pIHsKICAgICAgICBjb25zdCBtZWRpYVF1ZXJ5VmFsdWUgPSBjb25maWdDYWNoZUNvbnRlbnQubWVkaWFRdWVyaWVzW21lZGlhUXVlcnldOwogICAgICAgIHJldHVybiBgJHttZWRpYVF1ZXJ5VmFsdWV9IHsgJHt2YXJpYWJsZXMuam9pbignJyl9IH1gOwogICAgICB9CiAgICAgIHJldHVybiBgJHttZWRpYVF1ZXJ5fSB7ICR7dmFyaWFibGVzLmpvaW4oJycpfSB9YDsKICAgIH0pOwogICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTsKICAgIHJldHVybiByZXN1bHRzLmZsYXQoKTsKICB9OwoKICBjb25zdCBwYXJzZUNvbmRpdGlvbmFsVmFyaWFibGVzID0gYXN5bmMgPFQgZXh0ZW5kcyBDc3NDb25kaXRpb25hbFZhcmlhYmxlcz4ob2JqOiBUKTogUHJvbWlzZTxWYXJpYWJsZXNbXT4gPT4gewogICAgaWYgKCFvYmopIHJldHVybiBbXTsKCiAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5lbnRyaWVzKG9iaikubWFwKGFzeW5jIChbcHJvcGVydHksIGNvbmRpdGlvbnNdKTogUHJvbWlzZTxWYXJpYWJsZXMgfCBWYXJpYWJsZXNbXT4gPT4gewogICAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5lbnRyaWVzKGNvbmRpdGlvbnMpLm1hcChhc3luYyAoW2NvbmRpdGlvbiwgdmFsdWVzXSk6IFByb21pc2U8VmFyaWFibGVzIHwgVmFyaWFibGVzW10+ID0+IHsKICAgICAgICBjb25zdCB2YXJpYWJsZXMgPSBhd2FpdCBwYXJzZVZhcmlhYmxlcyh2YWx1ZXMsIFtwcm9wZXJ0eV0pOwogICAgICAgIGNvbnN0IGNvbmRpdGlvblNjb3BlID0gYC4ke3Byb3BlcnR5fS0ke2NvbmRpdGlvbn0sIFtkYXRhLSR7cHJvcGVydHl9PSIke2NvbmRpdGlvbn0iXWA7CiAgICAgICAgY29uc3QgY29tYmluZWQgPSB2YXJpYWJsZXMuam9pbignJyk7CiAgICAgICAgcmV0dXJuIGAke2NvbmRpdGlvblNjb3BlfSB7ICR7Y29tYmluZWR9IH1gOwogICAgICB9KTsKICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpOwogICAgICByZXR1cm4gcmVzdWx0LmZsYXQoKTsKICAgIH0pOwogICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTsKICAgIHJldHVybiByZXN1bHRzLmZsYXQoKTsKICB9OwoKICBjb25zdCBnZXRTdGF0aWNWYXJpYWJsZXMgPSAodmFyaWFibGVzOiBTYWx0eVZhcmlhYmxlcyk6IFJlY29yZDxzdHJpbmcsIGFueT4gPT4gewogICAgcmV0dXJuIHsgLi4udmFyaWFibGVzLCByZXNwb25zaXZlOiB1bmRlZmluZWQsIGNvbmRpdGlvbmFsOiB1bmRlZmluZWQgfTsKICB9OwoKICBjb25zdCBnZXRHZW5lcmF0ZWRWYXJpYWJsZXMgPSAodHlwZTogJ3N0YXRpYycgfCAncmVzcG9uc2l2ZScgfCAnY29uZGl0aW9uYWwnKSA9PiB7CiAgICByZXR1cm4gZ2VuZXJhdGlvblJlc3VsdHMudmFyaWFibGVzLm1hcCgoZmFjdG9yeSkgPT4gewogICAgICBpZiAodHlwZSA9PT0gJ3N0YXRpYycpIHJldHVybiBnZXRTdGF0aWNWYXJpYWJsZXMoZmFjdG9yeS5fY3VycmVudCk7CiAgICAgIHJldHVybiBmYWN0b3J5Ll9jdXJyZW50W3R5cGVdOwogICAgfSk7CiAgfTsKCiAgY29uc3QgX3N0YXRpY1ZhcmlhYmxlcyA9IG1lcmdlT2JqZWN0cyhnZXRTdGF0aWNWYXJpYWJsZXMoY29uZmlnLnZhcmlhYmxlcyksIGdldEdlbmVyYXRlZFZhcmlhYmxlcygnc3RhdGljJykpOwogIGNvbnN0IHN0YXRpY1ZhcmlhYmxlcyA9IGF3YWl0IHBhcnNlVmFyaWFibGVzKF9zdGF0aWNWYXJpYWJsZXMpOwogIGNvbnN0IF9yZXNwb25zaXZlVmFyaWFibGVzID0gbWVyZ2VPYmplY3RzPENzc1Jlc3BvbnNpdmVWYXJpYWJsZXM+KGNvbmZpZy52YXJpYWJsZXM/LnJlc3BvbnNpdmUsIGdldEdlbmVyYXRlZFZhcmlhYmxlcygncmVzcG9uc2l2ZScpKTsKICBjb25zdCByZXNwb25zaXZlVmFyaWFibGVzID0gYXdhaXQgcGFyc2VSZXNwb25zaXZlVmFyaWFibGVzKF9yZXNwb25zaXZlVmFyaWFibGVzKTsKICBjb25zdCBfY29uZGl0aW9uYWxWYXJpYWJsZXMgPSBtZXJnZU9iamVjdHMoY29uZmlnLnZhcmlhYmxlcz8uY29uZGl0aW9uYWwsIGdldEdlbmVyYXRlZFZhcmlhYmxlcygnY29uZGl0aW9uYWwnKSk7CiAgY29uc3QgY29uZGl0aW9uYWxWYXJpYWJsZXMgPSBhd2FpdCBwYXJzZUNvbmRpdGlvbmFsVmFyaWFibGVzKF9jb25kaXRpb25hbFZhcmlhYmxlcyk7CgogIGNvbnN0IHZhcmlhYmxlc1BhdGggPSBqb2luKGRlc3REaXIsICdjc3MvX3ZhcmlhYmxlcy5jc3MnKTsKICBjb25zdCB2YXJpYWJsZXNDc3MgPSBgOnJvb3QgeyAke3N0YXRpY1ZhcmlhYmxlcy5qb2luKCcnKX0gJHtyZXNwb25zaXZlVmFyaWFibGVzLmpvaW4oJycpfSB9ICR7Y29uZGl0aW9uYWxWYXJpYWJsZXMuam9pbignJyl9YDsKICB3cml0ZUZpbGVTeW5jKHZhcmlhYmxlc1BhdGgsIHZhcmlhYmxlc0Nzcyk7CiAgY29uZmlnQ2FjaGVDb250ZW50LnN0YXRpY1ZhcmlhYmxlcyA9IF9zdGF0aWNWYXJpYWJsZXM7CgogIC8vIEdlbmVyYXRlIGdsb2JhbCBzdHlsZXMKICBjb25zdCBnbG9iYWxTdHlsZXNQYXRoID0gam9pbihkZXN0RGlyLCAnY3NzL19nbG9iYWwuY3NzJyk7CiAgY29uc3QgbWVyZ2VkR2xvYmFsU3R5bGVzID0gbWVyZ2VPYmplY3RzKGNvbmZpZy5nbG9iYWwsIGdlbmVyYXRpb25SZXN1bHRzLmdsb2JhbFN0eWxlcyk7CiAgY29uc3QgZ2xvYmFsU3R5bGVzU3RyaW5nID0gYXdhaXQgcGFyc2VBbmRKb2luU3R5bGVzKG1lcmdlZEdsb2JhbFN0eWxlcywgJycpOwoKICB3cml0ZUZpbGVTeW5jKGdsb2JhbFN0eWxlc1BhdGgsIGBAbGF5ZXIgZ2xvYmFsIHsgJHtnbG9iYWxTdHlsZXNTdHJpbmd9IH1gKTsKCiAgLy8gR2VuZXJhdGUgcmVzZXQgc3R5bGVzCiAgY29uc3QgcmVzZXRTdHlsZXNQYXRoID0gam9pbihkZXN0RGlyLCAnY3NzL19yZXNldC5jc3MnKTsKCiAgY29uc3QgZ2V0UmVzZXRTdHlsZXMgPSAoKSA9PiB7CiAgICBpZiAoY29uZmlnLnJlc2V0ID09PSAnbm9uZScpIHJldHVybiB7fTsKICAgIGlmICh0eXBlb2YgY29uZmlnLnJlc2V0ID09PSAnb2JqZWN0JykgcmV0dXJuIGNvbmZpZy5yZXNldDsKICAgIHJldHVybiBzYWx0eVJlc2V0OwogIH07CgogIGNvbnN0IHJlc2V0U3R5bGVzID0gZ2V0UmVzZXRTdHlsZXMoKTsKICBjb25zdCByZXNldFN0eWxlc1N0cmluZyA9IGF3YWl0IHBhcnNlQW5kSm9pblN0eWxlcyhyZXNldFN0eWxlcywgJycpOwoKICB3cml0ZUZpbGVTeW5jKHJlc2V0U3R5bGVzUGF0aCwgYEBsYXllciByZXNldCB7ICR7cmVzZXRTdHlsZXNTdHJpbmd9IH1gKTsKCiAgLy8gR2VuZXJhdGUgdGVtcGxhdGVzCiAgY29uc3QgdGVtcGxhdGVTdHlsZXNQYXRoID0gam9pbihkZXN0RGlyLCAnY3NzL190ZW1wbGF0ZXMuY3NzJyk7CiAgY29uc3QgdGVtcGxhdGVzID0gbWVyZ2VPYmplY3RzPENzc1RlbXBsYXRlcz4oY29uZmlnLnRlbXBsYXRlcywgZ2VuZXJhdGlvblJlc3VsdHMudGVtcGxhdGVzKTsKCiAgY29uc3QgdGVtcGxhdGVTdHlsZXNTdHJpbmcgPSBhd2FpdCBwYXJzZVRlbXBsYXRlcyh0ZW1wbGF0ZXMpOwogIGNvbnN0IHRlbXBsYXRlVG9rZW5zID0gZ2V0VGVtcGxhdGVUeXBlcyh0ZW1wbGF0ZXMpOwoKICB3cml0ZUZpbGVTeW5jKHRlbXBsYXRlU3R5bGVzUGF0aCwgYEBsYXllciB0ZW1wbGF0ZXMgeyAke3RlbXBsYXRlU3R5bGVzU3RyaW5nfSB9YCk7CiAgY29uZmlnQ2FjaGVDb250ZW50LnRlbXBsYXRlcyA9IHRlbXBsYXRlczsKCiAgY29uc3QgY29uZmlnVGVtcGxhdGVGYWN0b3JpZXMgPSBjb25maWcudGVtcGxhdGVzID8gW2RlZmluZVRlbXBsYXRlcyhjb25maWcudGVtcGxhdGVzKS5fc2V0UGF0aChgY29uZmlnOzske2NvbmZpZ1BhdGh9YCldIDogW107CiAgY29uc3QgdGVtcGxhdGVGYWN0b3JpZXMgPSBtZXJnZUZhY3RvcmllcyhnZW5lcmF0aW9uUmVzdWx0cy50ZW1wbGF0ZXMsIGNvbmZpZ1RlbXBsYXRlRmFjdG9yaWVzKTsKCiAgY29uZmlnQ2FjaGVDb250ZW50LnRlbXBsYXRlUGF0aHMgPSBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXModGVtcGxhdGVGYWN0b3JpZXMpLm1hcCgoW2tleSwgZmFrdG9yeV0pID0+IFtrZXksIGZha3RvcnkuX3BhdGhdKSk7CgogIC8vIEdlbmVyYXRlIHR5cGVzCgogIGNvbnN0IHRzVG9rZW5zUGF0aCA9IGpvaW4oZGVzdERpciwgJ3R5cGVzL2Nzcy10b2tlbnMuZC50cycpOwogIGNvbnN0IHRzVmFyaWFibGVUb2tlbnMgPSBbLi4udmFyaWFibGVUb2tlbnNdLmpvaW4oJ3wnKTsKCiAgY29uc3QgdHNUb2tlbnNUeXBlcyA9IGAKICAvLyBWYXJpYWJsZSB0eXBlcwogIHR5cGUgVmFyaWFibGVUb2tlbnMgPSAke3RzVmFyaWFibGVUb2tlbnN9OyAKICB0eXBlIFByb3BlcnR5VmFsdWVUb2tlbiA9IFxge1wke1ZhcmlhYmxlVG9rZW5zfX1cYDsKCiAgLy8gVGVtcGxhdGUgdHlwZXMKICB0eXBlIFRlbXBsYXRlVG9rZW5zID0gewogICAgJHtPYmplY3QuZW50cmllcyh0ZW1wbGF0ZVRva2VucykKICAgICAgLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBgJHtrZXl9PzogJHt2YWx1ZX1gKQogICAgICAuam9pbignXG4nKX0KICB9CgogIC8vIE1lZGlhIHF1ZXJ5IHR5cGVzCiAgdHlwZSBNZWRpYVF1ZXJ5S2V5cyA9ICR7bWVkaWFRdWVyeUtleXMgfHwgYCcnYH07CiAgYDsKCiAgd3JpdGVGaWxlU3luYyh0c1Rva2Vuc1BhdGgsIHRzVG9rZW5zVHlwZXMpOwoKICAvLyBTYXZlIGNvbmZpZyBjYWNoZSBmaWxlCiAgY29uc3QgY29uZmlnQ2FjaGVQYXRoID0gam9pbihkZXN0RGlyLCAnY2FjaGUvY29uZmlnLWNhY2hlLmpzb24nKTsKICB3cml0ZUZpbGVTeW5jKGNvbmZpZ0NhY2hlUGF0aCwgSlNPTi5zdHJpbmdpZnkoY29uZmlnQ2FjaGVDb250ZW50LCBudWxsLCAyKSk7CgogIGNvbnN0IGNvbmZpZ0NhY2hlU2Vjb25kYXJ5UGF0aCA9IGpvaW4oX2Rpcm5hbWUsICcuLi9jYWNoZS9jb25maWctY2FjaGUuanNvbicpOwogIHdyaXRlRmlsZVN5bmMoY29uZmlnQ2FjaGVTZWNvbmRhcnlQYXRoLCBKU09OLnN0cmluZ2lmeShjb25maWdDYWNoZUNvbnRlbnQsIG51bGwsIDIpKTsKfTsKCmNvbnN0IHJlcGxhY2VTdHlsZWRUYWcgPSAoY3VycmVudEZpbGU6IHN0cmluZykgPT4gewogIHJldHVybiBjdXJyZW50RmlsZS5yZXBsYWNlKC9zdHlsZWRcKChbXiInYHssXSspLC9nLCAobWF0Y2gsIHRhZykgPT4gewogICAgLy8gQ2hlY2sgaWYgdGhlIHRhZyBpcyBhIHN0cmluZwogICAgY29uc3QgaXNTdHJpbmcgPSAvXlsnImBdLy50ZXN0KHRhZyk7CiAgICBpZiAoaXNTdHJpbmcpIHJldHVybiBtYXRjaDsKCiAgICAvLyBDaGVjayBpZiB0aGUgdGFnIGlzIGltcG9ydGVkIGZyb20gc29tZXdoZXJlIGVsc2UKICAgIGNvbnN0IGlzSW1wb3J0ZWRSZWdFeHAgPSBuZXcgUmVnRXhwKGBpbXBvcnRbXjtdKiR7dGFnfVssXFxze11bXjtdKmZyb21cXHM/KFtee307XSspO2ApOwogICAgY29uc3QgaXNJbXBvcnRlZCA9IGlzSW1wb3J0ZWRSZWdFeHAudGVzdChjdXJyZW50RmlsZSk7CiAgICBpZiAoIWlzSW1wb3J0ZWQpIHJldHVybiBtYXRjaDsKCiAgICAvLyBDaGVjayBpZiB0aGUgaW1wb3J0IGlzIGEgc2FsdHkgZmlsZQogICAgY29uc3QgaW1wb3J0UmVzdWx0ID0gaXNJbXBvcnRlZFJlZ0V4cC5leGVjKGN1cnJlbnRGaWxlKTsKICAgIGlmIChpbXBvcnRSZXN1bHQpIHsKICAgICAgY29uc3QgaW1wb3J0UGF0aCA9IGltcG9ydFJlc3VsdC5hdCgxKTsKICAgICAgY29uc3QgaXNTYWx0eUltcG9ydCA9IHNhbHR5RmlsZUV4dGVuc2lvbnMuc29tZSgoZXh0KSA9PiBpbXBvcnRQYXRoPy5pbmNsdWRlcyhleHQpKTsKICAgICAgaWYgKGlzU2FsdHlJbXBvcnQpIHJldHVybiBtYXRjaDsKICAgIH0KCiAgICAvLyBUbyBhdm9pZCB1bm5lY2Vzc2FyeSBpbXBvcnRzLCB3ZSB3aWxsIHJlcGxhY2UgdGhlIHN0eWxlZCBjYWxsIHdpdGggYSBzdHJpbmcgd2hlbiBpbXBvcnQgaXMgbm90IGEgc2FsdHkgZmlsZQogICAgcmV0dXJuICJzdHlsZWQoJ2RpdicsIjsKICB9KTsKfTsKCmNvbnN0IGFkZENvbmZpZ0NhY2hlID0gKGN1cnJlbnRGaWxlOiBzdHJpbmcsIGRpcm5hbWU6IHN0cmluZykgPT4gewogIHRyeSB7CiAgICBjb25zdCBzYWx0eUNhY2hlZENvbmZpZyA9IHJlYWRGaWxlU3luYyhqb2luKGRpcm5hbWUsICdzYWx0eWdlbi9jYWNoZS9jb25maWctY2FjaGUuanNvbicpLCAndXRmOCcpOwogICAgaWYgKCFzYWx0eUNhY2hlZENvbmZpZykgcmV0dXJuIGBnbG9iYWxUaGlzLnNhbHR5Q29uZmlnID0ge307XG5cbiR7Y3VycmVudEZpbGV9YDsKICAgIHJldHVybiBgZ2xvYmFsVGhpcy5zYWx0eUNvbmZpZyA9ICR7c2FsdHlDYWNoZWRDb25maWd9O1xuXG4ke2N1cnJlbnRGaWxlfWA7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gY3VycmVudEZpbGU7CiAgfQp9OwoKZXhwb3J0IGNvbnN0IGNvbXBpbGVTYWx0eUZpbGUgPSBhc3luYyAoZGlybmFtZTogc3RyaW5nLCBzb3VyY2VGaWxlUGF0aDogc3RyaW5nLCBvdXRwdXREaXJlY3Rvcnk6IHN0cmluZykgPT4gewogIGNvbnN0IGhhc2hlZE5hbWUgPSB0b0hhc2goc291cmNlRmlsZVBhdGgpOwogIGNvbnN0IHRlbXBEaXIgPSBqb2luKG91dHB1dERpcmVjdG9yeSwgJy4vdGVtcCcpOwoKICBpZiAoIWV4aXN0c1N5bmModGVtcERpcikpIG1rZGlyU3luYyh0ZW1wRGlyKTsKCiAgY29uc3QgcGFyc2VkID0gcGFyc2VQYXRoKHNvdXJjZUZpbGVQYXRoKTsKICBsZXQgY3VycmVudEZpbGUgPSByZWFkRmlsZVN5bmMoc291cmNlRmlsZVBhdGgsICd1dGY4Jyk7CgogIGN1cnJlbnRGaWxlID0gcmVwbGFjZVN0eWxlZFRhZyhjdXJyZW50RmlsZSk7CiAgY3VycmVudEZpbGUgPSBhZGRDb25maWdDYWNoZShjdXJyZW50RmlsZSwgZGlybmFtZSk7CgogIGNvbnN0IG91dHB1dEZpbGVQYXRoID0gam9pbihvdXRwdXREaXJlY3RvcnksICdqcycsIGhhc2hlZE5hbWUgKyAnLmpzJyk7CiAgY29uc3QgcmNQcm9qZWN0ID0gYXdhaXQgZ2V0UkNQcm9qZWN0Q29uZmlnKGRpcm5hbWUpOwogIGNvbnN0IGNvcmVDb25maWdQYXRoID0gam9pbihkaXJuYW1lLCByY1Byb2plY3Q/LmNvbmZpZ0RpciB8fCAnJywgJ3NhbHR5LmNvbmZpZy50cycpOwogIGNvbnN0IGV4dGVybmFsTW9kdWxlcyA9IGdldEV4dGVybmFsTW9kdWxlcyhjb3JlQ29uZmlnUGF0aCk7CiAgY29uc3QgbW9kdWxlVHlwZSA9IGF3YWl0IGRldGVjdEN1cnJlbnRNb2R1bGVUeXBlKGRpcm5hbWUpOwoKICBhd2FpdCBlc2J1aWxkLmJ1aWxkKHsKICAgIHN0ZGluOiB7CiAgICAgIGNvbnRlbnRzOiBjdXJyZW50RmlsZSwKICAgICAgc291cmNlZmlsZTogcGFyc2VkLmJhc2UsCiAgICAgIHJlc29sdmVEaXI6IHBhcnNlZC5kaXIsCiAgICAgIGxvYWRlcjogJ3RzeCcsCiAgICB9LAogICAgbWluaWZ5OiBmYWxzZSwKICAgIHRyZWVTaGFraW5nOiB0cnVlLAogICAgYnVuZGxlOiB0cnVlLAogICAgb3V0ZmlsZTogb3V0cHV0RmlsZVBhdGgsCiAgICBmb3JtYXQ6IG1vZHVsZVR5cGUsCiAgICB0YXJnZXQ6IFsnbm9kZTIwJ10sCiAgICBrZWVwTmFtZXM6IHRydWUsCiAgICBleHRlcm5hbDogZXh0ZXJuYWxNb2R1bGVzLAogICAgcGFja2FnZXM6ICdleHRlcm5hbCcsCiAgICBwbHVnaW5zOiBbCiAgICAgIHsKICAgICAgICBuYW1lOiAndGVzdCcsCiAgICAgICAgc2V0dXA6IChidWlsZCkgPT4gewogICAgICAgICAgYnVpbGQub25Mb2FkKHsgZmlsdGVyOiAvLipcLmNzc3xzYWx0eXxzdHlsZXN8c3R5bGVkXC50cy8gfSwgKGFyZ3MpID0+IHsKICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWwgPSByZWFkRmlsZVN5bmMoYXJncy5wYXRoLCAndXRmOCcpOwogICAgICAgICAgICBjb25zdCBtb2RpZmllZCA9IHJlcGxhY2VTdHlsZWRUYWcob3JpZ2luYWwpOwogICAgICAgICAgICByZXR1cm4geyBjb250ZW50czogbW9kaWZpZWQsIGxvYWRlcjogJ3RzJyB9OwogICAgICAgICAgfSk7CiAgICAgICAgfSwKICAgICAgfSwKICAgIF0sCiAgfSk7CgogIHR5cGUgQ29udGVudHMgPSB7CiAgICBba2V5OiBzdHJpbmddOiB7CiAgICAgIGdlbmVyYXRvcjogYW55OwogICAgICBpc0NsYXNzTmFtZT86IGJvb2xlYW47CiAgICAgIGlzTWVkaWE/OiBib29sZWFuOwogICAgICBpc0dsb2JhbERlZmluZT86IGJvb2xlYW47CiAgICAgIGlzRGVmaW5lVmFyaWFibGVzPzogYm9vbGVhbjsKICAgICAgaXNEZWZpbmVUZW1wbGF0ZXM/OiBib29sZWFuOwogICAgICBpc0tleWZyYW1lcz86IGJvb2xlYW47CiAgICAgIGFuaW1hdGlvbk5hbWU/OiBzdHJpbmc7CiAgICAgIGNzcz86IFByb21pc2U8c3RyaW5nPjsKICAgICAgc3R5bGVzPzogYW55OwogICAgfTsKICB9OwoKICBjb25zdCBub3cgPSBEYXRlLm5vdygpOwogIGNvbnN0IGNvbnRlbnRzID0gKGF3YWl0IGltcG9ydChgJHtvdXRwdXRGaWxlUGF0aH0/dD0ke25vd31gKSkgYXMgQ29udGVudHM7CgogIHJldHVybiB7IGNvbnRlbnRzLCBvdXRwdXRGaWxlUGF0aCB9Owp9OwoKY29uc3QgZ2V0Q29uZmlnQ2FjaGUgPSBhc3luYyAoZGlybmFtZTogc3RyaW5nKSA9PiB7CiAgY29uc3QgZGVzdERpciA9IGF3YWl0IGdldERlc3REaXIoZGlybmFtZSk7CiAgY29uc3QgY29yZUNvbmZpZ0Rlc3QgPSBqb2luKGRlc3REaXIsICdjYWNoZS9jb25maWctY2FjaGUuanNvbicpOwogIGNvbnN0IGNvbnRlbnRzID0gcmVhZEZpbGVTeW5jKGNvcmVDb25maWdEZXN0LCAndXRmOCcpOwogIGlmICghY29udGVudHMpIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGZpbmQgY29uZmlnIGNhY2hlIGZpbGUnKTsKICByZXR1cm4gSlNPTi5wYXJzZShjb250ZW50cyk7Cn07Cgpjb25zdCBnZXRDb25maWcgPSBhc3luYyAoZGlybmFtZTogc3RyaW5nKSA9PiB7CiAgY29uc3QgY2FjaGVkID0gYXdhaXQgZ2V0Q29uZmlnQ2FjaGUoZGlybmFtZSk7CiAgY29uc3QgZGVzdERpciA9IGF3YWl0IGdldERlc3REaXIoZGlybmFtZSk7CiAgY29uc3QgY29yZUNvbmZpZ0Rlc3QgPSBqb2luKGRlc3REaXIsICdzYWx0eS5jb25maWcuanMnKTsKICBjb25zdCBub3cgPSBEYXRlLm5vdygpOwogIGNvbnN0IHsgY29uZmlnIH0gPSBhd2FpdCBpbXBvcnQoYCR7Y29yZUNvbmZpZ0Rlc3R9P3Q9JHtub3d9YCk7CiAgcmV0dXJuIG1lcmdlT2JqZWN0czxTYWx0eUNvbmZpZyAmIENhY2hlZENvbmZpZz4oY29uZmlnLCBjYWNoZWQpOwp9OwoKY29uc3QgaXNQcm9kdWN0aW9uID0gKCkgPT4gewogIHRyeSB7CiAgICByZXR1cm4gcHJvY2Vzcy5lbnZbJ05PREVfRU5WJ10gPT09ICdwcm9kdWN0aW9uJzsKICB9IGNhdGNoIHsKICAgIHJldHVybiBmYWxzZTsKICB9Cn07CgpleHBvcnQgY29uc3QgZ2VuZXJhdGVDc3MgPSBhc3luYyAoZGlybmFtZTogc3RyaW5nLCBwcm9kID0gaXNQcm9kdWN0aW9uKCksIGNsZWFuID0gdHJ1ZSkgPT4gewogIHRyeSB7CiAgICBjb25zdCBzdGFydCA9IERhdGUubm93KCk7CiAgICBpZiAocHJvZCkgbG9nZ2VyLmluZm8oJ0dlbmVyYXRpbmcgQ1NTIGluIHByb2R1Y3Rpb24gbW9kZSEg8J+UpScpOwogICAgZWxzZSBsb2dnZXIuaW5mbygnR2VuZXJhdGluZyBDU1MgaW4gZGV2ZWxvcG1lbnQgbW9kZSEg8J+agCcpOwoKICAgIGNvbnN0IGdsb2JhbENzc0ZpbGVzOiBzdHJpbmdbXSA9IFtdOwogICAgY29uc3QgY3NzRmlsZXM6IHN0cmluZ1tdW10gPSBbXTsKICAgIGNvbnN0IGRlc3REaXIgPSBhd2FpdCBnZXREZXN0RGlyKGRpcm5hbWUpOwogICAgY29uc3QgY3NzRmlsZSA9IGpvaW4oZGVzdERpciwgJ2luZGV4LmNzcycpOwoKICAgIGNvbnN0IGNsZWFyRGlzdERpciA9ICgpID0+IHsKICAgICAgaWYgKGV4aXN0c1N5bmMoZGVzdERpcikpIGV4ZWNTeW5jKCdybSAtcmYgJyArIGRlc3REaXIpOwogICAgICBta2RpclN5bmMoZGVzdERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7CiAgICAgIG1rZGlyU3luYyhqb2luKGRlc3REaXIsICdjc3MnKSk7CiAgICAgIG1rZGlyU3luYyhqb2luKGRlc3REaXIsICd0eXBlcycpKTsKICAgICAgbWtkaXJTeW5jKGpvaW4oZGVzdERpciwgJ2pzJykpOwogICAgICBta2RpclN5bmMoam9pbihkZXN0RGlyLCAnY2FjaGUnKSk7CiAgICB9OwoKICAgIC8vIENsZWFyIHRoZSBkaXN0IGRpcmVjdG9yeQoKICAgIGlmIChjbGVhbikgY2xlYXJEaXN0RGlyKCk7CgogICAgLy8gQ29sbGVjdCBzYWx0eSBjc3MgZmlsZXMKICAgIGNvbnN0IGZpbGVzID0gbmV3IFNldDxzdHJpbmc+KCk7CiAgICBjb25zdCBjb25maWdGaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPigpOwoKICAgIGFzeW5jIGZ1bmN0aW9uIGNvbGxlY3RGaWxlcyhzcmM6IHN0cmluZykgewogICAgICBjb25zdCBmb2xkZXJzVG9Ta2lwID0gWydub2RlX21vZHVsZXMnLCAnc2FsdHlnZW4nXTsKICAgICAgY29uc3Qgc3RhdHMgPSBzdGF0U3luYyhzcmMpOwoKICAgICAgaWYgKHN0YXRzLmlzRGlyZWN0b3J5KCkpIHsKICAgICAgICBjb25zdCBmaWxlcyA9IHJlYWRkaXJTeW5jKHNyYyk7CiAgICAgICAgY29uc3Qgc2hvdWxkU2tpcCA9IGZvbGRlcnNUb1NraXAuc29tZSgoZm9sZGVyKSA9PiBzcmMuaW5jbHVkZXMoZm9sZGVyKSk7CiAgICAgICAgaWYgKHNob3VsZFNraXApIHJldHVybjsKICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChmaWxlcy5tYXAoKGZpbGUpID0+IGNvbGxlY3RGaWxlcyhqb2luKHNyYywgZmlsZSkpKSk7CiAgICAgIH0gZWxzZSBpZiAoc3RhdHMuaXNGaWxlKCkpIHsKICAgICAgICBjb25zdCB2YWxpZEZpbGUgPSBpc1NhbHR5RmlsZShzcmMpOwoKICAgICAgICBpZiAodmFsaWRGaWxlKSB7CiAgICAgICAgICBmaWxlcy5hZGQoc3JjKTsKICAgICAgICAgIGNvbnN0IGNvbnRlbnRzID0gcmVhZEZpbGVTeW5jKHNyYywgJ3V0ZjgnKTsKICAgICAgICAgIGNvbnN0IGhhc0RlZmluZUZ1bmN0aW9uID0gL2RlZmluZVtcd1xkXStcKC8udGVzdChjb250ZW50cyk7CiAgICAgICAgICBpZiAoaGFzRGVmaW5lRnVuY3Rpb24pIGNvbmZpZ0ZpbGVzLmFkZChzcmMpOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgLy8gU3RhcnQgdGhlIGNvcHlpbmcgcHJvY2VzcwogICAgYXdhaXQgY29sbGVjdEZpbGVzKGRpcm5hbWUpOwoKICAgIC8vIEdlbmVyYXRlIHZhcmlhYmxlcwogICAgYXdhaXQgZ2VuZXJhdGVDb25maWdTdHlsZXMoZGlybmFtZSwgY29uZmlnRmlsZXMpOwoKICAgIGNvbnN0IGdlbmVyYXRpb25SZXN1bHRzOiBTdHlsZXNHZW5lcmF0aW9uUmVzdWx0cyA9IHsKICAgICAga2V5ZnJhbWVzOiBbXSwKICAgICAgY29tcG9uZW50czogW10sCiAgICAgIGNsYXNzTmFtZXM6IFtdLAogICAgfTsKCiAgICBhd2FpdCBQcm9taXNlLmFsbCgKICAgICAgWy4uLmZpbGVzXS5tYXAoYXN5bmMgKHNyYykgPT4gewogICAgICAgIGNvbnN0IHsgY29udGVudHMgfSA9IGF3YWl0IGNvbXBpbGVTYWx0eUZpbGUoZGlybmFtZSwgc3JjLCBkZXN0RGlyKTsKICAgICAgICBmb3IgKGxldCBbbmFtZSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGNvbnRlbnRzKSkgewogICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgUHJvbWlzZSkgdmFsdWUgPSBhd2FpdCB2YWx1ZTsKCiAgICAgICAgICBpZiAodmFsdWUuaXNLZXlmcmFtZXMpIHsKICAgICAgICAgICAgZ2VuZXJhdGlvblJlc3VsdHMua2V5ZnJhbWVzLnB1c2goewogICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSBhcyBhbnksCiAgICAgICAgICAgICAgc3JjLAogICAgICAgICAgICAgIG5hbWUsCiAgICAgICAgICAgIH0pOwogICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZS5pc0NsYXNzTmFtZSkgewogICAgICAgICAgICBnZW5lcmF0aW9uUmVzdWx0cy5jbGFzc05hbWVzLnB1c2goewogICAgICAgICAgICAgIC4uLnZhbHVlLAogICAgICAgICAgICAgIHNyYywKICAgICAgICAgICAgICBuYW1lLAogICAgICAgICAgICB9KTsKICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUuZ2VuZXJhdG9yKSB7CiAgICAgICAgICAgIGdlbmVyYXRpb25SZXN1bHRzLmNvbXBvbmVudHMucHVzaCh7CiAgICAgICAgICAgICAgLi4udmFsdWUsCiAgICAgICAgICAgICAgc3JjLAogICAgICAgICAgICAgIG5hbWUsCiAgICAgICAgICAgIH0pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSkKICAgICk7CgogICAgLy8gR2V0IGNvbmZpZwogICAgY29uc3QgY29uZmlnID0gYXdhaXQgZ2V0Q29uZmlnKGRpcm5hbWUpOwoKICAgIC8vIEdlbmVyYXRlIENTUyBmb3Iga2V5ZnJhbWUgYW5pbWF0aW9ucwogICAgZm9yIChjb25zdCBrZXlmcmFtZXMgb2YgZ2VuZXJhdGlvblJlc3VsdHMua2V5ZnJhbWVzKSB7CiAgICAgIGNvbnN0IHsgdmFsdWUgfSA9IGtleWZyYW1lczsKICAgICAgY29uc3QgZmlsZU5hbWUgPSBgYV8ke3ZhbHVlLmFuaW1hdGlvbk5hbWV9LmNzc2A7CiAgICAgIGNvbnN0IGZpbGVQYXRoID0gYGNzcy8ke2ZpbGVOYW1lfWA7CiAgICAgIGNvbnN0IGNzc1BhdGggPSBqb2luKGRlc3REaXIsIGZpbGVQYXRoKTsKICAgICAgZ2xvYmFsQ3NzRmlsZXMucHVzaChmaWxlTmFtZSk7CgogICAgICB3cml0ZUZpbGVTeW5jKGNzc1BhdGgsIHZhbHVlLmNzcyk7CiAgICB9CgogICAgLy8gU3RhcnQgZ2F0aGVyaW5nIENTUyBmaWxlcyBmb3IgY29tcG9uZW50cwogICAgY29uc3QgbG9jYWxDc3NGaWxlczogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+ID0ge307CgogICAgLy8gR2VuZXJhdGUgQ1NTIGZvciBjb21wb25lbnRzCiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudFJlc3VsdCBvZiBnZW5lcmF0aW9uUmVzdWx0cy5jb21wb25lbnRzKSB7CiAgICAgIGNvbnN0IHsgc3JjLCBuYW1lIH0gPSBjb21wb25lbnRSZXN1bHQ7CiAgICAgIGlmICghbG9jYWxDc3NGaWxlc1tzcmNdKSBsb2NhbENzc0ZpbGVzW3NyY10gPSBbXTsKCiAgICAgIGNvbnN0IGdlbmVyYXRvciA9IGNvbXBvbmVudFJlc3VsdC5nZW5lcmF0b3IuX3dpdGhCdWlsZENvbnRleHQoewogICAgICAgIGNhbGxlck5hbWU6IG5hbWUsCiAgICAgICAgaXNQcm9kdWN0aW9uOiBwcm9kLAogICAgICAgIGNvbmZpZywKICAgICAgfSk7CgogICAgICBpZiAoIWNzc0ZpbGVzW2dlbmVyYXRvci5wcmlvcml0eV0pIGNzc0ZpbGVzW2dlbmVyYXRvci5wcmlvcml0eV0gPSBbXTsKICAgICAgY29uc3Qgc3R5bGVzID0gYXdhaXQgZ2VuZXJhdG9yLmNzczsKICAgICAgaWYgKCFzdHlsZXMpIGNvbnRpbnVlOwoKICAgICAgY3NzRmlsZXNbZ2VuZXJhdG9yLnByaW9yaXR5XS5wdXNoKGdlbmVyYXRvci5jc3NGaWxlTmFtZSk7CgogICAgICBjb25zdCBmaWxlUGF0aCA9IGBjc3MvJHtnZW5lcmF0b3IuY3NzRmlsZU5hbWV9YDsKICAgICAgY29uc3QgY3NzUGF0aCA9IGpvaW4oZGVzdERpciwgZmlsZVBhdGgpOwoKICAgICAgd3JpdGVGaWxlU3luYyhjc3NQYXRoLCBzdHlsZXMpOwoKICAgICAgaWYgKGNvbmZpZy5pbXBvcnRTdHJhdGVneSA9PT0gJ2NvbXBvbmVudCcpIHsKICAgICAgICBsb2NhbENzc0ZpbGVzW3NyY10ucHVzaChnZW5lcmF0b3IuY3NzRmlsZU5hbWUpOwogICAgICB9CiAgICB9CgogICAgLy8gR2VuZXJhdGUgQ1NTIGZvciBjbGFzcyBuYW1lcwogICAgZm9yIChjb25zdCBjbGFzc05hbWVSZXN1bHQgb2YgZ2VuZXJhdGlvblJlc3VsdHMuY2xhc3NOYW1lcykgewogICAgICBjb25zdCB7IHNyYywgbmFtZSB9ID0gY2xhc3NOYW1lUmVzdWx0OwogICAgICBpZiAoIWxvY2FsQ3NzRmlsZXNbc3JjXSkgbG9jYWxDc3NGaWxlc1tzcmNdID0gW107CgogICAgICBjb25zdCBnZW5lcmF0b3IgPSBjbGFzc05hbWVSZXN1bHQuZ2VuZXJhdG9yLl93aXRoQnVpbGRDb250ZXh0KHsKICAgICAgICBjYWxsZXJOYW1lOiBuYW1lLAogICAgICAgIGlzUHJvZHVjdGlvbjogcHJvZCwKICAgICAgICBjb25maWcsCiAgICAgIH0pOwoKICAgICAgY29uc3Qgc3R5bGVzID0gYXdhaXQgZ2VuZXJhdG9yLmNzczsKICAgICAgaWYgKCFzdHlsZXMpIGNvbnRpbnVlOwoKICAgICAgaWYgKCFjc3NGaWxlc1tnZW5lcmF0b3IucHJpb3JpdHldKSBjc3NGaWxlc1tnZW5lcmF0b3IucHJpb3JpdHldID0gW107CiAgICAgIGNzc0ZpbGVzW2dlbmVyYXRvci5wcmlvcml0eV0ucHVzaChnZW5lcmF0b3IuY3NzRmlsZU5hbWUpOwoKICAgICAgY29uc3QgZmlsZVBhdGggPSBgY3NzLyR7Z2VuZXJhdG9yLmNzc0ZpbGVOYW1lfWA7CiAgICAgIGNvbnN0IGNzc1BhdGggPSBqb2luKGRlc3REaXIsIGZpbGVQYXRoKTsKCiAgICAgIHdyaXRlRmlsZVN5bmMoY3NzUGF0aCwgc3R5bGVzKTsKCiAgICAgIGlmIChjb25maWcuaW1wb3J0U3RyYXRlZ3kgPT09ICdjb21wb25lbnQnKSB7CiAgICAgICAgbG9jYWxDc3NGaWxlc1tzcmNdLnB1c2goZ2VuZXJhdG9yLmNzc0ZpbGVOYW1lKTsKICAgICAgfQogICAgfQoKICAgIC8vIEdlbmVyYXRlIENTUyBmaWxlcyBmb3IgY29tcG9uZW50IGltcG9ydAogICAgaWYgKGNvbmZpZy5pbXBvcnRTdHJhdGVneSA9PT0gJ2NvbXBvbmVudCcpIHsKICAgICAgT2JqZWN0LmVudHJpZXMobG9jYWxDc3NGaWxlcykuZm9yRWFjaCgoW3NyYywgbG9jYWxDc3NGaWxlXSkgPT4gewogICAgICAgIGNvbnN0IGNzc0NvbnRlbnQgPSBsb2NhbENzc0ZpbGUubWFwKChmaWxlKSA9PiBgQGltcG9ydCB1cmwoJy4vJHtmaWxlfScpO2ApLmpvaW4oJ1xuJyk7CgogICAgICAgIGNvbnN0IGhhc2hOYW1lID0gdG9IYXNoKHNyYywgNik7CiAgICAgICAgY29uc3QgcGFyc2VkUGF0aCA9IHBhcnNlUGF0aChzcmMpOwogICAgICAgIGNvbnN0IGRhc2hlcml6ZWQgPSBkYXNoQ2FzZShwYXJzZWRQYXRoLm5hbWUpOwoKICAgICAgICBjb25zdCBjc3NGaWxlID0gam9pbihkZXN0RGlyLCBgY3NzL2ZfJHtkYXNoZXJpemVkfS0ke2hhc2hOYW1lfS5jc3NgKTsKICAgICAgICB3cml0ZUZpbGVTeW5jKGNzc0ZpbGUsIGNzc0NvbnRlbnQgfHwgYC8qIEVtcHR5IGZpbGUgKi9gKTsKICAgICAgfSk7CiAgICB9CgogICAgY29uc3Qgb3RoZXJHbG9iYWxDc3NGaWxlcyA9IGdsb2JhbENzc0ZpbGVzLm1hcCgoZmlsZSkgPT4gYEBpbXBvcnQgdXJsKCcuL2Nzcy8ke2ZpbGV9Jyk7YCkuam9pbignXG4nKTsKCiAgICBjb25zdCBnbG9iYWxDc3NGaWxlbmFtZXMgPSBbJ192YXJpYWJsZXMuY3NzJywgJ19yZXNldC5jc3MnLCAnX2dsb2JhbC5jc3MnLCAnX3RlbXBsYXRlcy5jc3MnXTsKICAgIGNvbnN0IGltcG9ydHNXaXRoRGF0YSA9IGdsb2JhbENzc0ZpbGVuYW1lcy5maWx0ZXIoKGZpbGUpID0+IHsKICAgICAgdHJ5IHsKICAgICAgICBjb25zdCBkYXRhID0gcmVhZEZpbGVTeW5jKGpvaW4oZGVzdERpciwgJ2NzcycsIGZpbGUpLCAndXRmOCcpOwogICAgICAgIHJldHVybiBkYXRhLmxlbmd0aCA+IDA7CiAgICAgIH0gY2F0Y2ggewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfSk7CiAgICBjb25zdCBnbG9iYWxJbXBvcnRzID0gaW1wb3J0c1dpdGhEYXRhLm1hcCgoZmlsZSkgPT4gYEBpbXBvcnQgdXJsKCcuL2Nzcy8ke2ZpbGV9Jyk7YCk7CiAgICBjb25zdCBnZW5lcmF0b3JUZXh0ID0gJy8qIVxuICogR2VuZXJhdGVkIHdpdGggU2FsdHkgQ1NTIChodHRwczovL3NhbHR5LWNzcy5kZXYpXG4gKiBEbyBub3QgZWRpdCB0aGlzIGZpbGUgZGlyZWN0bHlcbiAqL1xuJzsKICAgIGxldCBjc3NDb250ZW50ID0gYCR7Z2VuZXJhdG9yVGV4dH1AbGF5ZXIgcmVzZXQsIGdsb2JhbCwgdGVtcGxhdGVzLCBsMCwgbDEsIGwyLCBsMywgbDQsIGw1LCBsNiwgbDcsIGw4O1xuXG4ke2dsb2JhbEltcG9ydHMuam9pbigKICAgICAgJ1xuJwogICAgKX1cbiR7b3RoZXJHbG9iYWxDc3NGaWxlc31gOwoKICAgIGlmIChjb25maWcuaW1wb3J0U3RyYXRlZ3kgIT09ICdjb21wb25lbnQnKSB7CiAgICAgIGNvbnN0IG1lcmdlZENvbnRlbnQgPSBjc3NGaWxlcy5yZWR1Y2UoKGFjYywgdmFsLCBsYXllcikgPT4gewogICAgICAgIGNvbnN0IGxheWVyQ29udGVudCA9IHZhbC5yZWR1Y2UoKGxheWVyQWNjLCBmaWxlKSA9PiB7CiAgICAgICAgICBjb25zdCBmaWxlcGF0aCA9IGpvaW4oZGVzdERpciwgJ2NzcycsIGZpbGUpOwogICAgICAgICAgY29uc3QgY3NzID0gcmVhZEZpbGVTeW5jKGZpbGVwYXRoLCAndXRmOCcpOwogICAgICAgICAgY29uc3QgZmlsZXBhdGhIYXNoID0gLy4qLShbXi1dKyktXGQrLmNzcy8uZXhlYyhmaWxlKT8uYXQoMSkgfHwgdG9IYXNoKGZpbGVwYXRoLCA2KTsKICAgICAgICAgIGlmIChsYXllckFjYy5pbmNsdWRlcyhmaWxlcGF0aEhhc2gpKSByZXR1cm4gbGF5ZXJBY2M7CiAgICAgICAgICByZXR1cm4gYCR7bGF5ZXJBY2N9XG4vKnN0YXJ0OiR7ZmlsZXBhdGhIYXNofS0ke2ZpbGV9Ki9cbiR7Y3NzfVxuLyplbmQ6JHtmaWxlcGF0aEhhc2h9Ki9cbmA7CiAgICAgICAgfSwgJycpOwoKICAgICAgICBjb25zdCBsYXllckZpbGVOYW1lID0gYGxfJHtsYXllcn0uY3NzYDsKICAgICAgICBjb25zdCBsYXllckZpbGVQYXRoID0gam9pbihkZXN0RGlyLCAnY3NzJywgbGF5ZXJGaWxlTmFtZSk7CiAgICAgICAgY29uc3QgbGF5ZXJDb250ZW50V2l0aExheWVyID0gYEBsYXllciBsJHtsYXllcn0geyAke2xheWVyQ29udGVudH1cbiB9YDsKICAgICAgICB3cml0ZUZpbGVTeW5jKGxheWVyRmlsZVBhdGgsIGxheWVyQ29udGVudFdpdGhMYXllcik7CgogICAgICAgIHJldHVybiBgJHthY2N9XG5AaW1wb3J0IHVybCgnLi9jc3MvJHtsYXllckZpbGVOYW1lfScpO2A7CiAgICAgIH0sICcnKTsKCiAgICAgIGNzc0NvbnRlbnQgKz0gbWVyZ2VkQ29udGVudDsKICAgIH0KCiAgICB3cml0ZUZpbGVTeW5jKGNzc0ZpbGUsIGNzc0NvbnRlbnQpOwoKICAgIGNvbnN0IGVuZCA9IERhdGUubm93KCk7CiAgICBjb25zdCB0aW1lID0gZW5kIC0gc3RhcnQ7CiAgICBjb25zdCBlbW9qaSA9IHRpbWUgPCAyMDAgPyAn8J+UpScgOiB0aW1lIDwgNTAwID8gJ/CfmoAnIDogdGltZSA8IDEwMDAgPyAn8J+OiScgOiB0aW1lIDwgMjAwMCA/ICfwn5qXJyA6IHRpbWUgPCA1MDAwID8gJ/CfpJQnIDogJ/CfpbQnOwogICAgbG9nZ2VyLmluZm8oYEdlbmVyYXRlZCBDU1MgaW4gJHt0aW1lfW1zISAke2Vtb2ppfWApOwogIH0gY2F0Y2ggKGUpIHsKICAgIGNvbnNvbGUuZXJyb3IoZSk7CiAgfQp9OwoKZXhwb3J0IGNvbnN0IGdlbmVyYXRlRmlsZSA9IGFzeW5jIChkaXJuYW1lOiBzdHJpbmcsIGZpbGU6IHN0cmluZywgcHJvZCA9IGlzUHJvZHVjdGlvbigpKSA9PiB7CiAgdHJ5IHsKICAgIGNvbnN0IGRlc3REaXIgPSBhd2FpdCBnZXREZXN0RGlyKGRpcm5hbWUpOwogICAgY29uc3QgdmFsaWRGaWxlID0gaXNTYWx0eUZpbGUoZmlsZSk7CgogICAgaWYgKHZhbGlkRmlsZSkgewogICAgICBjb25zdCBjc3NGaWxlczogc3RyaW5nW11bXSA9IFtdOwogICAgICBjb25zdCBjb25maWcgPSBhd2FpdCBnZXRDb25maWcoZGlybmFtZSk7CiAgICAgIGNvbnN0IHsgY29udGVudHMgfSA9IGF3YWl0IGNvbXBpbGVTYWx0eUZpbGUoZGlybmFtZSwgZmlsZSwgZGVzdERpcik7CiAgICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhjb250ZW50cykpIHsKICAgICAgICAvLyBPYmplY3QuZW50cmllcyhjb250ZW50cykuZm9yRWFjaCgoW25hbWUsIHZhbHVlXTogW3N0cmluZywgYW55XSkgPT4gewogICAgICAgIGlmICh2YWx1ZS5pc0tleWZyYW1lcyAmJiB2YWx1ZS5jc3MpIHsKICAgICAgICAgIGNvbnN0IGZpbGVOYW1lID0gYGFfJHt2YWx1ZS5hbmltYXRpb25OYW1lfS5jc3NgOwogICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBgY3NzLyR7ZmlsZU5hbWV9YDsKICAgICAgICAgIGNvbnN0IGNzc1BhdGggPSBqb2luKGRlc3REaXIsIGZpbGVQYXRoKTsKCiAgICAgICAgICB3cml0ZUZpbGVTeW5jKGNzc1BhdGgsIGF3YWl0IHZhbHVlLmNzcyk7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGlmICh2YWx1ZS5pc0NsYXNzTmFtZSkgewogICAgICAgICAgY29uc3QgZ2VuZXJhdG9yID0gdmFsdWUuZ2VuZXJhdG9yLl93aXRoQnVpbGRDb250ZXh0KHsKICAgICAgICAgICAgY2FsbGVyTmFtZTogbmFtZSwKICAgICAgICAgICAgaXNQcm9kdWN0aW9uOiBwcm9kLAogICAgICAgICAgICBjb25maWcsCiAgICAgICAgICB9KTsKCiAgICAgICAgICBjb25zdCBzdHlsZXMgPSBhd2FpdCBnZW5lcmF0b3IuY3NzOwogICAgICAgICAgaWYgKCFzdHlsZXMpIGNvbnRpbnVlOwoKICAgICAgICAgIGlmICghY3NzRmlsZXNbZ2VuZXJhdG9yLnByaW9yaXR5XSkgY3NzRmlsZXNbZ2VuZXJhdG9yLnByaW9yaXR5XSA9IFtdOwogICAgICAgICAgY3NzRmlsZXNbZ2VuZXJhdG9yLnByaW9yaXR5XS5wdXNoKGdlbmVyYXRvci5jc3NGaWxlTmFtZSk7CgogICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBgY3NzLyR7Z2VuZXJhdG9yLmNzc0ZpbGVOYW1lfWA7CiAgICAgICAgICBjb25zdCBjc3NQYXRoID0gam9pbihkZXN0RGlyLCBmaWxlUGF0aCk7CiAgICAgICAgICB3cml0ZUZpbGVTeW5jKGNzc1BhdGgsIHN0eWxlcyk7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGlmICghdmFsdWUuZ2VuZXJhdG9yKSBjb250aW51ZTsKCiAgICAgICAgY29uc3QgZ2VuZXJhdG9yID0gdmFsdWUuZ2VuZXJhdG9yLl93aXRoQnVpbGRDb250ZXh0KHsKICAgICAgICAgIGNhbGxlck5hbWU6IG5hbWUsCiAgICAgICAgICBpc1Byb2R1Y3Rpb246IHByb2QsCiAgICAgICAgICBjb25maWcsCiAgICAgICAgfSk7CgogICAgICAgIGNvbnN0IHN0eWxlcyA9IGF3YWl0IGdlbmVyYXRvci5jc3M7CiAgICAgICAgaWYgKCFzdHlsZXMpIGNvbnRpbnVlOwoKICAgICAgICBjb25zdCBmaWxlUGF0aCA9IGBjc3MvJHtnZW5lcmF0b3IuY3NzRmlsZU5hbWV9YDsKICAgICAgICBjb25zdCBjc3NQYXRoID0gam9pbihkZXN0RGlyLCBmaWxlUGF0aCk7CgogICAgICAgIHdyaXRlRmlsZVN5bmMoY3NzUGF0aCwgc3R5bGVzKTsKCiAgICAgICAgaWYgKCFjc3NGaWxlc1tnZW5lcmF0b3IucHJpb3JpdHldKSBjc3NGaWxlc1tnZW5lcmF0b3IucHJpb3JpdHldID0gW107CiAgICAgICAgY3NzRmlsZXNbZ2VuZXJhdG9yLnByaW9yaXR5XS5wdXNoKGdlbmVyYXRvci5jc3NGaWxlTmFtZSk7CiAgICAgIH0KCiAgICAgIGlmIChjb25maWcuaW1wb3J0U3RyYXRlZ3kgIT09ICdjb21wb25lbnQnKSB7CiAgICAgICAgY3NzRmlsZXMuZm9yRWFjaCgodmFsLCBsYXllcikgPT4gewogICAgICAgICAgY29uc3QgbGF5ZXJGaWxlTmFtZSA9IGBsXyR7bGF5ZXJ9LmNzc2A7CiAgICAgICAgICBjb25zdCBsYXllckZpbGVQYXRoID0gam9pbihkZXN0RGlyLCAnY3NzJywgbGF5ZXJGaWxlTmFtZSk7CiAgICAgICAgICBsZXQgY3VycmVudExheWVyRmlsZUNvbnRlbnQgPSByZWFkRmlsZVN5bmMobGF5ZXJGaWxlUGF0aCwgJ3V0ZjgnKTsKICAgICAgICAgIHZhbC5mb3JFYWNoKChmaWxlKSA9PiB7CiAgICAgICAgICAgIGNvbnN0IGZpbGVwYXRoID0gam9pbihkZXN0RGlyLCAnY3NzJywgZmlsZSk7CiAgICAgICAgICAgIGNvbnN0IGZpbGVwYXRoSGFzaCA9IC8uKi0oW14tXSspLVxkKy5jc3MvLmV4ZWMoZmlsZSk/LmF0KDEpIHx8IHRvSGFzaChmaWxlcGF0aCwgNik7CiAgICAgICAgICAgIGNvbnN0IGZvdW5kID0gY3VycmVudExheWVyRmlsZUNvbnRlbnQuaW5jbHVkZXMoZmlsZXBhdGhIYXNoKTsKICAgICAgICAgICAgaWYgKCFmb3VuZCkgewogICAgICAgICAgICAgIGNvbnN0IGNzcyA9IHJlYWRGaWxlU3luYyhmaWxlcGF0aCwgJ3V0ZjgnKTsKICAgICAgICAgICAgICBjb25zdCBuZXdDb250ZW50ID0gYC8qc3RhcnQ6JHtmaWxlcGF0aEhhc2h9LSR7ZmlsZX0qL1xuJHtjc3N9XG4vKmVuZDoke2ZpbGVwYXRoSGFzaH0qL1xuYDsKICAgICAgICAgICAgICBjdXJyZW50TGF5ZXJGaWxlQ29udGVudCA9IGAke2N1cnJlbnRMYXllckZpbGVDb250ZW50LnJlcGxhY2UoL1x9JC8sICcnKX1cbiR7bmV3Q29udGVudH1cbn1gOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICAgIHdyaXRlRmlsZVN5bmMobGF5ZXJGaWxlUGF0aCwgY3VycmVudExheWVyRmlsZUNvbnRlbnQpOwogICAgICAgIH0pOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IGNzc0NvbnRlbnQgPSBjc3NGaWxlcwogICAgICAgICAgLmZsYXQoKQogICAgICAgICAgLm1hcCgoZmlsZSkgPT4gYEBpbXBvcnQgdXJsKCcuLyR7ZmlsZX0nKTtgKQogICAgICAgICAgLmpvaW4oJ1xuJyk7CgogICAgICAgIGNvbnN0IGhhc2hOYW1lID0gdG9IYXNoKGZpbGUsIDYpOwogICAgICAgIGNvbnN0IHBhcnNlZFBhdGggPSBwYXJzZVBhdGgoZmlsZSk7CiAgICAgICAgY29uc3QgZGFzaGVyaXplZCA9IGRhc2hDYXNlKHBhcnNlZFBhdGgubmFtZSk7CgogICAgICAgIGNvbnN0IGNzc0ZpbGUgPSBqb2luKGRlc3REaXIsIGBjc3MvZl8ke2Rhc2hlcml6ZWR9LSR7aGFzaE5hbWV9LmNzc2ApOwogICAgICAgIHdyaXRlRmlsZVN5bmMoY3NzRmlsZSwgY3NzQ29udGVudCB8fCBgLyogRW1wdHkgZmlsZSAqL2ApOwogICAgICB9CiAgICB9CiAgfSBjYXRjaCAoZSkgewogICAgY29uc29sZS5lcnJvcihlKTsKICB9Cn07CgpleHBvcnQgY29uc3QgbWluaW1pemVGaWxlID0gYXN5bmMgKGRpcm5hbWU6IHN0cmluZywgZmlsZTogc3RyaW5nLCBwcm9kID0gaXNQcm9kdWN0aW9uKCkpID0+IHsKICB0cnkgewogICAgY29uc3QgZGVzdERpciA9IGF3YWl0IGdldERlc3REaXIoZGlybmFtZSk7CiAgICBjb25zdCB2YWxpZEZpbGUgPSBpc1NhbHR5RmlsZShmaWxlKTsKCiAgICBpZiAodmFsaWRGaWxlKSB7CiAgICAgIGNvbnN0IG9yaWdpbmFsID0gcmVhZEZpbGVTeW5jKGZpbGUsICd1dGY4Jyk7CgogICAgICBjb25zdCBjb25maWcgPSBhd2FpdCBnZXRDb25maWcoZGlybmFtZSk7CiAgICAgIGNvbnN0IHsgY29udGVudHMgfSA9IGF3YWl0IGNvbXBpbGVTYWx0eUZpbGUoZGlybmFtZSwgZmlsZSwgZGVzdERpcik7CgogICAgICBsZXQgY3VycmVudCA9IG9yaWdpbmFsOwoKICAgICAgZm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGNvbnRlbnRzKSkgewogICAgICAgIGlmICh2YWx1ZS5pc0tleWZyYW1lcykgY29udGludWU7CgogICAgICAgIGlmICghdmFsdWUuZ2VuZXJhdG9yKSBjb250aW51ZTsKICAgICAgICBjb25zdCBnZW5lcmF0b3IgPSB2YWx1ZS5nZW5lcmF0b3IuX3dpdGhCdWlsZENvbnRleHQoewogICAgICAgICAgY2FsbGVyTmFtZTogbmFtZSwKICAgICAgICAgIGlzUHJvZHVjdGlvbjogcHJvZCwKICAgICAgICAgIGNvbmZpZywKICAgICAgICB9KTsKCiAgICAgICAgY29uc3QgW3N0YXJ0LCBlbmRdID0gYXdhaXQgZ2V0RnVuY3Rpb25SYW5nZShjdXJyZW50LCBuYW1lKTsKICAgICAgICBjb25zdCByYW5nZSA9IGN1cnJlbnQuc2xpY2Uoc3RhcnQsIGVuZCk7CgogICAgICAgIGlmICh2YWx1ZS5pc0NsYXNzTmFtZSkgewogICAgICAgICAgY29uc3QgY29weSA9IGN1cnJlbnQ7CiAgICAgICAgICBjb25zdCBjbGllbnRWZXJzaW9uID0gYCAke25hbWV9ID0gY2xhc3NOYW1lKCIke2dlbmVyYXRvci5jbGFzc05hbWVzfSIpYDsKICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnJlcGxhY2UocmFuZ2UsIGNsaWVudFZlcnNpb24pOwoKICAgICAgICAgIGlmIChjb3B5ID09PSBjdXJyZW50KSBjb25zb2xlLmVycm9yKCdNaW5pbWl6ZSBmaWxlIGZhaWxlZCB0byBjaGFuZ2UgY29udGVudCcsIHsgbmFtZSB9KTsKICAgICAgICB9CgogICAgICAgIGlmIChyYW5nZS5pbmNsdWRlcygnc3R5bGVkJykpIHsKICAgICAgICAgIGNvbnN0IHRhZ05hbWUgPSAvc3R5bGVkXCgoW14sXSspLC8uZXhlYyhyYW5nZSk/LmF0KDEpPy50cmltKCk7CgogICAgICAgICAgLy8gUmVwbGFjZSB0aGUgc3R5bGVkIGNhbGwgd2l0aCB0aGUgY2xpZW50IHZlcnNpb24KICAgICAgICAgIGNvbnN0IGNvcHkgPSBjdXJyZW50OwogICAgICAgICAgY29uc3QgY2xpZW50VmVyc2lvbiA9IGAgJHtuYW1lfSA9IHN0eWxlZCgke3RhZ05hbWV9LCAiJHtnZW5lcmF0b3IuY2xhc3NOYW1lc30iLCAke0pTT04uc3RyaW5naWZ5KGdlbmVyYXRvci5jbGllbnRQcm9wcyl9KWA7CiAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC5yZXBsYWNlKHJhbmdlLCBjbGllbnRWZXJzaW9uKTsKCiAgICAgICAgICBpZiAoY29weSA9PT0gY3VycmVudCkgY29uc29sZS5lcnJvcignTWluaW1pemUgZmlsZSBmYWlsZWQgdG8gY2hhbmdlIGNvbnRlbnQnLCB7IG5hbWUsIHRhZ05hbWUgfSk7CiAgICAgICAgfQogICAgICB9CgogICAgICBpZiAoY29uZmlnLmltcG9ydFN0cmF0ZWd5ID09PSAnY29tcG9uZW50JykgewogICAgICAgIGNvbnN0IGZpbGVIYXNoID0gdG9IYXNoKGZpbGUsIDYpOwogICAgICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlUGF0aChmaWxlKTsKICAgICAgICBjb25zdCBkYXNoZXJpemVkID0gZGFzaENhc2UocGFyc2VkLm5hbWUpOwogICAgICAgIGNvbnN0IGNzc0ZpbGVOYW1lID0gYGZfJHtkYXNoZXJpemVkfS0ke2ZpbGVIYXNofS5jc3NgOwogICAgICAgIGN1cnJlbnQgPSBgaW1wb3J0ICcuLi8uLi9zYWx0eWdlbi9jc3MvJHtjc3NGaWxlTmFtZX0nO1xuJHtjdXJyZW50fWA7CiAgICAgIH0KCiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnJlcGxhY2UoYEBzYWx0eS1jc3MvcmVhY3QvY2xhc3MtbmFtZWAsIGBAc2FsdHktY3NzL3JlYWN0L2NsYXNzLW5hbWUtY2xpZW50YCk7CgogICAgICBjdXJyZW50ID0gY3VycmVudC5yZXBsYWNlKGB7IHN0eWxlZCB9YCwgYHsgc3R5bGVkQ2xpZW50IGFzIHN0eWxlZCB9YCk7CiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnJlcGxhY2UoYEBzYWx0eS1jc3MvcmVhY3Qvc3R5bGVkYCwgYEBzYWx0eS1jc3MvcmVhY3Qvc3R5bGVkLWNsaWVudGApOwoKICAgICAgcmV0dXJuIGN1cnJlbnQ7CiAgICB9CiAgfSBjYXRjaCAoZSkgewogICAgY29uc29sZS5lcnJvcignRXJyb3IgaW4gbWluaW1pemVGaWxlOicsIGUpOwogIH0KICByZXR1cm4gdW5kZWZpbmVkOwp9Owo=", import.meta.url).pathname, K = {
100
+ externalModules: [],
101
+ rcFile: void 0,
102
+ destDir: void 0
103
+ }, Bg = (g) => {
104
+ if (K.externalModules.length > 0) return K.externalModules;
105
+ const c = F(g, "utf8").match(/externalModules:\s?\[(.*)\]/);
106
+ if (!c) return [];
107
+ const l = c[1].split(",").map((Z) => Z.replace(/['"`]/g, "").trim());
108
+ return K.externalModules = l, l;
109
+ }, k = async (g) => {
110
+ if (K.destDir) return K.destDir;
111
+ const I = await eg(g), c = b(g, (I == null ? void 0 : I.saltygenDir) || "saltygen");
112
+ return K.destDir = c, c;
113
+ }, ug = ["salty", "css", "styles", "styled"], Og = (g = []) => new RegExp(`\\.(${[...ug, ...g].join("|")})\\.`), mg = (g, I = []) => Og(I).test(g), Rg = async (g) => {
114
+ if (K.rcFile) return K.rcFile;
115
+ if (g === "/") throw new Error("Could not find .saltyrc.json file");
116
+ const I = b(g, ".saltyrc.json"), c = await pg(I, "utf-8").then(JSON.parse).catch(() => {
117
+ });
118
+ return c ? (K.rcFile = c, c) : Rg(b(g, ".."));
119
+ }, eg = async (g) => {
120
+ var l, Z;
121
+ const I = await Rg(g), c = (l = I.projects) == null ? void 0 : l.find((n) => g.endsWith(n.dir || ""));
122
+ return c || ((Z = I.projects) == null ? void 0 : Z.find((n) => n.dir === I.defaultProject));
123
+ }, Pg = async (g) => {
124
+ const I = await eg(g), c = await k(g), l = b(g, (I == null ? void 0 : I.configDir) || "", "salty.config.ts"), Z = b(c, "salty.config.js"), n = await Ng(g), C = Bg(l);
125
+ await Xg.build({
126
+ entryPoints: [l],
127
+ minify: !0,
128
+ treeShaking: !0,
129
+ bundle: !0,
130
+ outfile: Z,
131
+ format: n,
132
+ external: C
133
+ });
134
+ const G = Date.now(), { config: W } = await import(`${Z}?t=${G}`);
135
+ return { config: W, path: Z };
136
+ }, Eg = async (g, I) => {
137
+ var dg, Ag;
138
+ const c = await k(g), l = {
139
+ mediaQueries: [],
140
+ globalStyles: [],
141
+ variables: [],
142
+ templates: []
143
+ };
144
+ await Promise.all(
145
+ [...I].map(async (A) => {
146
+ const { contents: X, outputFilePath: O } = await Ig(g, A, c);
147
+ Object.entries(X).forEach(([J, h]) => {
148
+ h.isMedia ? l.mediaQueries.push([J, h]) : h.isGlobalDefine ? l.globalStyles.push(h) : h.isDefineVariables ? l.variables.push(h) : h.isDefineTemplates && l.templates.push(h._setPath(`${J};;${O}`));
149
+ });
150
+ })
151
+ );
152
+ const { config: Z, path: n } = await Pg(g), C = { ...Z }, { mediaQueries: G } = l;
153
+ C.mediaQueries = Object.fromEntries(G.map(([A, X]) => [`@${A}`, X]));
154
+ const W = G.map(([A]) => `'@${A}'`).join(" | "), e = /* @__PURE__ */ new Set(), s = async (A, X = []) => {
155
+ if (!A) return [];
156
+ const O = Object.entries(A).map(async ([h, v]) => {
157
+ const P = async (r) => {
158
+ if (!r) return;
159
+ if (r instanceof Promise) return await P(await r);
160
+ if (typeof r == "function") return await P(await r());
161
+ if (typeof r == "object") return await s(r, [...X, h]);
162
+ const sg = hg(h), bg = E(h), Zg = [...X, sg].join(".");
163
+ e.add(`"${Zg}"`);
164
+ const q = [...X.map(E), bg].join("-"), Wg = wg(r);
165
+ return Wg ? `--${q}: ${Wg.transformed};` : `--${q}: ${r};`;
166
+ };
167
+ return await P(v);
168
+ });
169
+ return (await Promise.all(O)).flat();
170
+ }, i = async (A) => {
171
+ if (!A) return [];
172
+ const X = Object.entries(A).map(async ([J, h]) => {
173
+ const v = await s(h);
174
+ return J === "base" ? v.join("") : C.mediaQueries[J] ? `${C.mediaQueries[J]} { ${v.join("")} }` : `${J} { ${v.join("")} }`;
175
+ });
176
+ return (await Promise.all(X)).flat();
177
+ }, o = async (A) => {
178
+ if (!A) return [];
179
+ const X = Object.entries(A).map(async ([J, h]) => {
180
+ const v = Object.entries(h).map(async ([r, sg]) => {
181
+ const bg = await s(sg, [J]), Zg = `.${J}-${r}, [data-${J}="${r}"]`, q = bg.join("");
182
+ return `${Zg} { ${q} }`;
183
+ });
184
+ return (await Promise.all(v)).flat();
185
+ });
186
+ return (await Promise.all(X)).flat();
187
+ }, d = (A) => ({ ...A, responsive: void 0, conditional: void 0 }), m = (A) => l.variables.map((X) => A === "static" ? d(X._current) : X._current[A]), V = U(d(Z.variables), m("static")), u = await s(V), R = U((dg = Z.variables) == null ? void 0 : dg.responsive, m("responsive")), z = await i(R), j = U((Ag = Z.variables) == null ? void 0 : Ag.conditional, m("conditional")), M = await o(j), ig = b(c, "css/_variables.css"), w = `:root { ${u.join("")} ${z.join("")} } ${M.join("")}`;
188
+ p(ig, w), C.staticVariables = V;
189
+ const cg = b(c, "css/_global.css"), a = U(Z.global, l.globalStyles), Y = await Yg(a, "");
190
+ p(cg, `@layer global { ${Y} }`);
191
+ const y = b(c, "css/_reset.css"), N = Z.reset === "none" ? {} : typeof Z.reset == "object" ? Z.reset : Tg, B = await Yg(N, "");
192
+ p(y, `@layer reset { ${B} }`);
193
+ const H = b(c, "css/_templates.css"), S = U(Z.templates, l.templates), T = await Sg(S), L = vg(S);
194
+ p(H, `@layer templates { ${T} }`), C.templates = S;
195
+ const $ = Z.templates ? [fg(Z.templates)._setPath(`config;;${n}`)] : [], lg = xg(l.templates, $);
196
+ C.templatePaths = Object.fromEntries(Object.entries(lg).map(([A, X]) => [A, X._path]));
197
+ const D = b(c, "types/css-tokens.d.ts"), Jg = `
198
+ // Variable types
199
+ type VariableTokens = ${[...e].join("|")};
200
+ type PropertyValueToken = \`{\${VariableTokens}}\`;
201
+
202
+ // Template types
203
+ type TemplateTokens = {
204
+ ${Object.entries(L).map(([A, X]) => `${A}?: ${X}`).join(`
205
+ `)}
206
+ }
207
+
208
+ // Media query types
209
+ type MediaQueryKeys = ${W || "''"};
210
+ `;
211
+ p(D, Jg);
212
+ const rg = b(c, "cache/config-cache.json");
213
+ p(rg, JSON.stringify(C, null, 2));
214
+ const Fg = b(Dg, "../cache/config-cache.json");
215
+ p(Fg, JSON.stringify(C, null, 2));
216
+ }, yg = (g) => g.replace(/styled\(([^"'`{,]+),/g, (I, c) => {
217
+ if (/^['"`]/.test(c)) return I;
218
+ const Z = new RegExp(`import[^;]*${c}[,\\s{][^;]*from\\s?([^{};]+);`);
219
+ if (!Z.test(g)) return I;
220
+ const C = Z.exec(g);
221
+ if (C) {
222
+ const G = C.at(1);
223
+ if (ug.some((e) => G == null ? void 0 : G.includes(e))) return I;
224
+ }
225
+ return "styled('div',";
226
+ }), Mg = (g, I) => {
227
+ try {
228
+ const c = F(b(I, "saltygen/cache/config-cache.json"), "utf8");
229
+ return c ? `globalThis.saltyConfig = ${c};
230
+
231
+ ${g}` : `globalThis.saltyConfig = {};
232
+
233
+ ${g}`;
234
+ } catch {
235
+ return g;
236
+ }
237
+ }, Ig = async (g, I, c) => {
238
+ const l = Q(I), Z = b(c, "./temp");
239
+ ag(Z) || f(Z);
240
+ const n = gg(I);
241
+ let C = F(I, "utf8");
242
+ C = yg(C), C = Mg(C, g);
243
+ const G = b(c, "js", l + ".js"), W = await eg(g), e = b(g, (W == null ? void 0 : W.configDir) || "", "salty.config.ts"), s = Bg(e), i = await Ng(g);
244
+ await Xg.build({
245
+ stdin: {
246
+ contents: C,
247
+ sourcefile: n.base,
248
+ resolveDir: n.dir,
249
+ loader: "tsx"
250
+ },
251
+ minify: !1,
252
+ treeShaking: !0,
253
+ bundle: !0,
254
+ outfile: G,
255
+ format: i,
256
+ target: ["node20"],
257
+ keepNames: !0,
258
+ external: s,
259
+ packages: "external",
260
+ plugins: [
261
+ {
262
+ name: "test",
263
+ setup: (m) => {
264
+ m.onLoad({ filter: /.*\.css|salty|styles|styled\.ts/ }, (V) => {
265
+ const u = F(V.path, "utf8");
266
+ return { contents: yg(u), loader: "ts" };
267
+ });
268
+ }
269
+ }
270
+ ]
271
+ });
272
+ const o = Date.now();
273
+ return { contents: await import(`${G}?t=${o}`), outputFilePath: G };
274
+ }, $g = async (g) => {
275
+ const I = await k(g), c = b(I, "cache/config-cache.json"), l = F(c, "utf8");
276
+ if (!l) throw new Error("Could not find config cache file");
277
+ return JSON.parse(l);
278
+ }, og = async (g) => {
279
+ const I = await $g(g), c = await k(g), l = b(c, "salty.config.js"), Z = Date.now(), { config: n } = await import(`${l}?t=${Z}`);
280
+ return U(n, I);
281
+ }, Gg = () => {
282
+ try {
283
+ return process.env.NODE_ENV === "production";
284
+ } catch {
285
+ return !1;
286
+ }
287
+ }, aI = async (g, I = Gg(), c = !0) => {
288
+ try {
289
+ const l = Date.now();
290
+ I ? _.info("Generating CSS in production mode! 🔥") : _.info("Generating CSS in development mode! 🚀");
291
+ const Z = [], n = [], C = await k(g), G = b(C, "index.css");
292
+ c && (() => {
293
+ ag(C) && Hg("rm -rf " + C), f(C, { recursive: !0 }), f(b(C, "css")), f(b(C, "types")), f(b(C, "js")), f(b(C, "cache"));
294
+ })();
295
+ const e = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set();
296
+ async function i(a) {
297
+ const Y = ["node_modules", "saltygen"], y = Kg(a);
298
+ if (y.isDirectory()) {
299
+ const t = zg(a);
300
+ if (Y.some((B) => a.includes(B))) return;
301
+ await Promise.all(t.map((B) => i(b(a, B))));
302
+ } else if (y.isFile() && mg(a)) {
303
+ e.add(a);
304
+ const N = F(a, "utf8");
305
+ /define[\w\d]+\(/.test(N) && s.add(a);
306
+ }
307
+ }
308
+ await i(g), await Eg(g, s);
309
+ const o = {
310
+ keyframes: [],
311
+ components: [],
312
+ classNames: []
313
+ };
314
+ await Promise.all(
315
+ [...e].map(async (a) => {
316
+ const { contents: Y } = await Ig(g, a, C);
317
+ for (let [y, t] of Object.entries(Y))
318
+ t instanceof Promise && (t = await t), t.isKeyframes ? o.keyframes.push({
319
+ value: t,
320
+ src: a,
321
+ name: y
322
+ }) : t.isClassName ? o.classNames.push({
323
+ ...t,
324
+ src: a,
325
+ name: y
326
+ }) : t.generator && o.components.push({
327
+ ...t,
328
+ src: a,
329
+ name: y
330
+ });
331
+ })
332
+ );
333
+ const d = await og(g);
334
+ for (const a of o.keyframes) {
335
+ const { value: Y } = a, y = `a_${Y.animationName}.css`, t = `css/${y}`, N = b(C, t);
336
+ Z.push(y), p(N, Y.css);
337
+ }
338
+ const m = {};
339
+ for (const a of o.components) {
340
+ const { src: Y, name: y } = a;
341
+ m[Y] || (m[Y] = []);
342
+ const t = a.generator._withBuildContext({
343
+ callerName: y,
344
+ isProduction: I,
345
+ config: d
346
+ });
347
+ n[t.priority] || (n[t.priority] = []);
348
+ const N = await t.css;
349
+ if (!N) continue;
350
+ n[t.priority].push(t.cssFileName);
351
+ const B = `css/${t.cssFileName}`, H = b(C, B);
352
+ p(H, N), d.importStrategy === "component" && m[Y].push(t.cssFileName);
353
+ }
354
+ for (const a of o.classNames) {
355
+ const { src: Y, name: y } = a;
356
+ m[Y] || (m[Y] = []);
357
+ const t = a.generator._withBuildContext({
358
+ callerName: y,
359
+ isProduction: I,
360
+ config: d
361
+ }), N = await t.css;
362
+ if (!N) continue;
363
+ n[t.priority] || (n[t.priority] = []), n[t.priority].push(t.cssFileName);
364
+ const B = `css/${t.cssFileName}`, H = b(C, B);
365
+ p(H, N), d.importStrategy === "component" && m[Y].push(t.cssFileName);
366
+ }
367
+ d.importStrategy === "component" && Object.entries(m).forEach(([a, Y]) => {
368
+ const y = Y.map((S) => `@import url('./${S}');`).join(`
369
+ `), t = Q(a, 6), N = gg(a), B = E(N.name), H = b(C, `css/f_${B}-${t}.css`);
370
+ p(H, y || "/* Empty file */");
371
+ });
372
+ const V = Z.map((a) => `@import url('./css/${a}');`).join(`
373
+ `);
374
+ let M = `/*!
375
+ * Generated with Salty CSS (https://salty-css.dev)
376
+ * Do not edit this file directly
377
+ */
378
+ @layer reset, global, templates, l0, l1, l2, l3, l4, l5, l6, l7, l8;
379
+
380
+ ${["_variables.css", "_reset.css", "_global.css", "_templates.css"].filter((a) => {
381
+ try {
382
+ return F(b(C, "css", a), "utf8").length > 0;
383
+ } catch {
384
+ return !1;
385
+ }
386
+ }).map((a) => `@import url('./css/${a}');`).join(
387
+ `
388
+ `
389
+ )}
390
+ ${V}`;
391
+ if (d.importStrategy !== "component") {
392
+ const a = n.reduce((Y, y, t) => {
393
+ const N = y.reduce((T, L) => {
394
+ var Cg;
395
+ const $ = b(C, "css", L), lg = F($, "utf8"), D = ((Cg = /.*-([^-]+)-\d+.css/.exec(L)) == null ? void 0 : Cg.at(1)) || Q($, 6);
396
+ return T.includes(D) ? T : `${T}
397
+ /*start:${D}-${L}*/
398
+ ${lg}
399
+ /*end:${D}*/
400
+ `;
401
+ }, ""), B = `l_${t}.css`, H = b(C, "css", B), S = `@layer l${t} { ${N}
402
+ }`;
403
+ return p(H, S), `${Y}
404
+ @import url('./css/${B}');`;
405
+ }, "");
406
+ M += a;
407
+ }
408
+ p(G, M);
409
+ const w = Date.now() - l, cg = w < 200 ? "🔥" : w < 500 ? "🚀" : w < 1e3 ? "🎉" : w < 2e3 ? "🚗" : w < 5e3 ? "🤔" : "🥴";
410
+ _.info(`Generated CSS in ${w}ms! ${cg}`);
411
+ } catch (l) {
412
+ console.error(l);
413
+ }
414
+ }, mI = async (g, I, c = Gg()) => {
415
+ try {
416
+ const l = await k(g);
417
+ if (mg(I)) {
418
+ const n = [], C = await og(g), { contents: G } = await Ig(g, I, l);
419
+ for (const [W, e] of Object.entries(G)) {
420
+ if (e.isKeyframes && e.css) {
421
+ const V = `css/${`a_${e.animationName}.css`}`, u = b(l, V);
422
+ p(u, await e.css);
423
+ continue;
424
+ }
425
+ if (e.isClassName) {
426
+ const m = e.generator._withBuildContext({
427
+ callerName: W,
428
+ isProduction: c,
429
+ config: C
430
+ }), V = await m.css;
431
+ if (!V) continue;
432
+ n[m.priority] || (n[m.priority] = []), n[m.priority].push(m.cssFileName);
433
+ const u = `css/${m.cssFileName}`, R = b(l, u);
434
+ p(R, V);
435
+ continue;
436
+ }
437
+ if (!e.generator) continue;
438
+ const s = e.generator._withBuildContext({
439
+ callerName: W,
440
+ isProduction: c,
441
+ config: C
442
+ }), i = await s.css;
443
+ if (!i) continue;
444
+ const o = `css/${s.cssFileName}`, d = b(l, o);
445
+ p(d, i), n[s.priority] || (n[s.priority] = []), n[s.priority].push(s.cssFileName);
446
+ }
447
+ if (C.importStrategy !== "component")
448
+ n.forEach((W, e) => {
449
+ const s = `l_${e}.css`, i = b(l, "css", s);
450
+ let o = F(i, "utf8");
451
+ W.forEach((d) => {
452
+ var R;
453
+ const m = b(l, "css", d), V = ((R = /.*-([^-]+)-\d+.css/.exec(d)) == null ? void 0 : R.at(1)) || Q(m, 6);
454
+ if (!o.includes(V)) {
455
+ const z = F(m, "utf8"), j = `/*start:${V}-${d}*/
456
+ ${z}
457
+ /*end:${V}*/
458
+ `;
459
+ o = `${o.replace(/\}$/, "")}
460
+ ${j}
461
+ }`;
462
+ }
463
+ }), p(i, o);
464
+ });
465
+ else {
466
+ const W = n.flat().map((d) => `@import url('./${d}');`).join(`
467
+ `), e = Q(I, 6), s = gg(I), i = E(s.name), o = b(l, `css/f_${i}-${e}.css`);
468
+ p(o, W || "/* Empty file */");
469
+ }
470
+ }
471
+ } catch (l) {
472
+ console.error(l);
473
+ }
474
+ }, eI = async (g, I, c = Gg()) => {
475
+ var l, Z;
476
+ try {
477
+ const n = await k(g);
478
+ if (mg(I)) {
479
+ const G = F(I, "utf8"), W = await og(g), { contents: e } = await Ig(g, I, n);
480
+ let s = G;
481
+ for (const [i, o] of Object.entries(e)) {
482
+ if (o.isKeyframes || !o.generator) continue;
483
+ const d = o.generator._withBuildContext({
484
+ callerName: i,
485
+ isProduction: c,
486
+ config: W
487
+ }), [m, V] = await Lg(s, i), u = s.slice(m, V);
488
+ if (o.isClassName) {
489
+ const R = s, z = ` ${i} = className("${d.classNames}")`;
490
+ s = s.replace(u, z), R === s && console.error("Minimize file failed to change content", { name: i });
491
+ }
492
+ if (u.includes("styled")) {
493
+ const R = (Z = (l = /styled\(([^,]+),/.exec(u)) == null ? void 0 : l.at(1)) == null ? void 0 : Z.trim(), z = s, j = ` ${i} = styled(${R}, "${d.classNames}", ${JSON.stringify(d.clientProps)})`;
494
+ s = s.replace(u, j), z === s && console.error("Minimize file failed to change content", { name: i, tagName: R });
495
+ }
496
+ }
497
+ if (W.importStrategy === "component") {
498
+ const i = Q(I, 6), o = gg(I);
499
+ s = `import '../../saltygen/css/${`f_${E(o.name)}-${i}.css`}';
500
+ ${s}`;
501
+ }
502
+ return s = s.replace("@salty-css/react/class-name", "@salty-css/react/class-name-client"), s = s.replace("{ styled }", "{ styledClient as styled }"), s = s.replace("@salty-css/react/styled", "@salty-css/react/styled-client"), s;
503
+ }
504
+ } catch (n) {
505
+ console.error("Error in minimizeFile:", n);
506
+ }
507
+ };
508
+ export {
509
+ tI as a,
510
+ mI as b,
511
+ Og as c,
512
+ Eg as d,
513
+ Ig as e,
514
+ aI as g,
515
+ mg as i,
516
+ _ as l,
517
+ eI as m,
518
+ ug as s
519
+ };