@decohere/forge 0.0.1-dev.20 → 0.0.1-dev.20261105.103

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 (181) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +152 -0
  3. package/es6/src/actions/build.action.js +3 -7
  4. package/es6/src/actions/clean.action.js +3 -6
  5. package/es6/src/actions/commit.action.js +3 -6
  6. package/es6/src/actions/copy.action.js +61 -12
  7. package/es6/src/actions/dependency-report.action.js +7 -7
  8. package/es6/src/actions/dependency-sync.action.js +8 -6
  9. package/es6/src/actions/docker.action.js +82 -36
  10. package/es6/src/actions/index.js +3 -2
  11. package/es6/src/actions/link.action.js +2 -5
  12. package/es6/src/actions/package.action.js +219 -0
  13. package/es6/src/actions/paths.action.js +97 -0
  14. package/es6/src/actions/publish.action.js +3 -6
  15. package/es6/src/actions/sync-lock-file.action.js +2 -4
  16. package/es6/src/actions/tag.action.js +5 -9
  17. package/es6/src/actions/typecheck.action.js +52 -0
  18. package/es6/src/actions/unlink.action.js +1 -3
  19. package/es6/src/actions/version.action.js +69 -17
  20. package/es6/src/actions/watch.action.js +2 -5
  21. package/es6/src/commands/build.command.js +4 -3
  22. package/es6/src/commands/dependency.command.js +1 -3
  23. package/es6/src/commands/docker.command.js +2 -4
  24. package/es6/src/commands/forge.command.js +1 -3
  25. package/es6/src/commands/index.js +3 -2
  26. package/es6/src/commands/link.command.js +4 -3
  27. package/es6/src/commands/package.command.js +26 -0
  28. package/es6/src/commands/paths.command.js +14 -0
  29. package/es6/src/commands/publish.command.js +1 -3
  30. package/es6/src/commands/tag.command.js +1 -3
  31. package/es6/src/commands/typecheck.command.js +14 -0
  32. package/es6/src/commands/version.command.js +3 -3
  33. package/es6/src/const.js +0 -2
  34. package/es6/src/create-workspace.js +26 -0
  35. package/es6/src/errors.js +1 -3
  36. package/es6/src/extensions/project.extensions.js +5 -7
  37. package/es6/src/factories/swc-config.factory.js +29 -9
  38. package/es6/src/forge.module.js +15 -20
  39. package/es6/src/index.js +2 -2
  40. package/es6/src/packaging/dependency-pinner.service.js +103 -0
  41. package/es6/src/packaging/deployable.js +21 -0
  42. package/es6/src/packaging/import-graph.service.js +122 -0
  43. package/es6/src/packaging/release-exports.js +80 -0
  44. package/es6/src/packaging/ui-assets.js +49 -0
  45. package/es6/src/semver/index.js +1 -0
  46. package/es6/src/semver/semver.js +75 -0
  47. package/es6/src/services/dependency-resolver.service.js +70 -26
  48. package/es6/src/services/file-writer.service.js +2 -11
  49. package/es6/src/services/incremental-watch.js +18 -0
  50. package/es6/src/services/output-cache.js +29 -0
  51. package/es6/src/services/swc-transpiler.js +85 -99
  52. package/es6/src/services/transpile-cache.js +29 -0
  53. package/es6/src/services/ts-compiler-options.js +39 -0
  54. package/es6/src/services/ts-program-host.js +4 -6
  55. package/es6/src/services/type-emission-program.js +25 -10
  56. package/es6/src/services/type-emitter.js +57 -20
  57. package/es6/src/transpile/index.js +6 -0
  58. package/es6/src/types/build-target.type.js +0 -2
  59. package/es6/src/types/configuration.type.js +0 -2
  60. package/es6/src/types/dependency.types.js +0 -2
  61. package/es6/src/types/swc-config.type.js +0 -2
  62. package/es6/src/types/transform-response.model.js +0 -7
  63. package/es6/src/types/transformer.type.js +0 -2
  64. package/es6/src/types/workspace-config.type.js +0 -2
  65. package/es6/src/vitest/forge-build.plugin.js +27 -43
  66. package/es6/src/vitest/index.js +0 -2
  67. package/es6/src/workspace.config.js +26 -6
  68. package/package.json +21 -10
  69. package/types/src/actions/build.action.d.ts +4 -4
  70. package/types/src/actions/clean.action.d.ts +3 -3
  71. package/types/src/actions/commit.action.d.ts +3 -3
  72. package/types/src/actions/copy.action.d.ts +18 -3
  73. package/types/src/actions/dependency-report.action.d.ts +3 -3
  74. package/types/src/actions/dependency-sync.action.d.ts +3 -3
  75. package/types/src/actions/docker.action.d.ts +14 -3
  76. package/types/src/actions/index.d.ts +3 -0
  77. package/types/src/actions/link.action.d.ts +3 -3
  78. package/types/src/actions/package.action.d.ts +38 -0
  79. package/types/src/actions/paths.action.d.ts +28 -0
  80. package/types/src/actions/publish.action.d.ts +4 -4
  81. package/types/src/actions/sync-lock-file.action.d.ts +2 -2
  82. package/types/src/actions/tag.action.d.ts +3 -3
  83. package/types/src/actions/typecheck.action.d.ts +14 -0
  84. package/types/src/actions/unlink.action.d.ts +2 -2
  85. package/types/src/actions/version.action.d.ts +14 -4
  86. package/types/src/actions/watch.action.d.ts +3 -3
  87. package/types/src/commands/build.command.d.ts +3 -2
  88. package/types/src/commands/dependency.command.d.ts +2 -2
  89. package/types/src/commands/docker.command.d.ts +1 -1
  90. package/types/src/commands/forge.command.d.ts +2 -2
  91. package/types/src/commands/index.d.ts +3 -0
  92. package/types/src/commands/link.command.d.ts +3 -2
  93. package/types/src/commands/package.command.d.ts +11 -0
  94. package/types/src/commands/paths.command.d.ts +6 -0
  95. package/types/src/commands/publish.command.d.ts +1 -1
  96. package/types/src/commands/tag.command.d.ts +1 -1
  97. package/types/src/commands/typecheck.command.d.ts +6 -0
  98. package/types/src/commands/version.command.d.ts +1 -1
  99. package/types/src/create-workspace.d.ts +7 -0
  100. package/types/src/errors.d.ts +1 -1
  101. package/types/src/extensions/project.extensions.d.ts +2 -2
  102. package/types/src/factories/swc-config.factory.d.ts +3 -2
  103. package/types/src/forge.module.d.ts +10 -4
  104. package/types/src/index.d.ts +2 -0
  105. package/types/src/packaging/dependency-pinner.service.d.ts +20 -0
  106. package/types/src/packaging/deployable.d.ts +17 -0
  107. package/types/src/packaging/import-graph.service.d.ts +33 -0
  108. package/types/src/packaging/release-exports.d.ts +18 -0
  109. package/types/src/packaging/ui-assets.d.ts +21 -0
  110. package/types/src/semver/index.d.ts +1 -0
  111. package/types/src/semver/semver.d.ts +20 -0
  112. package/types/src/services/dependency-resolver.service.d.ts +8 -1
  113. package/types/src/services/file-writer.service.d.ts +1 -2
  114. package/types/src/services/incremental-watch.d.ts +13 -0
  115. package/types/src/services/output-cache.d.ts +10 -0
  116. package/types/src/services/swc-transpiler.d.ts +28 -15
  117. package/types/src/services/transpile-cache.d.ts +17 -0
  118. package/types/src/services/ts-compiler-options.d.ts +8 -0
  119. package/types/src/services/ts-program-host.d.ts +2 -2
  120. package/types/src/services/type-emission-program.d.ts +10 -3
  121. package/types/src/services/type-emitter.d.ts +21 -8
  122. package/types/src/transpile/index.d.ts +6 -0
  123. package/types/src/types/configuration.type.d.ts +6 -1
  124. package/types/src/types/dependency.types.d.ts +8 -9
  125. package/types/src/types/swc-config.type.d.ts +7 -1
  126. package/types/src/types/transform-response.model.d.ts +2 -7
  127. package/types/src/types/transformer.type.d.ts +3 -12
  128. package/types/src/types/workspace-config.type.d.ts +3 -3
  129. package/types/src/vitest/forge-build.plugin.d.ts +0 -2
  130. package/commonjs/src/actions/build.action.js +0 -116
  131. package/commonjs/src/actions/clean.action.js +0 -55
  132. package/commonjs/src/actions/commit.action.js +0 -87
  133. package/commonjs/src/actions/copy.action.js +0 -83
  134. package/commonjs/src/actions/dependency-report.action.js +0 -142
  135. package/commonjs/src/actions/dependency-sync.action.js +0 -100
  136. package/commonjs/src/actions/docker.action.js +0 -162
  137. package/commonjs/src/actions/index.js +0 -33
  138. package/commonjs/src/actions/link.action.js +0 -156
  139. package/commonjs/src/actions/publish.action.js +0 -156
  140. package/commonjs/src/actions/sync-lock-file.action.js +0 -43
  141. package/commonjs/src/actions/tag.action.js +0 -76
  142. package/commonjs/src/actions/unlink.action.js +0 -76
  143. package/commonjs/src/actions/version.action.js +0 -209
  144. package/commonjs/src/actions/watch.action.js +0 -51
  145. package/commonjs/src/commands/build.command.js +0 -49
  146. package/commonjs/src/commands/dependency.command.js +0 -88
  147. package/commonjs/src/commands/docker.command.js +0 -28
  148. package/commonjs/src/commands/forge.command.js +0 -24
  149. package/commonjs/src/commands/index.js +0 -27
  150. package/commonjs/src/commands/link.command.js +0 -89
  151. package/commonjs/src/commands/publish.command.js +0 -32
  152. package/commonjs/src/commands/tag.command.js +0 -28
  153. package/commonjs/src/commands/version.command.js +0 -36
  154. package/commonjs/src/const.js +0 -81
  155. package/commonjs/src/errors.js +0 -39
  156. package/commonjs/src/extensions/project.extensions.js +0 -94
  157. package/commonjs/src/factories/swc-config.factory.js +0 -98
  158. package/commonjs/src/forge.module.js +0 -115
  159. package/commonjs/src/index.js +0 -46
  160. package/commonjs/src/mixins/caches-outputs.mixin.js +0 -44
  161. package/commonjs/src/mixins/incremental-transform.mixin.js +0 -36
  162. package/commonjs/src/services/dependency-resolver.service.js +0 -172
  163. package/commonjs/src/services/file-writer.service.js +0 -232
  164. package/commonjs/src/services/swc-transpiler.js +0 -235
  165. package/commonjs/src/services/ts-program-host.js +0 -135
  166. package/commonjs/src/services/type-emission-program.js +0 -160
  167. package/commonjs/src/services/type-emitter.js +0 -141
  168. package/commonjs/src/types/build-target.type.js +0 -17
  169. package/commonjs/src/types/configuration.type.js +0 -6
  170. package/commonjs/src/types/dependency.types.js +0 -6
  171. package/commonjs/src/types/swc-config.type.js +0 -17
  172. package/commonjs/src/types/transform-response.model.js +0 -65
  173. package/commonjs/src/types/transformer.type.js +0 -13
  174. package/commonjs/src/types/workspace-config.type.js +0 -6
  175. package/commonjs/src/vitest/forge-build.plugin.js +0 -129
  176. package/commonjs/src/vitest/index.js +0 -13
  177. package/commonjs/src/workspace.config.js +0 -75
  178. package/es6/src/mixins/caches-outputs.mixin.js +0 -34
  179. package/es6/src/mixins/incremental-transform.mixin.js +0 -26
  180. package/types/src/mixins/caches-outputs.mixin.d.ts +0 -7
  181. package/types/src/mixins/incremental-transform.mixin.d.ts +0 -13
@@ -9,13 +9,13 @@ function _ts_metadata(k, v) {
9
9
  }
10
10
  import path from "node:path";
11
11
  import { injectable } from "@decohere/crucible/decorators";
12
- // biome-ignore lint/style/useImportType: <DI>
13
- import { Workspace } from "@decohere/mesh";
14
- import { ActionResponse } from "@decohere/nexus/cli";
15
- import { Docker as DockerInterop } from "@decohere/nexus/interop";
16
- import { io } from "@decohere/nexus/io";
12
+ import { Workspace } from "@decohere/workspace";
13
+ import { ActionResponse } from "@decohere/devkit/cli";
14
+ import { Docker as DockerInterop } from "@decohere/devkit/interop";
15
+ import { io } from "@decohere/core/io";
17
16
  import { scribe } from "@decohere/scribe";
18
17
  import { ForgeError, formatUnknownError } from "../errors.js";
18
+ import { deployable, PACKAGE_DIR } from "../packaging/deployable.js";
19
19
  export class Docker {
20
20
  workspace;
21
21
  #logger = scribe.logger(Docker.name);
@@ -27,10 +27,12 @@ export class Docker {
27
27
  async run(options) {
28
28
  const projects = await this.getDockerProjects(this.workspace.getProjects(options.configuration));
29
29
  if (projects.length === 0) {
30
- throw new ForgeError(`No projects found with a Dockerfile`);
30
+ this.#logger.info("No projects found with a Dockerfile — nothing to dockerize");
31
+ return ActionResponse.Success(Docker.name, []);
31
32
  }
33
+ const workspacePackageJson = await this.workspace.getPackageJson();
32
34
  const version = await this.workspace.getVersion();
33
- const responses = await Promise.all(projects.map(async (project)=>await this.buildProject(project, version, options)));
35
+ const responses = await Promise.all(projects.map(async (project)=>await this.buildProject(project, workspacePackageJson, version, options)));
34
36
  const failed = responses.filter((response)=>!response.succeeded);
35
37
  if (failed.length > 0) {
36
38
  return ActionResponse.Error(Docker.name, responses);
@@ -40,60 +42,76 @@ export class Docker {
40
42
  async getDockerProjects(projects) {
41
43
  const result = [];
42
44
  for (const project of projects){
43
- const dockerfile = project.dockerConfig?.dockerfile ?? "Dockerfile";
44
- const dockerfilePath = path.join(project.projectRoot, dockerfile);
45
- if (!await io.fileExists(dockerfilePath)) {
46
- this.#logger.info(`Skipping ${project.name}: missing ${dockerfile}`);
45
+ if (!await deployable.isDeployable(project)) {
46
+ this.#logger.info(`Skipping ${project.name}: missing ${deployable.dockerfileName(project)}`);
47
47
  continue;
48
48
  }
49
49
  result.push(project);
50
50
  }
51
51
  return result;
52
52
  }
53
- async buildProject(project, version, options) {
53
+ /**
54
+ * A Dockerfile that copies `.package/` needs `forge package` to have run. Fail before the
55
+ * build with that instruction rather than with Docker's "not found" from deep in a layer.
56
+ */ async assertPackaged(project) {
57
+ const dockerfile = await io.readFile(deployable.dockerfilePath(project)).catch(()=>"");
58
+ if (!dockerfile.includes(PACKAGE_DIR)) {
59
+ return;
60
+ }
61
+ const packaged = path.join(project.projectRoot, PACKAGE_DIR, "package.json");
62
+ if (!await io.fileExists(packaged)) {
63
+ throw new ForgeError(`${project.name}: its Dockerfile copies ${PACKAGE_DIR}/, which does not exist. ` + `Run \`forge build --configuration release\` and \`forge package ${project.name}\` first.`);
64
+ }
65
+ }
66
+ async buildProject(project, workspacePackageJson, version, options) {
54
67
  const dockerConfig = project.dockerConfig ?? {};
55
68
  const envBuildArgs = this.parseJsonEnv("FORGE_DOCKER_BUILD_ARGS_JSON", {});
56
69
  const envSecrets = this.parseJsonEnv("FORGE_DOCKER_SECRETS_JSON", {});
57
70
  const envTags = this.parseJsonEnv("FORGE_DOCKER_EXTRA_TAGS_JSON", []);
58
- const image = dockerConfig.image ?? this.defaultImageName(project.name);
71
+ const image = dockerConfig.image ?? this.defaultImageName(project.name, workspacePackageJson);
59
72
  const dockerfile = dockerConfig.dockerfile ?? "Dockerfile";
60
- const tags = [
61
- `${image}:${version}`,
73
+ const extraTags = this.extraTagsForImage(image, [
62
74
  ...dockerConfig.tags ?? [],
63
75
  ...envTags
76
+ ]);
77
+ const tags = [
78
+ `${image}:${version}`,
79
+ ...extraTags
64
80
  ];
65
81
  const buildArgs = this.interpolateBuildArgs({
66
- ...dockerConfig.buildArgs ?? {},
82
+ ...dockerConfig.buildArgs,
67
83
  ...envBuildArgs
68
84
  }, version);
69
85
  const secrets = {
70
- ...dockerConfig.secrets ?? {},
86
+ ...dockerConfig.secrets,
71
87
  ...envSecrets
72
88
  };
73
89
  this.#logger.info(`${options.dryRun ? "[dry-run] " : ""}Building ${project.name}`);
74
90
  try {
75
- if (!options.dryRun) {
76
- await this.docker.build(project.projectRoot, {
77
- cwd: project.projectRoot,
78
- dockerfile: path.join(project.projectRoot, dockerfile),
79
- tags,
80
- buildArgs,
81
- secrets
82
- });
83
- if (options.push || dockerConfig.push) {
84
- for (const tag of tags){
85
- await this.docker.push(tag, {
86
- cwd: project.projectRoot
87
- });
88
- }
91
+ await this.assertPackaged(project);
92
+ await this.docker.build(project.projectRoot, {
93
+ cwd: project.projectRoot,
94
+ dockerfile: path.join(project.projectRoot, dockerfile),
95
+ tags,
96
+ buildArgs,
97
+ secrets
98
+ });
99
+ const shouldPush = options.push || dockerConfig.push;
100
+ if (shouldPush && !options.dryRun) {
101
+ for (const tag of tags){
102
+ await this.docker.push(tag, {
103
+ cwd: project.projectRoot
104
+ });
89
105
  }
106
+ } else if (shouldPush && options.dryRun) {
107
+ this.#logger.info(`[dry-run] Skipping push for ${project.name}`);
90
108
  }
91
109
  return {
92
110
  projectName: project.name,
93
111
  image,
94
112
  tags,
95
113
  succeeded: true,
96
- message: options.dryRun ? "Dry run" : `Built ${image}`
114
+ message: options.dryRun ? `Built ${image} (not pushed)` : `Built ${image}`
97
115
  };
98
116
  } catch (reason) {
99
117
  const message = formatUnknownError(reason);
@@ -115,8 +133,30 @@ export class Docker {
115
133
  }
116
134
  return result;
117
135
  }
118
- defaultImageName(projectName) {
119
- return `${this.#defaultRegistry}/${this.normalizeDockerRepository(projectName)}`;
136
+ /**
137
+ * Keep FORGE_DOCKER_EXTRA_TAGS_JSON scoped to this image so multi-image
138
+ * publishes do not stamp create:latest onto the app Dev Container (and vice versa).
139
+ */ extraTagsForImage(image, tags) {
140
+ const prefix = `${image}:`;
141
+ const seen = new Set();
142
+ const result = [];
143
+ for (const tag of tags){
144
+ if (tag === image || tag.startsWith(prefix)) {
145
+ if (!seen.has(tag)) {
146
+ seen.add(tag);
147
+ result.push(tag);
148
+ }
149
+ }
150
+ }
151
+ return result;
152
+ }
153
+ defaultImageName(projectName, workspacePackageJson) {
154
+ const repositoryPath = process.env.FORGE_DOCKER_NAMESPACE?.trim() || workspacePackageJson.getRepositoryFullName() || this.normalizeDockerRepository(projectName);
155
+ const projectSlug = this.normalizeProjectSlug(projectName);
156
+ if (repositoryPath.includes("/") && projectSlug !== "") {
157
+ return `${this.#defaultRegistry}/${repositoryPath}/${projectSlug}`;
158
+ }
159
+ return `${this.#defaultRegistry}/${repositoryPath}`;
120
160
  }
121
161
  normalizeDockerRepository(name) {
122
162
  const repository = name.replace(/^@/, "").split("/").map((segment)=>segment.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "")).filter(Boolean).join("/");
@@ -125,6 +165,14 @@ export class Docker {
125
165
  }
126
166
  return repository;
127
167
  }
168
+ normalizeProjectSlug(name) {
169
+ const unscoped = name.includes("/") ? name.split("/").at(-1) ?? name : name;
170
+ const slug = unscoped.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
171
+ if (slug === "") {
172
+ throw new ForgeError(`Could not derive a Docker project slug from project name "${name}"`);
173
+ }
174
+ return slug;
175
+ }
128
176
  parseJsonEnv(name, fallback) {
129
177
  const value = process.env[name];
130
178
  if (value == null || value.trim() === "") {
@@ -144,5 +192,3 @@ Docker = _ts_decorate([
144
192
  typeof Workspace === "undefined" ? Object : Workspace
145
193
  ])
146
194
  ], Docker);
147
-
148
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9hY3Rpb25zL2RvY2tlci5hY3Rpb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gXCJAZGVjb2hlcmUvY3J1Y2libGUvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHR5cGUgeyBQcm9qZWN0IH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG4vLyBiaW9tZS1pZ25vcmUgbGludC9zdHlsZS91c2VJbXBvcnRUeXBlOiA8REk+XG5pbXBvcnQgeyBXb3Jrc3BhY2UgfSBmcm9tIFwiQGRlY29oZXJlL21lc2hcIjtcbmltcG9ydCB0eXBlIHsgQWN0aW9uLCBSZXN1bHRTdGF0dXMgfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2NsaVwiO1xuaW1wb3J0IHsgQWN0aW9uUmVzcG9uc2UgfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2NsaVwiO1xuaW1wb3J0IHsgRG9ja2VyIGFzIERvY2tlckludGVyb3AgfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2ludGVyb3BcIjtcbmltcG9ydCB7IGlvIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9pb1wiO1xuaW1wb3J0IHsgc2NyaWJlIH0gZnJvbSBcIkBkZWNvaGVyZS9zY3JpYmVcIjtcbmltcG9ydCB7IEZvcmdlRXJyb3IsIGZvcm1hdFVua25vd25FcnJvciB9IGZyb20gXCIuLi9lcnJvcnMuanNcIjtcblxuZXhwb3J0IHR5cGUgRG9ja2VyT3B0aW9ucyA9IHtcblx0Y29uZmlndXJhdGlvbjogc3RyaW5nO1xuXHRkcnlSdW4/OiBib29sZWFuO1xuXHRwdXNoPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCB0eXBlIERvY2tlclJlc3BvbnNlID0gUmVzdWx0U3RhdHVzICYge1xuXHRwcm9qZWN0TmFtZTogc3RyaW5nO1xuXHRpbWFnZTogc3RyaW5nO1xuXHR0YWdzOiBzdHJpbmdbXTtcblx0bWVzc2FnZTogc3RyaW5nO1xufTtcblxuQGluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIERvY2tlciBpbXBsZW1lbnRzIEFjdGlvbjxEb2NrZXJPcHRpb25zPiB7XG5cdCNsb2dnZXIgPSBzY3JpYmUubG9nZ2VyKERvY2tlci5uYW1lKTtcblx0cHJpdmF0ZSByZWFkb25seSBkb2NrZXIgPSBuZXcgRG9ja2VySW50ZXJvcCgpO1xuXHRyZWFkb25seSAjZGVmYXVsdFJlZ2lzdHJ5ID0gcHJvY2Vzcy5lbnYuRk9SR0VfRE9DS0VSX1JFR0lTVFJZPy50cmltKCkgfHwgXCJnaGNyLmlvXCI7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgd29ya3NwYWNlOiBXb3Jrc3BhY2UpIHt9XG5cblx0cHVibGljIGFzeW5jIHJ1bihvcHRpb25zOiBEb2NrZXJPcHRpb25zKTogUHJvbWlzZTxBY3Rpb25SZXNwb25zZTxEb2NrZXJSZXNwb25zZT4+IHtcblx0XHRjb25zdCBwcm9qZWN0cyA9IGF3YWl0IHRoaXMuZ2V0RG9ja2VyUHJvamVjdHMoXG5cdFx0XHR0aGlzLndvcmtzcGFjZS5nZXRQcm9qZWN0cyhvcHRpb25zLmNvbmZpZ3VyYXRpb24pLFxuXHRcdCk7XG5cdFx0aWYgKHByb2plY3RzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0dGhyb3cgbmV3IEZvcmdlRXJyb3IoYE5vIHByb2plY3RzIGZvdW5kIHdpdGggYSBEb2NrZXJmaWxlYCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgdmVyc2lvbiA9IGF3YWl0IHRoaXMud29ya3NwYWNlLmdldFZlcnNpb24oKTtcblx0XHRjb25zdCByZXNwb25zZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcblx0XHRcdHByb2plY3RzLm1hcChhc3luYyAocHJvamVjdCkgPT4gYXdhaXQgdGhpcy5idWlsZFByb2plY3QocHJvamVjdCwgdmVyc2lvbiwgb3B0aW9ucykpLFxuXHRcdCk7XG5cdFx0Y29uc3QgZmFpbGVkID0gcmVzcG9uc2VzLmZpbHRlcigocmVzcG9uc2UpID0+ICFyZXNwb25zZS5zdWNjZWVkZWQpO1xuXHRcdGlmIChmYWlsZWQubGVuZ3RoID4gMCkge1xuXHRcdFx0cmV0dXJuIEFjdGlvblJlc3BvbnNlLkVycm9yKERvY2tlci5uYW1lLCByZXNwb25zZXMpO1xuXHRcdH1cblx0XHRyZXR1cm4gQWN0aW9uUmVzcG9uc2UuU3VjY2VzcyhEb2NrZXIubmFtZSwgcmVzcG9uc2VzKTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgZ2V0RG9ja2VyUHJvamVjdHMocHJvamVjdHM6IHJlYWRvbmx5IFByb2plY3RbXSkge1xuXHRcdGNvbnN0IHJlc3VsdDogUHJvamVjdFtdID0gW107XG5cdFx0Zm9yIChjb25zdCBwcm9qZWN0IG9mIHByb2plY3RzKSB7XG5cdFx0XHRjb25zdCBkb2NrZXJmaWxlID0gcHJvamVjdC5kb2NrZXJDb25maWc/LmRvY2tlcmZpbGUgPz8gXCJEb2NrZXJmaWxlXCI7XG5cdFx0XHRjb25zdCBkb2NrZXJmaWxlUGF0aCA9IHBhdGguam9pbihwcm9qZWN0LnByb2plY3RSb290LCBkb2NrZXJmaWxlKTtcblx0XHRcdGlmICghKGF3YWl0IGlvLmZpbGVFeGlzdHMoZG9ja2VyZmlsZVBhdGgpKSkge1xuXHRcdFx0XHR0aGlzLiNsb2dnZXIuaW5mbyhgU2tpcHBpbmcgJHtwcm9qZWN0Lm5hbWV9OiBtaXNzaW5nICR7ZG9ja2VyZmlsZX1gKTtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdHJlc3VsdC5wdXNoKHByb2plY3QpO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBidWlsZFByb2plY3QoXG5cdFx0cHJvamVjdDogUHJvamVjdCxcblx0XHR2ZXJzaW9uOiBzdHJpbmcsXG5cdFx0b3B0aW9uczogRG9ja2VyT3B0aW9ucyxcblx0KTogUHJvbWlzZTxEb2NrZXJSZXNwb25zZT4ge1xuXHRcdGNvbnN0IGRvY2tlckNvbmZpZyA9IHByb2plY3QuZG9ja2VyQ29uZmlnID8/IHt9O1xuXHRcdGNvbnN0IGVudkJ1aWxkQXJncyA9IHRoaXMucGFyc2VKc29uRW52PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KFxuXHRcdFx0XCJGT1JHRV9ET0NLRVJfQlVJTERfQVJHU19KU09OXCIsXG5cdFx0XHR7fSxcblx0XHQpO1xuXHRcdGNvbnN0IGVudlNlY3JldHMgPSB0aGlzLnBhcnNlSnNvbkVudjxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+Pihcblx0XHRcdFwiRk9SR0VfRE9DS0VSX1NFQ1JFVFNfSlNPTlwiLFxuXHRcdFx0e30sXG5cdFx0KTtcblx0XHRjb25zdCBlbnZUYWdzID0gdGhpcy5wYXJzZUpzb25FbnY8c3RyaW5nW10+KFwiRk9SR0VfRE9DS0VSX0VYVFJBX1RBR1NfSlNPTlwiLCBbXSk7XG5cblx0XHRjb25zdCBpbWFnZSA9IGRvY2tlckNvbmZpZy5pbWFnZSA/PyB0aGlzLmRlZmF1bHRJbWFnZU5hbWUocHJvamVjdC5uYW1lKTtcblx0XHRjb25zdCBkb2NrZXJmaWxlID0gZG9ja2VyQ29uZmlnLmRvY2tlcmZpbGUgPz8gXCJEb2NrZXJmaWxlXCI7XG5cdFx0Y29uc3QgdGFncyA9IFtgJHtpbWFnZX06JHt2ZXJzaW9ufWAsIC4uLihkb2NrZXJDb25maWcudGFncyA/PyBbXSksIC4uLmVudlRhZ3NdO1xuXHRcdGNvbnN0IGJ1aWxkQXJncyA9IHRoaXMuaW50ZXJwb2xhdGVCdWlsZEFyZ3MoXG5cdFx0XHR7IC4uLihkb2NrZXJDb25maWcuYnVpbGRBcmdzID8/IHt9KSwgLi4uZW52QnVpbGRBcmdzIH0sXG5cdFx0XHR2ZXJzaW9uLFxuXHRcdCk7XG5cdFx0Y29uc3Qgc2VjcmV0cyA9IHsgLi4uKGRvY2tlckNvbmZpZy5zZWNyZXRzID8/IHt9KSwgLi4uZW52U2VjcmV0cyB9O1xuXG5cdFx0dGhpcy4jbG9nZ2VyLmluZm8oYCR7b3B0aW9ucy5kcnlSdW4gPyBcIltkcnktcnVuXSBcIiA6IFwiXCJ9QnVpbGRpbmcgJHtwcm9qZWN0Lm5hbWV9YCk7XG5cdFx0dHJ5IHtcblx0XHRcdGlmICghb3B0aW9ucy5kcnlSdW4pIHtcblx0XHRcdFx0YXdhaXQgdGhpcy5kb2NrZXIuYnVpbGQocHJvamVjdC5wcm9qZWN0Um9vdCwge1xuXHRcdFx0XHRcdGN3ZDogcHJvamVjdC5wcm9qZWN0Um9vdCxcblx0XHRcdFx0XHRkb2NrZXJmaWxlOiBwYXRoLmpvaW4ocHJvamVjdC5wcm9qZWN0Um9vdCwgZG9ja2VyZmlsZSksXG5cdFx0XHRcdFx0dGFncyxcblx0XHRcdFx0XHRidWlsZEFyZ3MsXG5cdFx0XHRcdFx0c2VjcmV0cyxcblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0aWYgKG9wdGlvbnMucHVzaCB8fCBkb2NrZXJDb25maWcucHVzaCkge1xuXHRcdFx0XHRcdGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMuZG9ja2VyLnB1c2godGFnLCB7IGN3ZDogcHJvamVjdC5wcm9qZWN0Um9vdCB9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0cHJvamVjdE5hbWU6IHByb2plY3QubmFtZSxcblx0XHRcdFx0aW1hZ2UsXG5cdFx0XHRcdHRhZ3MsXG5cdFx0XHRcdHN1Y2NlZWRlZDogdHJ1ZSxcblx0XHRcdFx0bWVzc2FnZTogb3B0aW9ucy5kcnlSdW4gPyBcIkRyeSBydW5cIiA6IGBCdWlsdCAke2ltYWdlfWAsXG5cdFx0XHR9O1xuXHRcdH0gY2F0Y2ggKHJlYXNvbikge1xuXHRcdFx0Y29uc3QgbWVzc2FnZSA9IGZvcm1hdFVua25vd25FcnJvcihyZWFzb24pO1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0cHJvamVjdE5hbWU6IHByb2plY3QubmFtZSxcblx0XHRcdFx0aW1hZ2UsXG5cdFx0XHRcdHRhZ3MsXG5cdFx0XHRcdHN1Y2NlZWRlZDogZmFsc2UsXG5cdFx0XHRcdG1lc3NhZ2UsXG5cdFx0XHRcdGVycm9yOiBgJHtwcm9qZWN0Lm5hbWV9OiAke21lc3NhZ2V9YCxcblx0XHRcdH07XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBpbnRlcnBvbGF0ZUJ1aWxkQXJncyhcblx0XHRidWlsZEFyZ3M6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQsXG5cdFx0dmVyc2lvbjogc3RyaW5nLFxuXHQpIHtcblx0XHRjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblx0XHRjb25zdCB2ZXJzaW9uUGxhY2Vob2xkZXIgPSBcIiRcIiArIFwie3ZlcnNpb259XCI7XG5cdFx0Zm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYnVpbGRBcmdzID8/IHt9KSkge1xuXHRcdFx0cmVzdWx0W2tleV0gPSB2YWx1ZS5zcGxpdCh2ZXJzaW9uUGxhY2Vob2xkZXIpLmpvaW4odmVyc2lvbik7XG5cdFx0fVxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblxuXHRwcml2YXRlIGRlZmF1bHRJbWFnZU5hbWUocHJvamVjdE5hbWU6IHN0cmluZykge1xuXHRcdHJldHVybiBgJHt0aGlzLiNkZWZhdWx0UmVnaXN0cnl9LyR7dGhpcy5ub3JtYWxpemVEb2NrZXJSZXBvc2l0b3J5KHByb2plY3ROYW1lKX1gO1xuXHR9XG5cblx0cHJpdmF0ZSBub3JtYWxpemVEb2NrZXJSZXBvc2l0b3J5KG5hbWU6IHN0cmluZykge1xuXHRcdGNvbnN0IHJlcG9zaXRvcnkgPSBuYW1lXG5cdFx0XHQucmVwbGFjZSgvXkAvLCBcIlwiKVxuXHRcdFx0LnNwbGl0KFwiL1wiKVxuXHRcdFx0Lm1hcCgoc2VnbWVudCkgPT5cblx0XHRcdFx0c2VnbWVudFxuXHRcdFx0XHRcdC50b0xvd2VyQ2FzZSgpXG5cdFx0XHRcdFx0LnJlcGxhY2UoL1teYS16MC05XSsvZywgXCItXCIpXG5cdFx0XHRcdFx0LnJlcGxhY2UoL14tK3wtKyQvZywgXCJcIiksXG5cdFx0XHQpXG5cdFx0XHQuZmlsdGVyKEJvb2xlYW4pXG5cdFx0XHQuam9pbihcIi9cIik7XG5cblx0XHRpZiAocmVwb3NpdG9yeSA9PT0gXCJcIikge1xuXHRcdFx0dGhyb3cgbmV3IEZvcmdlRXJyb3IoYENvdWxkIG5vdCBkZXJpdmUgYSBEb2NrZXIgcmVwb3NpdG9yeSBmcm9tIHByb2plY3QgbmFtZSBcIiR7bmFtZX1cImApO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXBvc2l0b3J5O1xuXHR9XG5cblx0cHJpdmF0ZSBwYXJzZUpzb25FbnY8VD4obmFtZTogc3RyaW5nLCBmYWxsYmFjazogVCk6IFQge1xuXHRcdGNvbnN0IHZhbHVlID0gcHJvY2Vzcy5lbnZbbmFtZV07XG5cdFx0aWYgKHZhbHVlID09IG51bGwgfHwgdmFsdWUudHJpbSgpID09PSBcIlwiKSB7XG5cdFx0XHRyZXR1cm4gZmFsbGJhY2s7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiBKU09OLnBhcnNlKHZhbHVlKSBhcyBUO1xuXHRcdH0gY2F0Y2ggKHJlYXNvbikge1xuXHRcdFx0dGhyb3cgbmV3IEZvcmdlRXJyb3IoYEludmFsaWQgSlNPTiBpbiAke25hbWV9OiAke2Zvcm1hdFVua25vd25FcnJvcihyZWFzb24pfWApO1xuXHRcdH1cblx0fVxufVxuIl0sIm5hbWVzIjpbInBhdGgiLCJpbmplY3RhYmxlIiwiV29ya3NwYWNlIiwiQWN0aW9uUmVzcG9uc2UiLCJEb2NrZXIiLCJEb2NrZXJJbnRlcm9wIiwiaW8iLCJzY3JpYmUiLCJGb3JnZUVycm9yIiwiZm9ybWF0VW5rbm93bkVycm9yIiwibG9nZ2VyIiwibmFtZSIsImRvY2tlciIsInByb2Nlc3MiLCJlbnYiLCJGT1JHRV9ET0NLRVJfUkVHSVNUUlkiLCJ0cmltIiwid29ya3NwYWNlIiwicnVuIiwib3B0aW9ucyIsInByb2plY3RzIiwiZ2V0RG9ja2VyUHJvamVjdHMiLCJnZXRQcm9qZWN0cyIsImNvbmZpZ3VyYXRpb24iLCJsZW5ndGgiLCJ2ZXJzaW9uIiwiZ2V0VmVyc2lvbiIsInJlc3BvbnNlcyIsIlByb21pc2UiLCJhbGwiLCJtYXAiLCJwcm9qZWN0IiwiYnVpbGRQcm9qZWN0IiwiZmFpbGVkIiwiZmlsdGVyIiwicmVzcG9uc2UiLCJzdWNjZWVkZWQiLCJFcnJvciIsIlN1Y2Nlc3MiLCJyZXN1bHQiLCJkb2NrZXJmaWxlIiwiZG9ja2VyQ29uZmlnIiwiZG9ja2VyZmlsZVBhdGgiLCJqb2luIiwicHJvamVjdFJvb3QiLCJmaWxlRXhpc3RzIiwiaW5mbyIsInB1c2giLCJlbnZCdWlsZEFyZ3MiLCJwYXJzZUpzb25FbnYiLCJlbnZTZWNyZXRzIiwiZW52VGFncyIsImltYWdlIiwiZGVmYXVsdEltYWdlTmFtZSIsInRhZ3MiLCJidWlsZEFyZ3MiLCJpbnRlcnBvbGF0ZUJ1aWxkQXJncyIsInNlY3JldHMiLCJkcnlSdW4iLCJidWlsZCIsImN3ZCIsInRhZyIsInByb2plY3ROYW1lIiwibWVzc2FnZSIsInJlYXNvbiIsImVycm9yIiwidmVyc2lvblBsYWNlaG9sZGVyIiwia2V5IiwidmFsdWUiLCJPYmplY3QiLCJlbnRyaWVzIiwic3BsaXQiLCJub3JtYWxpemVEb2NrZXJSZXBvc2l0b3J5IiwicmVwb3NpdG9yeSIsInJlcGxhY2UiLCJzZWdtZW50IiwidG9Mb3dlckNhc2UiLCJCb29sZWFuIiwiZmFsbGJhY2siLCJKU09OIiwicGFyc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU9BLFVBQVUsWUFBWTtBQUM3QixTQUFTQyxVQUFVLFFBQVEsZ0NBQWdDO0FBRTNELDhDQUE4QztBQUM5QyxTQUFTQyxTQUFTLFFBQVEsaUJBQWlCO0FBRTNDLFNBQVNDLGNBQWMsUUFBUSxzQkFBc0I7QUFDckQsU0FBU0MsVUFBVUMsYUFBYSxRQUFRLDBCQUEwQjtBQUNsRSxTQUFTQyxFQUFFLFFBQVEscUJBQXFCO0FBQ3hDLFNBQVNDLE1BQU0sUUFBUSxtQkFBbUI7QUFDMUMsU0FBU0MsVUFBVSxFQUFFQyxrQkFBa0IsUUFBUSxlQUFlO0FBZ0I5RCxPQUFPLE1BQU1MOztJQUNaLENBQUEsTUFBTyxHQUFHRyxPQUFPRyxNQUFNLENBQUNOLE9BQU9PLElB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
@@ -6,11 +6,12 @@ export * from "./dependency-report.action.js";
6
6
  export * from "./dependency-sync.action.js";
7
7
  export * from "./docker.action.js";
8
8
  export * from "./link.action.js";
9
+ export * from "./package.action.js";
10
+ export * from "./paths.action.js";
9
11
  export * from "./publish.action.js";
10
12
  export * from "./sync-lock-file.action.js";
11
13
  export * from "./tag.action.js";
14
+ export * from "./typecheck.action.js";
12
15
  export * from "./unlink.action.js";
13
16
  export * from "./version.action.js";
14
17
  export * from "./watch.action.js";
15
-
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9hY3Rpb25zL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL2J1aWxkLmFjdGlvbi5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2xlYW4uYWN0aW9uLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb21taXQuYWN0aW9uLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb3B5LmFjdGlvbi5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZGVwZW5kZW5jeS1yZXBvcnQuYWN0aW9uLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kZXBlbmRlbmN5LXN5bmMuYWN0aW9uLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kb2NrZXIuYWN0aW9uLmpzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9saW5rLmFjdGlvbi5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vcHVibGlzaC5hY3Rpb24uanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3N5bmMtbG9jay1maWxlLmFjdGlvbi5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdGFnLmFjdGlvbi5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdW5saW5rLmFjdGlvbi5qc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdmVyc2lvbi5hY3Rpb24uanNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3dhdGNoLmFjdGlvbi5qc1wiO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsb0JBQW9CO0FBQ2xDLGNBQWMsb0JBQW9CO0FBQ2xDLGNBQWMscUJBQXFCO0FBQ25DLGNBQWMsbUJBQW1CO0FBQ2pDLGNBQWMsZ0NBQWdDO0FBQzlDLGNBQWMsOEJBQThCO0FBQzVDLGNBQWMscUJBQXFCO0FBQ25DLGNBQWMsbUJBQW1CO0FBQ2pDLGNBQWMsc0JBQXNCO0FBQ3BDLGNBQWMsNkJBQTZCO0FBQzNDLGNBQWMsa0JBQWtCO0FBQ2hDLGNBQWMscUJBQXFCO0FBQ25DLGNBQWMsc0JBQXNCO0FBQ3BDLGNBQWMsb0JBQW9CIn0=
@@ -10,9 +10,8 @@ function _ts_metadata(k, v) {
10
10
  import fs from "node:fs/promises";
11
11
  import path from "node:path";
12
12
  import { injectable } from "@decohere/crucible/decorators";
13
- // biome-ignore lint/style/useImportType: <DI>
14
- import { Workspace } from "@decohere/mesh";
15
- import { ActionResponse } from "@decohere/nexus/cli";
13
+ import { Workspace } from "@decohere/workspace";
14
+ import { ActionResponse } from "@decohere/devkit/cli";
16
15
  import { scribe } from "@decohere/scribe";
17
16
  import "../extensions/project.extensions.js";
18
17
  import { ForgeError } from "../errors.js";
@@ -127,5 +126,3 @@ Link = _ts_decorate([
127
126
  typeof Workspace === "undefined" ? Object : Workspace
128
127
  ])
129
128
  ], Link);
130
-
131
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9hY3Rpb25zL2xpbmsuYWN0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gXCJAZGVjb2hlcmUvY3J1Y2libGUvZGVjb3JhdG9yc1wiO1xuLy8gYmlvbWUtaWdub3JlIGxpbnQvc3R5bGUvdXNlSW1wb3J0VHlwZTogPERJPlxuaW1wb3J0IHsgV29ya3NwYWNlIH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgdHlwZSB7IEFjdGlvbiB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvY2xpXCI7XG5pbXBvcnQgeyBBY3Rpb25SZXNwb25zZSB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvY2xpXCI7XG5pbXBvcnQgeyBzY3JpYmUgfSBmcm9tIFwiQGRlY29oZXJlL3NjcmliZVwiO1xuaW1wb3J0IFwiLi4vZXh0ZW5zaW9ucy9wcm9qZWN0LmV4dGVuc2lvbnMuanNcIjtcbmltcG9ydCB7IEZvcmdlRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3JzLmpzXCI7XG5cbmV4cG9ydCBjb25zdCBMSU5LX01BTklGRVNUID0gXCIuZm9yZ2UtbGluay5qc29uXCI7XG5cbmV4cG9ydCB0eXBlIExpbmtPcHRpb25zID0ge1xuXHRjb25maWd1cmF0aW9uOiBzdHJpbmc7XG5cdHRhcmdldERpcjogc3RyaW5nO1xufTtcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfTElOS19DT05GSUdVUkFUSU9OID0gXCJsaW5rXCI7XG5cbmV4cG9ydCB0eXBlIExpbmtNYW5pZmVzdCA9IHtcblx0d29ya3NwYWNlUm9vdDogc3RyaW5nO1xuXHRwZWVyTm9kZU1vZHVsZXNEaXI/OiBzdHJpbmc7XG5cdGxpbmtzOiBBcnJheTx7IHBhY2thZ2VOYW1lOiBzdHJpbmc7IHN5bWxpbmtQYXRoOiBzdHJpbmc7IG9yaWdpbmFsUGF0aDogc3RyaW5nIHwgbnVsbCB9Pjtcbn07XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBMaW5rIGltcGxlbWVudHMgQWN0aW9uPExpbmtPcHRpb25zPiB7XG5cdCNsb2dnZXIgPSBzY3JpYmUubG9nZ2VyKExpbmsubmFtZSk7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgd29ya3NwYWNlOiBXb3Jrc3BhY2UpIHt9XG5cblx0cHVibGljIHJ1biA9IGFzeW5jIChvcHRpb25zOiBMaW5rT3B0aW9ucyk6IFByb21pc2U8QWN0aW9uUmVzcG9uc2U+ID0+IHtcblx0XHRjb25zdCB0YXJnZXREaXIgPSBwYXRoLnJlc29sdmUob3B0aW9ucy50YXJnZXREaXIpO1xuXHRcdGNvbnN0IG5vZGVNb2R1bGVzRGlyID0gcGF0aC5qb2luKHRhcmdldERpciwgXCJub2RlX21vZHVsZXNcIik7XG5cblx0XHRjb25zdCBzdGF0ID0gYXdhaXQgZnMuc3RhdChub2RlTW9kdWxlc0RpcikuY2F0Y2goKCkgPT4gbnVsbCk7XG5cdFx0aWYgKHN0YXQgPT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgbmV3IEZvcmdlRXJyb3IoXG5cdFx0XHRcdGBub2RlX21vZHVsZXMgbm90IGZvdW5kIGluIFwiJHt0YXJnZXREaXJ9XCIuIFJ1biBwbnBtIGluc3RhbGwgZmlyc3QuYCxcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgcHJvamVjdHMgPSB0aGlzLndvcmtzcGFjZS5nZXRQcm9qZWN0cyhvcHRpb25zLmNvbmZpZ3VyYXRpb24pO1xuXHRcdGlmIChwcm9qZWN0cy5sZW5ndGggPT09IDApIHtcblx0XHRcdHRocm93IG5ldyBGb3JnZUVycm9yKGBObyBwcm9qZWN0cyBmb3VuZCBmb3IgY29uZmlndXJhdGlvbiBcIiR7b3B0aW9ucy5jb25maWd1cmF0aW9ufVwiYCk7XG5cdFx0fVxuXG5cdFx0Ly8gTG9hZCBhbnkgZXhpc3RpbmcgbWFuaWZlc3Qgc28gb3JpZ2luYWxQYXRoIHZhbHVlcyBhcmUgcHJlc2VydmVkIG9uIHJlLWxpbmtcblx0XHRjb25zdCBtYW5pZmVzdFBhdGggPSBwYXRoLmpvaW4odGFyZ2V0RGlyLCBMSU5LX01BTklGRVNUKTtcblx0XHRjb25zdCBleGlzdGluZ01hbmlmZXN0VGV4dCA9IGF3YWl0IGZzLnJlYWRGaWxlKG1hbmlmZXN0UGF0aCwgXCJ1dGY4XCIpLmNhdGNoKCgpID0+IG51bGwpO1xuXHRcdGNvbnN0IGV4aXN0aW5nTWFuaWZlc3Q6IExpbmtNYW5pZmVzdCB8IG51bGwgPVxuXHRcdFx0ZXhpc3RpbmdNYW5pZmVzdFRleHQgIT0gbnVsbCA/IEpTT04ucGFyc2UoZXhpc3RpbmdNYW5pZmVzdFRleHQpIDogbnVsbDtcblxuXHRcdGNvbnN0IG1hbmlmZXN0OiBMaW5rTWFuaWZlc3QgPSB7XG5cdFx0XHR3b3Jrc3BhY2VSb290OiB0aGlzLndvcmtzcGFjZS5yb290RGlyLFxuXHRcdFx0bGlua3M6IFtdLFxuXHRcdH07XG5cblx0XHRmb3IgKGNvbnN0IHByb2plY3Qgb2YgcHJvamVjdHMpIHtcblx0XHRcdGNvbnN0IHBrZyA9IGF3YWl0IHByb2plY3QuZ2V0UGFja2FnZUpzb24oKTtcblx0XHRcdGNvbnN0IHBhY2thZ2VOYW1lID0gcGtnLm5hbWU7XG5cdFx0XHRpZiAoIXBhY2thZ2VOYW1lKSB7XG5cdFx0XHRcdHRoaXMuI2xvZ2dlci50cmFjZShgU2tpcHBpbmcgcHJvamVjdCBcIiR7cHJvamVjdC5uYW1lfVwiIOKAlCBubyBwYWNrYWdlIG5hbWVgKTtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlc29sdmUgdGhlIGJ1aWxkIG91dHB1dCBkaXJlY3RvcnkgKG5vIHRhcmdldCBhcmcg4oCUIGRlYnVnIGNvbmZpZyBpcyBub3QgcGFja2VkKVxuXHRcdFx0Y29uc3Qgb3V0RGlyID0gcHJvamVjdC5nZXRPdXREaXIoKTtcblx0XHRcdGNvbnN0IGFic29sdXRlT3V0RGlyID0gcGF0aC5yZXNvbHZlKG91dERpcik7XG5cblx0XHRcdC8vIFByZS1jcmVhdGUgdGhlIG91dHB1dCBkaXIgc28gdGhlIHN5bWxpbmsgaXMgdmFsaWQgZXZlbiBiZWZvcmUgYSBidWlsZCBjb21wbGV0ZXMuXG5cdFx0XHRhd2FpdCBmcy5ta2RpcihhYnNvbHV0ZU91dERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cblx0XHRcdC8vIENvbXB1dGUgc3ltbGluayBwYXRoIGluc2lkZSB0YXJnZXQgbm9kZV9tb2R1bGVzXG5cdFx0XHRjb25zdCBzeW1saW5rUGF0aCA9IHBhdGguam9pbihub2RlTW9kdWxlc0RpciwgLi4ucGFja2FnZU5hbWUuc3BsaXQoXCIvXCIpKTtcblx0XHRcdGNvbnN0IHN5bWxpbmtQYXJlbnQgPSBwYXRoLmRpcm5hbWUoc3ltbGlua1BhdGgpO1xuXG5cdFx0XHQvLyBDYXB0dXJlIGFueSBleGlzdGluZyBlbnRyeSBzbyB3ZSBjYW4gcmVzdG9yZSBpdCBvbiB1bmxpbmsuXG5cdFx0XHQvLyBJZiBhIG1hbmlmZXN0IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHBhY2thZ2UsIHByZXNlcnZlIGl0cyBvcmlnaW5hbFBhdGgg4oCUXG5cdFx0XHQvLyB0aGUgY3VycmVudCBzeW1saW5rIGlzIG91ciBvd24gYW5kIG11c3Qgbm90IGJlIHRyZWF0ZWQgYXMgdGhlIG9yaWdpbmFsLlxuXHRcdFx0bGV0IG9yaWdpbmFsUGF0aDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cdFx0XHRjb25zdCBleGlzdGluZ1N0YXQgPSBhd2FpdCBmcy5sc3RhdChzeW1saW5rUGF0aCkuY2F0Y2goKCkgPT4gbnVsbCk7XG5cdFx0XHRpZiAoZXhpc3RpbmdTdGF0ICE9IG51bGwpIHtcblx0XHRcdFx0Y29uc3QgZXhpc3RpbmdFbnRyeSA9IGV4aXN0aW5nTWFuaWZlc3Q/LmxpbmtzLmZpbmQoXG5cdFx0XHRcdFx0KGwpID0+IGwucGFja2FnZU5hbWUgPT09IHBhY2thZ2VOYW1lLFxuXHRcdFx0XHQpO1xuXHRcdFx0XHRpZiAoZXhpc3RpbmdFbnRyeSAhPSBudWxsKSB7XG5cdFx0XHRcdFx0Ly8gQWxyZWFkeSBsaW5rZWQg4oCUIHByZXNlcnZlIHRoZSByZWNvcmRlZCBvcmlnaW5hbFBhdGggYW5kIHJlcGxhY2UgdGhlIHN5bWxpbmtcblx0XHRcdFx0XHRvcmlnaW5hbFBhdGggPSBleGlzdGluZ0VudHJ5Lm9yaWdpbmFsUGF0aDtcblx0XHRcdFx0XHRpZiAoZXhpc3RpbmdTdGF0LmlzU3ltYm9saWNMaW5rKCkpIHtcblx0XHRcdFx0XHRcdGF3YWl0IGZzLnVubGluayhzeW1saW5rUGF0aCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2UgaWYgKGV4aXN0aW5nU3RhdC5pc1N5bWJvbGljTGluaygpKSB7XG5cdFx0XHRcdFx0b3JpZ2luYWxQYXRoID0gYXdhaXQgZnMucmVhZGxpbmsoc3ltbGlua1BhdGgpO1xuXHRcdFx0XHRcdGF3YWl0IGZzLnVubGluayhzeW1saW5rUGF0aCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gUmVhbCBkaXJlY3Rvcnkg4oCUIGJhY2sgaXQgdXAgYnkgcmVuYW1pbmdcblx0XHRcdFx0XHRvcmlnaW5hbFBhdGggPSBgJHtzeW1saW5rUGF0aH0uX19mb3JnZV9iYWNrdXBfX2A7XG5cdFx0XHRcdFx0YXdhaXQgZnMucmVuYW1lKHN5bWxpbmtQYXRoLCBvcmlnaW5hbFBhdGgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGF3YWl0IGZzLm1rZGlyKHN5bWxpbmtQYXJlbnQsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuXHRcdFx0YXdhaXQgZnMuc3ltbGluayhhYnNvbHV0ZU91dERpciwgc3ltbGlua1BhdGgsIFwiZGlyXCIpO1xuXG5cdFx0XHRtYW5pZmVzdC5saW5rcy5wdXNoKHsgcGFja2FnZU5hbWUsIHN5bWxpbmtQYXRoLCBvcmlnaW5hbFBhdGggfSk7XG5cdFx0XHR0aGlzLiNsb2dnZXIuaW5mbyhgTGlua2VkICR7cGFja2FnZU5hbWV9IOKGkiAke2Fic29sdXRlT3V0RGlyfWApO1xuXHRcdH1cblxuXHRcdC8vIENyZWF0ZSBhIHBlZXIgbm9kZV9tb2R1bGVzIGF0IHRoZSBidWlsZCBvdXRwdXQgcm9vdCBzbyBOb2RlIGNhbiByZXNvbHZlXG5cdFx0Ly8gYmFyZSBzcGVjaWZpZXJzIGZyb20gdGhlIHJlYWwgKG5vbi1zeW1saW5rKSBwYXRocyBvZiBsaW5rZWQgcGFja2FnZXMuXG5cdFx0aWYgKG1hbmlmZXN0LmxpbmtzLmxlbmd0aCA+IDApIHtcblx0XHRcdGNvbnN0IGJ1aWxkUm9vdCA9IHBhdGgucmVzb2x2ZShwcm9qZWN0c1swXS5nZXRSb290T3V0KCkpO1xuXHRcdFx0Y29uc3QgcGVlck5vZGVNb2R1bGVzRGlyID0gcGF0aC5qb2luKGJ1aWxkUm9vdCwgXCJub2RlX21vZHVsZXNcIik7XG5cdFx0XHRhd2FpdCBmcy5ybShwZWVyTm9kZU1vZHVsZXNEaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcblx0XHRcdGZvciAoY29uc3QgcHJvamVjdCBvZiBwcm9qZWN0cykge1xuXHRcdFx0XHRjb25zdCBwa2cgPSBhd2FpdCBwcm9qZWN0LmdldFBhY2thZ2VKc29uKCk7XG5cdFx0XHRcdGlmICghcGtnLm5hbWUpIGNvbnRpbnVlO1xuXHRcdFx0XHRjb25zdCBvdXREaXIgPSBwYXRoLnJlc29sdmUocHJvamVjdC5nZXRPdXREaXIoKSk7XG5cdFx0XHRcdGNvbnN0IHBlZXJTeW1saW5rID0gcGF0aC5qb2luKHBlZXJOb2RlTW9kdWxlc0RpciwgLi4ucGtnLm5hbWUuc3BsaXQoXCIvXCIpKTtcblx0XHRcdFx0YXdhaXQgZnMubWtkaXIocGF0aC5kaXJuYW1lKHBlZXJTeW1saW5rKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cdFx0XHRcdGF3YWl0IGZzLnN5bWxpbmsob3V0RGlyLCBwZWVyU3ltbGluaywgXCJkaXJcIik7XG5cdFx0XHRcdHRoaXMuI2xvZ2dlci50cmFjZShgUGVlci1saW5rZWQgJHtwa2cubmFtZX0g4oaSICR7b3V0RGlyfWApO1xuXHRcdFx0fVxuXHRcdFx0bWFuaWZlc3QucGVlck5vZGVNb2R1bGVzRGlyID0gcGVlck5vZGVNb2R1bGVzRGlyO1xuXHRcdFx0dGhpcy4jbG9nZ2VyLmluZm8oYENyZWF0ZWQgcGVlciBub2RlX21vZHVsZXMgYXQgJHtwZWVyTm9kZU1vZHVsZXNEaXJ9YCk7XG5cdFx0fVxuXG5cdFx0YXdhaXQgZnMud3JpdGVGaWxlKHBhdGguam9pbih0YXJnZXREaXIsIExJTktfTUFOSUZFU1QpLCBKU09OLnN0cmluZ2lmeShtYW5pZmVzdCwgbnVsbCwgMikpO1xuXG5cdFx0cmV0dXJuIEFjdGlvblJlc3BvbnNlLlN1Y2Nlc3MoTGluay5uYW1lKTtcblx0fTtcbn1cbiJdLCJuYW1lcyI6WyJmcyIsInBhdGgiLCJpbmplY3RhYmxlIiwiV29ya3NwYWNlIiwiQWN0aW9uUmVzcG9uc2UiLCJzY3JpYmUiLCJGb3JnZUVycm9yIiwiTElOS19NQU5JRkVTVCIsIkRFRkFVTFRfTElOS19DT05GSUdVUkFUSU9OIiwiTGluayIsImxvZ2dlciIsIm5hbWUiLCJ3b3Jrc3BhY2UiLCJydW4iLCJvcHRpb25zIiwidGFyZ2V0RGlyIiwicmVzb2x2ZSIsIm5vZGVNb2R1bGVzRGlyIiwiam9pbiIsInN0YXQiLCJjYXRjaCIsInByb2plY3RzIiwiZ2V0UHJvamVjdHMiLCJjb25maWd1cmF0aW9uIiwibGVuZ3RoIiwibWFuaWZlc3RQYXRoIiwiZXhpc3RpbmdNYW5pZmVzdFRleHQiLCJyZWFkRmlsZSIsImV4aXN0aW5nTWFuaWZlc3QiLCJKU09OIiwicGFyc2UiLCJtYW5pZmVzdCIsIndvcmtzcGFjZVJvb3QiLCJyb290RGlyIiwibGlua3MiLCJwcm9qZWN0IiwicGtnIiwiZ2V0UGFja2FnZUpzb24iLCJwYWNrYWdlTmFtZSIsInRyYWNlIiwib3V0RGlyIiwiZ2V0T3V0RGlyIiwiYWJzb2x1dGVPdXREaXIiLCJta2RpciIsInJlY3Vyc2l2ZSIsInN5bWxpbmtQYXRoIiwic3BsaXQiLCJzeW1saW5rUGFyZW50IiwiZGlybmFtZSIsIm9yaWdpbmFsUGF0aCIsImV4aXN0aW5nU3RhdCIsImxzdGF0IiwiZXhpc3RpbmdFbnRyeSIsImZpbmQiLCJsIiwiaXNTeW1ib2xpY0xpbmsiLCJ1bmxpbmsiLCJyZWFkbGluayIsInJlbmFtZSIsInN5bWxpbmsiLCJwdXNoIiwiaW5mbyIsImJ1aWxkUm9vdCIsImdldFJvb3RPdXQiLCJwZWVyTm9kZU1vZHVsZXNEaXIiLCJybSIsImZvcmNlIiwicGVlclN5bWxpbmsiLCJ3cml0ZUZpbGUiLCJzdHJpbmdpZnkiLCJTdWNjZXNzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQSxPQUFPQSxRQUFRLG1CQUFtQjtBQUNsQyxPQUFPQyxVQUFVLFlBQVk7QUFDN0IsU0FBU0MsVUFBVSxRQUFRLGdDQUFnQztBQUMzRCw4Q0FBOEM7QUFDOUMsU0FBU0MsU0FBUyxRQUFRLGlCQUFpQjtBQUUzQyxTQUFTQyxjQUFjLFFBQVEsc0JBQXNCO0FBQ3JELFNBQVNDLE1BQU0sUUFBUSxtQkFBbUI7QUFDMUMsT0FBTyxzQ0FBc0M7QUFDN0MsU0FBU0MsVUFBVSxRQUFRLGVBQWU7QUFFMUMsT0FBTyxNQUFNQyxnQkFBZ0IsbUJBQW1CO0FBT2hELE9BQU8sTUFBTUMsNkJBQTZCLE9BQU87QUFTakQsT0FBTyxNQUFNQzs7SUFDWixDQUFBLE1BQU8sR0FBR0osT0FBT0ssTUFBTSxDQUFDRCxLQUFLRSxJQUFJLEVBQUU7SUFFbkMsWUFBbUIsQUFBaUJDLFNBQW9CLENBQUU7YUFBdEJBLFlBQUFBO0lBQXVCO0lBRXBEQyxNQUFNLE9BQU9DO1FBQ25CLE1BQU1DLFlBQVlkLEtBQUtlLE9BQU8sQ0FBQ0YsUUFBUUMsU0FBUztRQUNoRCxNQUFNRSxpQkFBaUJoQixLQUFLaUIsSUFBSSxDQUFDSCxXQUFXO1FBRTVDLE1BQU1JLE9BQU8sTUFBTW5CLEdBQUdtQixJQUFJLENBQUNGLGdCQUFnQkcsS0FBSyxDQUFDLElBQU07UUFDdkQsSUFBSUQsUUFBUSxNQUFNO1lBQ2pCLE1BQU0sSUFBSWIsV0FDVCxDQUFDLDJCQUEyQixFQUFFUyxVQUFVLDBCQUEwQixDQUFDO1FBRXJFO1FBRUEsTUFBTU0sV0FBVyxJQUFJLENBQUNULFNBQVMsQ0FBQ1UsV0FBVyxDQUFDUixRQUFRUyxhQUFhO1FBQ2pFLElBQUlGLFNBQVNHLE1BQU0sS0FBSyxHQUFHO1lBQzFCLE1BQU0sSUFBSWxCLFdBQVcsQ0FBQyxxQ0FBcUMsRUFBRVEsUUFBUVMsYUFBYSxDQUFDLENBQUMsQ0FBQztRQUN0RjtRQUVBLDZFQUE2RTtRQUM3RSxNQUFNRSxlQUFleEIsS0FBS2lCLElBQUksQ0FBQ0gsV0FBV1I7UUFDMUMsTUFBTW1CLHVCQUF1QixNQUFNMUIsR0FBRzJCLFFBQVEsQ0FBQ0YsY0FBYyxRQUFRTCxLQUFLLENBQUMsSUFBTTtRQUNqRixNQUFNUSxtQkFDTEYsd0JBQXdCLE9BQU9HLEtBQUtDLEtBQUssQ0FBQ0osd0JBQXdCO1FBRW5FLE1BQU1LLFdBQXlCO1lBQzlCQyxlQUFlLElBQUksQ0FBQ3BCLFNBQVMsQ0FBQ3FCLE9BQU87WUFDckNDLE9BQU8sRUFBRTtRQUNWO1FBRUEsS0FBSyxNQUFNQyxXQUFXZCxTQUFVO1lBQy9CLE1BQU1lLE1BQU0sTUFBTUQsUUFBUUUsY0FBYztZQUN4QyxNQUFNQyxjQUFjRixJQUFJekIsSUFBSTtZQUM1QixJQUFJLENBQUMyQixhQUFhO2dCQUNqQixJQUFJLENBQUMsQ0FBQSxNQUFPLENBQUNDLEtBQUssQ0FBQyxDQUFDLGtCQUFrQixFQUFFSixRQUFReEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDO2dCQUN6RTtZQUNEO1lBRUEsa0ZBQWtGO1lBQ2xGLE1BQU02QixTQUFTTCxRQUFRTSxTQUFTO1lBQ2hDLE1BQU1DLGlCQUFpQnpDLEtBQUtlLE9BQU8sQ0FBQ3dCO1lBRXBDLG1GQUFtRjtZQUNuRixNQUFNeEMsR0FBRzJDLEtBQUssQ0FBQ0QsZ0JBQWdCO2dCQUFFRSxXQUFXO1lBQUs7WUFFakQsa0RBQWtEO1lBQ2xELE1BQU1DLGNBQWM1QyxLQUFLaUIsSUFBSSxDQUFDRCxtQkFBbUJxQixZQUFZUSxLQUFLLENBQUM7WUFDbkUsTUFBTUMsZ0JBQWdCOUMsS0FBSytDLE9BQU8sQ0FBQ0g7WUFFbkMsNkRBQTZEO1lBQzdELDZFQUE2RTtZQUM3RSwwRUFBMEU7WUFDMUUsSUFBSUksZUFBOEI7WUFDbEMsTUFBTUMsZUFBZSxNQUFNbEQsR0FBR21ELEtBQUssQ0FBQ04sYUFBYXpCLEtBQUssQ0FBQyxJQUFNO1lBQzdELElBQUk4QixnQkFBZ0IsTUFBTTtnQkFDekIsTUFBTUUsZ0JBQWdCeEIsa0JBQWtCTSxNQUFNbUIsS0FDN0MsQ0FBQ0MsSUFBTUEsRUFBRWhCLFdBQVcsS0FBS0E7Z0JBRTFCLElBQUljLGlCQUFpQixNQUFNO29CQUMxQiw4RUFBOEU7b0JBQzlFSCxlQUFlRyxjQUFjSCxZQUFZO29CQUN6QyxJQUFJQyxhQUFhSyxjQUFjLElBQUk7d0JBQ2xDLE1BQU12RCxHQUFHd0QsTUFBTSxDQUFDWDtvQkFDakI7Z0JBQ0QsT0FBTyxJQUFJSyxhQUFhSyxjQUFjLElBQUk7b0JBQ3pDTixlQUFlLE1BQU1qRCxHQUFHeUQsUUFBUSxDQUFDWjtvQkFDakMsTUFBTTdDLEdBQUd3RCxNQUFNLENBQUNYO2dCQUNqQixPQUFPO29CQUNOLDBDQUEwQztvQkFDMUNJLGVBQWUsR0FBR0osWUFBWSxpQkFBaUIsQ0FBQztvQkFDaEQsTUFBTTdDLEdBQUcwRCxNQUFNLENBQUNiLGFBQWFJO2dCQUM5QjtZQUNEO1lBRUEsTUFBTWpELEdBQUcyQyxLQUFLLENBQUNJLGVBQWU7Z0JBQUVILFdBQVc7WUFBSztZQUNoRCxNQUFNNUMsR0FBRzJELE9BQU8sQ0FBQ2pCLGdCQUFnQkcsYUFBYTtZQUU5Q2QsU0FBU0csS0FBSyxDQUFDMEIsSUFBSSxDQUFDO2dCQUFFdEI7Z0JBQWFPO2dCQUFhSTtZQUFhO1lBQzdELElBQUksQ0FBQyxDQUFBLE1BQU8sQ0FBQ1ksSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFdkIsWUFBWSxHQUFHLEVBQUVJLGdCQUFnQjtRQUM5RDtRQUVBLDBFQUEwRTtRQUMxRSx3RUFBd0U7UUFDeEUsSUFBSVgsU0FBU0csS0FBSyxDQUFDVixNQUFNLEdBQUcsR0FBRztZQUM5QixNQUFNc0MsWUFBWTdELEtBQUtlLE9BQU8sQ0FBQ0ssUUFBUSxDQUFDLEVBQUUsQ0FBQzBDLFVBQVU7WUFDckQsTUFBTUMscUJBQXFCL0QsS0FBS2lCLElBQUksQ0FBQzRDLFdBQVc7WUFDaEQsTUFBTTlELEdBQUdpRSxFQUFFLENBQUNELG9CQUFvQjtnQkFBRXBCLFdBQVc7Z0JBQU1zQixPQUFPO1lBQUs7WUFDL0QsS0FBSyxNQUFNL0IsV0FBV2QsU0FBVTtnQkFDL0IsTUFBTWUsTUFBTSxNQUFNRCxRQUFRRSxjQUFjO2dCQUN4QyxJQUFJLENBQUNELElBQUl6QixJQUFJLEVBQUU7Z0JBQ2YsTUFBTTZCLFNBQVN2QyxLQUFLZSxPQUFPLENBQUNtQixRQUFRTSxTQUFTO2dCQUM3QyxNQUFNMEIsY0FBY2xFLEtBQUtpQixJQUFJLENBQUM4Qyx1QkFBdUI1QixJQUFJekIsSUFBSSxDQUFDbUMsS0FBSyxDQUFDO2dCQUNwRSxNQUFNOUMsR0FBRzJDLEtBQUssQ0FBQzFDLEtBQUsrQyxPQUFPLENBQUNtQixjQUFjO29CQUFFdkIsV0FBVztnQkFBSztnQkFDNUQsTUFBTTVDLEdBQUcyRCxPQUFPLENBQUNuQixRQUFRMkIsYUFBYTtnQkFDdEMsSUFBSSxDQUFDLENBQUEsTUFBTyxDQUFDNUIsS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFSCxJQUFJekIsSUFBSSxDQUFDLEdBQUcsRUFBRTZCLFFBQVE7WUFDekQ7WUFDQVQsU0FBU2lDLGtCQUFrQixHQUFHQTtZQUM5QixJQUFJLENBQUMsQ0FBQSxNQUFPLENBQUNILElBQUksQ0FBQyxDQUFDLDZCQUE2QixFQUFFRyxvQkFBb0I7UUFDdkU7UUFFQSxNQUFNaEUsR0FBR29FLFNBQVMsQ0FBQ25FLEtBQUtpQixJQUFJLENBQUNILFdBQVdSLGdCQUFnQnNCLEtBQUt3QyxTQUFTLENBQUN0QyxVQUFVLE1BQU07UUFFdkYsT0FBTzNCLGVBQWVrRSxPQUFPLENBQUM3RCxLQUFLRSxJQUFJO0lBQ3hDLEVBQUU7QUFDSCJ9
@@ -0,0 +1,219 @@
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ function _ts_metadata(k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ }
10
+ import fs from "node:fs/promises";
11
+ import path from "node:path";
12
+ import { injectable } from "@decohere/crucible/decorators";
13
+ import { Workspace } from "@decohere/workspace";
14
+ import { ActionResponse } from "@decohere/devkit/cli";
15
+ import { Npm } from "@decohere/devkit/interop";
16
+ import { io } from "@decohere/core/io";
17
+ import { scribe } from "@decohere/scribe";
18
+ import { ForgeError, formatUnknownError } from "../errors.js";
19
+ import { DependencyPinner } from "../packaging/dependency-pinner.service.js";
20
+ import { deployable, PACKAGE_DIR } from "../packaging/deployable.js";
21
+ import { ImportGraph } from "../packaging/import-graph.service.js";
22
+ import { releaseExports } from "../packaging/release-exports.js";
23
+ import { uiAssets } from "../packaging/ui-assets.js";
24
+ import { Release } from "../workspace.config.js";
25
+ export class PackageDeployable {
26
+ workspace;
27
+ importGraph;
28
+ pinner;
29
+ #logger = scribe.logger(PackageDeployable.name);
30
+ npm = new Npm();
31
+ constructor(workspace, importGraph, pinner){
32
+ this.workspace = workspace;
33
+ this.importGraph = importGraph;
34
+ this.pinner = pinner;
35
+ }
36
+ async run(options) {
37
+ const projects = this.workspace.getProjects(Release.name);
38
+ const selected = await this.select(projects, options.project);
39
+ if (typeof selected === "string") {
40
+ return ActionResponse.Error(PackageDeployable.name, selected);
41
+ }
42
+ if (selected.length === 0) {
43
+ this.#logger.info("No projects found with a Dockerfile — nothing to package");
44
+ return ActionResponse.Success(PackageDeployable.name, []);
45
+ }
46
+ const releaseProjects = await this.releaseProjects(projects);
47
+ const responses = [];
48
+ for (const project of selected){
49
+ responses.push(await this.packageProject(project, releaseProjects, projects));
50
+ }
51
+ return responses.some((response)=>!response.succeeded) ? ActionResponse.Error(PackageDeployable.name, responses) : ActionResponse.Success(PackageDeployable.name, responses);
52
+ }
53
+ /** The deployables to package, or the reason a named project cannot be one. */ async select(projects, requested) {
54
+ if (requested == null || requested === "") {
55
+ const found = [];
56
+ for (const project of projects){
57
+ if (await deployable.isDeployable(project)) {
58
+ found.push(project);
59
+ }
60
+ }
61
+ return found;
62
+ }
63
+ const project = projects.find((candidate)=>candidate.name === requested);
64
+ if (project == null) {
65
+ return `${requested} is not a workspace project. Known projects: ${projects.map((p)=>p.name).join(", ")}`;
66
+ }
67
+ if (!await deployable.isDeployable(project)) {
68
+ return `${requested} has no ${deployable.dockerfileName(project)}, so it is a library, not a deployable. ` + "Libraries are packaged into the deployables that import them.";
69
+ }
70
+ return [
71
+ project
72
+ ];
73
+ }
74
+ async releaseProjects(projects) {
75
+ const entries = await Promise.all(projects.map(async (project)=>{
76
+ const pkg = await project.getPackageJson();
77
+ return [
78
+ project.name,
79
+ {
80
+ name: project.name,
81
+ pkg,
82
+ projectRoot: path.resolve(project.projectRoot),
83
+ releaseDir: path.resolve(project.getOutDir())
84
+ }
85
+ ];
86
+ }));
87
+ return new Map(entries);
88
+ }
89
+ async packageProject(project, releaseProjects, projects) {
90
+ const outDir = path.join(path.resolve(project.projectRoot), PACKAGE_DIR);
91
+ const base = {
92
+ projectName: project.name,
93
+ outDir,
94
+ workspacePackages: [],
95
+ dependencies: {}
96
+ };
97
+ try {
98
+ const entry = releaseProjects.get(project.name);
99
+ if (!await io.directoryExists(path.join(entry.releaseDir, "es6"))) {
100
+ throw new ForgeError(`No release build for ${project.name}. Run \`forge build --configuration release\` first.`);
101
+ }
102
+ const ui = await uiAssets.resolve(project, projects);
103
+ const reached = await this.importGraph.walk(entry, releaseProjects);
104
+ const libraries = [
105
+ ...reached.workspace
106
+ ].filter((name)=>name !== project.name).sort().map((name)=>releaseProjects.get(name));
107
+ const dependencies = await this.pinner.pin(reached.thirdParty, [
108
+ entry,
109
+ ...libraries
110
+ ], releaseProjects, {
111
+ dir: path.resolve(this.workspace.rootDir),
112
+ pkg: await this.workspace.getPackageJson()
113
+ });
114
+ await this.write(entry, libraries, dependencies, outDir, ui);
115
+ const workspacePackages = [
116
+ ...reached.workspace
117
+ ].sort();
118
+ this.#logger.info(`Packaged ${project.name} to ${outDir}`, {
119
+ workspace: workspacePackages,
120
+ thirdParty: Object.keys(dependencies)
121
+ });
122
+ return {
123
+ projectName: project.name,
124
+ outDir,
125
+ workspacePackages,
126
+ dependencies,
127
+ succeeded: true,
128
+ message: `Packaged ${project.name} to ${outDir}`
129
+ };
130
+ } catch (reason) {
131
+ const message = formatUnknownError(reason);
132
+ return {
133
+ ...base,
134
+ succeeded: false,
135
+ message,
136
+ error: `${project.name}: ${message}`
137
+ };
138
+ }
139
+ }
140
+ async write(entry, libraries, dependencies, outDir, ui) {
141
+ await fs.rm(outDir, {
142
+ recursive: true,
143
+ force: true
144
+ });
145
+ await fs.mkdir(outDir, {
146
+ recursive: true
147
+ });
148
+ await this.writeJson(path.join(outDir, "package.json"), {
149
+ name: entry.name.replace(/^@/, "").replace("/", "-"),
150
+ version: entry.pkg.version,
151
+ private: true,
152
+ type: "module",
153
+ scripts: {
154
+ start: `node es6/${releaseExports.toJs(entry.pkg.main ?? "src/index.ts")}`
155
+ },
156
+ dependencies
157
+ });
158
+ // npm writes real folders. It also removes anything in node_modules it does not know,
159
+ // so the workspace libraries are copied in only after it has run.
160
+ if (Object.keys(dependencies).length > 0) {
161
+ await this.npm.installProduction({
162
+ cwd: outDir
163
+ });
164
+ }
165
+ await this.copyTree(path.join(entry.releaseDir, "es6"), path.join(outDir, "es6"));
166
+ const config = path.join(path.resolve(this.workspace.rootDir), "config");
167
+ if (await io.directoryExists(config)) {
168
+ await this.copyTree(config, path.join(outDir, "config"));
169
+ }
170
+ if (ui != null) {
171
+ await this.copyTree(ui.from, path.join(outDir, ui.to));
172
+ }
173
+ for (const library of libraries){
174
+ const target = path.join(outDir, "node_modules", ...library.name.split("/"));
175
+ await this.copyTree(path.join(library.releaseDir, "es6"), path.join(target, "es6"));
176
+ await this.writeJson(path.join(target, "package.json"), {
177
+ name: library.name,
178
+ version: library.pkg.version,
179
+ type: "module",
180
+ exports: releaseExports.build(library.pkg)
181
+ });
182
+ }
183
+ await this.assertNoSymlinks(outDir);
184
+ }
185
+ /** Copies file contents, never links: a symlink in the output would break outside the image. */ async copyTree(from, to) {
186
+ await fs.cp(from, to, {
187
+ recursive: true,
188
+ dereference: true
189
+ });
190
+ }
191
+ async writeJson(filePath, value) {
192
+ await io.writeFile(filePath, `${JSON.stringify(value, null, "\t")}\n`, {
193
+ mkdir: true,
194
+ encoding: "utf8"
195
+ });
196
+ }
197
+ async assertNoSymlinks(dir) {
198
+ for (const entry of (await fs.readdir(dir, {
199
+ withFileTypes: true
200
+ }))){
201
+ const entryPath = path.join(dir, entry.name);
202
+ if (entry.isSymbolicLink()) {
203
+ throw new ForgeError(`The packaged output must hold no symlinks, but found ${entryPath}`);
204
+ }
205
+ if (entry.isDirectory()) {
206
+ await this.assertNoSymlinks(entryPath);
207
+ }
208
+ }
209
+ }
210
+ }
211
+ PackageDeployable = _ts_decorate([
212
+ injectable(),
213
+ _ts_metadata("design:type", Function),
214
+ _ts_metadata("design:paramtypes", [
215
+ typeof Workspace === "undefined" ? Object : Workspace,
216
+ typeof ImportGraph === "undefined" ? Object : ImportGraph,
217
+ typeof DependencyPinner === "undefined" ? Object : DependencyPinner
218
+ ])
219
+ ], PackageDeployable);
@@ -0,0 +1,97 @@
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ function _ts_metadata(k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ }
10
+ import { existsSync } from "node:fs";
11
+ import { readFile, writeFile } from "node:fs/promises";
12
+ import path from "node:path";
13
+ import { injectable } from "@decohere/crucible/decorators";
14
+ import { packageAliases, Workspace } from "@decohere/workspace";
15
+ import { ActionResponse } from "@decohere/devkit/cli";
16
+ import { scribe } from "@decohere/scribe";
17
+ export const PATHS_FILE = "tsconfig.paths.json";
18
+ export class Paths {
19
+ workspace;
20
+ #logger = scribe.logger(Paths.name);
21
+ constructor(workspace){
22
+ this.workspace = workspace;
23
+ }
24
+ async run(options) {
25
+ const file = path.join(this.workspace.rootDir, PATHS_FILE);
26
+ if (this.workspace.isStandalone) {
27
+ // One project has no other projects to import from source.
28
+ this.#logger.info(`Standalone project: no ${PATHS_FILE} needed`);
29
+ return ActionResponse.Success(Paths.name, [
30
+ {
31
+ file,
32
+ changed: false,
33
+ succeeded: true
34
+ }
35
+ ]);
36
+ }
37
+ const content = Paths.render(this.workspace);
38
+ const current = existsSync(file) ? await readFile(file, "utf8") : null;
39
+ const changed = current !== content;
40
+ if (options.check) {
41
+ if (!changed) {
42
+ return ActionResponse.Success(Paths.name, [
43
+ {
44
+ file,
45
+ changed,
46
+ succeeded: true
47
+ }
48
+ ]);
49
+ }
50
+ const error = `${PATHS_FILE} is out of date. Run \`forge paths\` to update it.`;
51
+ this.#logger.error(error);
52
+ return ActionResponse.Error(Paths.name, [
53
+ {
54
+ file,
55
+ changed,
56
+ succeeded: false,
57
+ error
58
+ }
59
+ ]);
60
+ }
61
+ if (changed) {
62
+ await writeFile(file, content);
63
+ this.#logger.info(`Wrote ${PATHS_FILE}`);
64
+ }
65
+ return ActionResponse.Success(Paths.name, [
66
+ {
67
+ file,
68
+ changed,
69
+ succeeded: true
70
+ }
71
+ ]);
72
+ }
73
+ /** The file's content: convention and exported subpaths only, never the tsconfig's own paths. */ static render(workspace) {
74
+ const rootDir = path.resolve(workspace.rootDir);
75
+ const { paths } = packageAliases.build(workspace.getProjects("debug"), {
76
+ baseUrl: rootDir
77
+ });
78
+ const sorted = Object.fromEntries(Object.keys(paths).sort().map((key)=>[
79
+ key,
80
+ (paths[key] ?? []).map((target)=>`./${target}`)
81
+ ]));
82
+ const json = {
83
+ $comment: "Generated by `forge paths` from the workspace packages. Do not edit.",
84
+ compilerOptions: {
85
+ paths: sorted
86
+ }
87
+ };
88
+ return `${JSON.stringify(json, null, 2)}\n`;
89
+ }
90
+ }
91
+ Paths = _ts_decorate([
92
+ injectable(),
93
+ _ts_metadata("design:type", Function),
94
+ _ts_metadata("design:paramtypes", [
95
+ typeof Workspace === "undefined" ? Object : Workspace
96
+ ])
97
+ ], Paths);
@@ -8,10 +8,9 @@ function _ts_metadata(k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  }
10
10
  import { injectable } from "@decohere/crucible/decorators";
11
- // biome-ignore lint/style/useImportType: <DI>
12
- import { Workspace } from "@decohere/mesh";
13
- import { ActionResponse } from "@decohere/nexus/cli";
14
- import { Npm } from "@decohere/nexus/interop";
11
+ import { Workspace } from "@decohere/workspace";
12
+ import { ActionResponse } from "@decohere/devkit/cli";
13
+ import { Npm } from "@decohere/devkit/interop";
15
14
  import { scribe } from "@decohere/scribe";
16
15
  import { ForgeError, formatUnknownError } from "../errors.js";
17
16
  export class Publish {
@@ -143,5 +142,3 @@ Publish = _ts_decorate([
143
142
  typeof Workspace === "undefined" ? Object : Workspace
144
143
  ])
145
144
  ], Publish);
146
-
147
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9hY3Rpb25zL3B1Ymxpc2guYWN0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdGFibGUgfSBmcm9tIFwiQGRlY29oZXJlL2NydWNpYmxlL2RlY29yYXRvcnNcIjtcbmltcG9ydCB0eXBlIHsgUHJvamVjdCB9IGZyb20gXCJAZGVjb2hlcmUvbWVzaFwiO1xuLy8gYmlvbWUtaWdub3JlIGxpbnQvc3R5bGUvdXNlSW1wb3J0VHlwZTogPERJPlxuaW1wb3J0IHsgV29ya3NwYWNlIH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgdHlwZSB7IEFjdGlvbiwgUmVzdWx0U3RhdHVzIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9jbGlcIjtcbmltcG9ydCB7IEFjdGlvblJlc3BvbnNlIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9jbGlcIjtcbmltcG9ydCB7IE5wbSB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvaW50ZXJvcFwiO1xuaW1wb3J0IHsgc2NyaWJlIH0gZnJvbSBcIkBkZWNvaGVyZS9zY3JpYmVcIjtcbmltcG9ydCB7IEZvcmdlRXJyb3IsIGZvcm1hdFVua25vd25FcnJvciB9IGZyb20gXCIuLi9lcnJvcnMuanNcIjtcblxuZXhwb3J0IHR5cGUgUHVibGlzaE9wdGlvbnMgPSB7XG5cdGNvbmZpZ3VyYXRpb246IHN0cmluZztcblx0Y2hhbm5lbD86IHN0cmluZztcblx0ZHJ5UnVuPzogYm9vbGVhbjtcblx0dG9rZW4/OiBzdHJpbmc7XG5cdG90cD86IHN0cmluZztcblx0cHJvbXB0QXV0aD86IGJvb2xlYW47XG5cdHByb21wdE90cD86IGJvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBQdWJsaXNoUmVzcG9uc2UgPSBSZXN1bHRTdGF0dXMgJiB7XG5cdHByb2plY3ROYW1lOiBzdHJpbmc7XG5cdG1lc3NhZ2U6IHN0cmluZztcblx0cGFja2FnZU5hbWU/OiBzdHJpbmc7XG59O1xuXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUHVibGlzaCBpbXBsZW1lbnRzIEFjdGlvbjxQdWJsaXNoT3B0aW9ucz4ge1xuXHQvLyBUT0RPOiBwcm9iYWJseSBiZXN0IHRvIGluamVjdCBucG1cblx0cHJpdmF0ZSByZWFkb25seSBucG0gPSBuZXcgTnBtKCk7XG5cdCNsb2dnZXIgPSBzY3JpYmUubG9nZ2VyKFB1Ymxpc2gubmFtZSk7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgd29ya3NwYWNlOiBXb3Jrc3BhY2UpIHt9XG5cblx0cHVibGljIGFzeW5jIHJ1bihvcHRpb25zOiBQdWJsaXNoT3B0aW9ucyk6IFByb21pc2U8QWN0aW9uUmVzcG9uc2U8UHVibGlzaFJlc3BvbnNlPj4ge1xuXHRcdGNvbnN0IHByb2plY3RzID0gdGhpcy53b3Jrc3BhY2UuZ2V0UHJvamVjdHMob3B0aW9ucy5jb25maWd1cmF0aW9uKTtcblx0XHRjb25zdCB0b2tlbiA9IGF3YWl0IHRoaXMucmVzb2x2ZVRva2VuKG9wdGlvbnMpO1xuXHRcdGNvbnN0IG90cCA9IGF3YWl0IHRoaXMucmVzb2x2ZU90cChvcHRpb25zKTtcblxuXHRcdGlmIChwcm9qZWN0cy5sZW5ndGggPT09IDApIHtcblx0XHRcdHRocm93IG5ldyBGb3JnZUVycm9yKGBObyBwcm9qZWN0cyBmb3VuZCB0byBwdWJsaXNoYCk7XG5cdFx0fVxuXHRcdGNvbnN0IHB1Ymxpc2hSZXNwb25zZXMgPSBhd2FpdCB0aGlzLnB1Ymxpc2hQcm9qZWN0cyhwcm9qZWN0cywge1xuXHRcdFx0Li4ub3B0aW9ucyxcblx0XHRcdHRva2VuLFxuXHRcdFx0b3RwLFxuXHRcdH0pO1xuXHRcdGNvbnN0IGZhaWxlZCA9IHB1Ymxpc2hSZXNwb25zZXMuZmlsdGVyKChyKSA9PiAhci5zdWNjZWVkZWQpO1xuXHRcdGlmIChmYWlsZWQubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gQWN0aW9uUmVzcG9uc2UuRXJyb3IoUHVibGlzaC5uYW1lLCBwdWJsaXNoUmVzcG9uc2VzKTtcblx0XHR9XG5cdFx0cmV0dXJuIEFjdGlvblJlc3BvbnNlLlN1Y2Nlc3MoUHVibGlzaC5uYW1lLCBwdWJsaXNoUmVzcG9uc2VzKTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBwdWJsaXNoUHJvamVjdHMocHJvamVjdHM6IHJlYWRvbmx5IFByb2plY3RbXSwgb3B0aW9uczogUHVibGlzaE9wdGlvbnMpIHtcblx0XHRyZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoXG5cdFx0XHRwcm9qZWN0c1xuXHRcdFx0XHQuZmlsdGVyKChwcm9qZWN0KSA9PiB7XG5cdFx0XHRcdFx0aWYgKHByb2plY3QuaXNQcml2YXRlKSB7XG5cdFx0XHRcdFx0XHR0aGlzLiNsb2dnZXIuaW5mbyhgU2tpcHBpbmcgcHJpdmF0ZSBwYWNrYWdlOiAke3Byb2plY3QubmFtZX1gKTtcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5tYXAoYXN5bmMgKHByb2plY3QpID0+IGF3YWl0IHRoaXMucHVibGlzaFByb2plY3QocHJvamVjdCwgb3B0aW9ucykpLFxuXHRcdCk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIHB1Ymxpc2hQcm9qZWN0KFxuXHRcdHByb2plY3Q6IFByb2plY3QsXG5cdFx0b3B0aW9uczogUHVibGlzaE9wdGlvbnMsXG5cdCk6IFByb21pc2U8UHVibGlzaFJlc3BvbnNlPiB7XG5cdFx0Y29uc3QgeyBjaGFubmVsLCBkcnlSdW4sIHRva2VuLCBvdHAgfSA9IG9wdGlvbnM7XG5cdFx0Y29uc3Qgb3V0RGlyID0gcHJvamVjdC5nZXRPdXREaXIoKTtcblx0XHR0aGlzLiNsb2dnZXIuaW5mbyhgJHtkcnlSdW4gPyBcIltkcnktcnVuXSBcIiA6IFwiXCJ9UHVibGlzaGluZyAke3Byb2plY3QubmFtZX1gKTtcblxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMubnBtLnB1Ymxpc2gob3V0RGlyLCB7XG5cdFx0XHRcdGNoYW5uZWwsXG5cdFx0XHRcdGRyeVJ1bixcblx0XHRcdFx0YXV0aFRva2VuOiB0b2tlbixcblx0XHRcdFx0b3RwLFxuXHRcdFx0XHRza2lwSWZQdWJsaXNoZWQ6IHRydWUsXG5cdFx0XHR9KTtcblxuXHRcdFx0Y29uc3QgcGFja2FnZU5hbWUgPSByZXNwb25zZS5kYXRhPy5qb2luKFwiXCIpO1xuXHRcdFx0dGhpcy4jbG9nZ2VyLnRyYWNlKGAke3Byb2plY3QubmFtZX0g4oaSICR7cGFja2FnZU5hbWUgPz8gcmVzcG9uc2UubWVzc2FnZX1gKTtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHByb2plY3ROYW1lOiBwcm9qZWN0Lm5hbWUsXG5cdFx0XHRcdHN1Y2NlZWRlZDogdHJ1ZSxcblx0XHRcdFx0bWVzc2FnZTogcmVzcG9uc2UubWVzc2FnZSxcblx0XHRcdFx0cGFja2FnZU5hbWUsXG5cdFx0XHR9O1xuXHRcdH0gY2F0Y2ggKHJlYXNvbikge1xuXHRcdFx0Y29uc3QgbWVzc2FnZSA9IGZvcm1hdFVua25vd25FcnJvcihyZWFzb24pO1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0cHJvamVjdE5hbWU6IHByb2plY3QubmFtZSxcblx0XHRcdFx0c3VjY2VlZGVkOiBmYWxzZSxcblx0XHRcdFx0bWVzc2FnZSxcblx0XHRcdFx0ZXJyb3I6IGAke3Byb2plY3QubmFtZX06ICR7bWVzc2FnZX1gLFxuXHRcdFx0fTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIHJlc29sdmVUb2tlbihvcHRpb25zOiBQdWJsaXNoT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG5cdFx0aWYgKG9wdGlvbnMudG9rZW4/LnRyaW0oKSkge1xuXHRcdFx0cmV0dXJuIG9wdGlvbnMudG9rZW4udHJpbSgpO1xuXHRcdH1cblxuXHRcdGlmIChvcHRpb25zLnByb21wdEF1dGgpIHtcblx0XHRcdHJldHVybiBhd2FpdCB0aGlzLnByb21wdFNlY3JldChcIm5wbSBhY2Nlc3MgdG9rZW46IFwiKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyByZXNvbHZlT3RwKG9wdGlvbnM6IFB1Ymxpc2hPcHRpb25zKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcblx0XHRpZiAob3B0aW9ucy5vdHA/LnRyaW0oKSkge1xuXHRcdFx0cmV0dXJuIG9wdGlvbnMub3RwLnRyaW0oKTtcblx0XHR9XG5cblx0XHRpZiAob3B0aW9ucy5wcm9tcHRBdXRoIHx8IG9wdGlvbnMucHJvbXB0T3RwKSB7XG5cdFx0XHRyZXR1cm4gYXdhaXQgdGhpcy5wcm9tcHRTZWNyZXQoXCJucG0gT1RQOiBcIik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgcHJvbXB0U2VjcmV0KGxhYmVsOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuXHRcdGlmICghcHJvY2Vzcy5zdGRpbi5pc1RUWSB8fCAhcHJvY2Vzcy5zdGRvdXQuaXNUVFkpIHtcblx0XHRcdHRocm93IG5ldyBGb3JnZUVycm9yKGBDYW5ub3QgcHJvbXB0IGZvciBzZWNyZXQgd2l0aG91dCBhbiBpbnRlcmFjdGl2ZSBUVFlgKTtcblx0XHR9XG5cblx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShsYWJlbCk7XG5cdFx0Y29uc3Qgc3RkaW4gPSBwcm9jZXNzLnN0ZGluO1xuXHRcdHN0ZGluLnNldEVuY29kaW5nKFwidXRmOFwiKTtcblx0XHRzdGRpbi5yZXN1bWUoKTtcblx0XHRzdGRpbi5zZXRSYXdNb2RlPy4odHJ1ZSk7XG5cblx0XHRsZXQgdmFsdWUgPSBcIlwiO1xuXG5cdFx0cmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0Y29uc3QgY2xlYW51cCA9ICgpID0+IHtcblx0XHRcdFx0c3RkaW4uc2V0UmF3TW9kZT8uKGZhbHNlKTtcblx0XHRcdFx0c3RkaW4ucGF1c2UoKTtcblx0XHRcdFx0c3RkaW4ucmVtb3ZlTGlzdGVuZXIoXCJkYXRhXCIsIG9uRGF0YSk7XG5cdFx0XHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKFwiXFxuXCIpO1xuXHRcdFx0fTtcblxuXHRcdFx0Y29uc3Qgb25EYXRhID0gKGNodW5rOiBzdHJpbmcpID0+IHtcblx0XHRcdFx0Y29uc3QgY2hhciA9IGNodW5rO1xuXHRcdFx0XHRpZiAoY2hhciA9PT0gXCJcXHUwMDAzXCIpIHtcblx0XHRcdFx0XHRjbGVhbnVwKCk7XG5cdFx0XHRcdFx0cmVqZWN0KG5ldyBGb3JnZUVycm9yKFwiSW5wdXQgY2FuY2VsbGVkXCIpKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoY2hhciA9PT0gXCJcXHJcIiB8fCBjaGFyID09PSBcIlxcblwiKSB7XG5cdFx0XHRcdFx0Y2xlYW51cCgpO1xuXHRcdFx0XHRcdHJlc29sdmUodmFsdWUudHJpbSgpKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoY2hhciA9PT0gXCJcXHUwMDA4XCIgfHwgY2hhciA9PT0gXCJcXHUwMDdmXCIpIHtcblx0XHRcdFx0XHR2YWx1ZSA9IHZhbHVlLnNsaWNlKDAsIC0xKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YWx1ZSArPSBjaGFyO1xuXHRcdFx0fTtcblxuXHRcdFx0c3RkaW4ub24oXCJkYXRhXCIsIG9uRGF0YSk7XG5cdFx0fSk7XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJpbmplY3RhYmxlIiwiV29ya3NwYWNlIiwiQWN0aW9uUmVzcG9uc2UiLCJOcG0iLCJzY3JpYmUiLCJGb3JnZUVycm9yIiwiZm9ybWF0VW5rbm93bkVycm9yIiwiUHVibGlzaCIsIm5wbSIsImxvZ2dlciIsIm5hbWUiLCJ3b3Jrc3BhY2UiLCJydW4iLCJvcHRpb25zIiwicHJvamVjdHMiLCJnZXRQcm9qZWN0cyIsImNvbmZpZ3VyYXRpb24iLCJ0b2tlbiIsInJlc29sdmVUb2tlbiIsIm90cCIsInJlc29sdmVPdHAiLCJsZW5ndGgiLCJwdWJsaXNoUmVzcG9uc2VzIiwicHVibGlzaFByb2plY3RzIiwiZmFpbGVkIiwiZmlsdGVyIiwiciIsInN1Y2NlZWRlZCIsIkVycm9yIiwiU3VjY2VzcyIsIlByb21pc2UiLCJhbGwiLCJwcm9qZWN0IiwiaXNQcml2YXRlIiwiaW5mbyIsIm1hcCIsInB1Ymxpc2hQcm9qZWN0IiwiY2hhbm5lbCIsImRyeVJ1biIsIm91dERpciIsImdldE91dERpciIsInJlc3BvbnNlIiwicHVibGlzaCIsImF1dGhUb2tlbiIsInNraXBJZlB1Ymxpc2hlZCIsInBhY2thZ2VOYW1lIiwiZGF0YSIsImpvaW4iLCJ0cmFjZSIsIm1lc3NhZ2UiLCJwcm9qZWN0TmFtZSIsInJlYXNvbiIsImVycm9yIiwidHJpbSIsInByb21wdEF1dGgiLCJwcm9tcHRTZWNyZXQiLCJ1bmRlZmluZWQiLCJwcm9tcHRPdHAiLCJsYWJlbCIsInByb2Nlc3MiLCJzdGRpbiIsImlzVFRZIiwic3Rkb3V0Iiwid3JpdGUiLCJzZXRFbmNvZGluZyIsInJlc3VtZSIsInNldFJhd01vZGUiLCJ2YWx1ZSIsInJlc29sdmUiLCJyZWplY3QiLCJjbGVhbnVwIiwicGF1c2UiLCJyZW1vdmVMaXN0ZW5lciIsIm9uRGF0YSIsImNodW5rIiwiY2hhciIsInNsaWNlIiwib24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLFNBQVNBLFVBQVUsUUFBUSxnQ0FBZ0M7QUFFM0QsOENBQThDO0FBQzlDLFNBQVNDLFNBQVMsUUFBUSxpQkFBaUI7QUFFM0MsU0FBU0MsY0FBYyxRQUFRLHNCQUFzQjtBQUNyRCxTQUFTQyxHQUFHLFFBQVEsMEJBQTBCO0FBQzlDLFNBQVNDLE1BQU0sUUFBUSxtQkFBbUI7QUFDMUMsU0FBU0MsVUFBVSxFQUFFQyxrQkFBa0IsUUFBUSxlQUFlO0FBbUI5RCxPQUFP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